@@ -115,13 +115,15 @@ struct PullIntoDescriptor final
115
115
116
116
PullIntoDescriptor (JS::Handle <JSObject*> aBuffer, uint64_t aBufferByteLength,
117
117
uint64_t aByteOffset, uint64_t aByteLength,
118
- uint64_t aBytesFilled, uint64_t aElementSize,
119
- Constructor aViewConstructor, ReaderType aReaderType)
118
+ uint64_t aBytesFilled, uint64_t aMinimumFill,
119
+ uint64_t aElementSize, Constructor aViewConstructor,
120
+ ReaderType aReaderType)
120
121
: mBuffer (aBuffer),
121
122
mBufferByteLength (aBufferByteLength),
122
123
mByteOffset(aByteOffset),
123
124
mByteLength(aByteLength),
124
125
mBytesFilled(aBytesFilled),
126
+ mMinimumFill(aMinimumFill),
125
127
mElementSize(aElementSize),
126
128
mViewConstructor(aViewConstructor),
127
129
mReaderType(aReaderType) {
@@ -147,6 +149,8 @@ struct PullIntoDescriptor final
147
149
mBytesFilled = aBytesFilled;
148
150
}
149
151
152
+ uint64_t MinimumFill () const { return mMinimumFill ; }
153
+
150
154
uint64_t ElementSize () const { return mElementSize ; }
151
155
void SetElementSize (const uint64_t aElementSize) {
152
156
mElementSize = aElementSize;
@@ -166,6 +170,7 @@ struct PullIntoDescriptor final
166
170
uint64_t mByteOffset = 0 ;
167
171
uint64_t mByteLength = 0 ;
168
172
uint64_t mBytesFilled = 0 ;
173
+ uint64_t mMinimumFill = 0 ;
169
174
uint64_t mElementSize = 0 ;
170
175
Constructor mViewConstructor ;
171
176
ReaderType mReaderType ;
@@ -397,8 +402,11 @@ void ReadableByteStreamControllerClose(
397
402
398
403
PullIntoDescriptor* firstPendingPullInto =
399
404
aController->PendingPullIntos ().getFirst ();
405
+
406
+
400
407
401
- if (firstPendingPullInto->BytesFilled () > 0 ) {
408
+ if ((firstPendingPullInto->BytesFilled () %
409
+ firstPendingPullInto->ElementSize ()) != 0 ) {
402
410
403
411
ErrorResult rv;
404
412
rv.ThrowTypeError (" Leftover Bytes" );
@@ -704,7 +712,9 @@ void ReadableByteStreamControllerCommitPullIntoDescriptor(
704
712
705
713
if (aStream->State () == ReadableStream::ReaderState::Closed) {
706
714
707
- MOZ_ASSERT (pullIntoDescriptor->BytesFilled () == 0 );
715
+
716
+ MOZ_ASSERT ((pullIntoDescriptor->BytesFilled () %
717
+ pullIntoDescriptor->ElementSize ()) == 0 );
708
718
709
719
710
720
done = true ;
@@ -1170,9 +1180,11 @@ void ReadableByteStreamController::PullSteps(JSContext* aCx,
1170
1180
1171
1181
if (autoAllocateChunkSize) {
1172
1182
1183
+
1173
1184
aRv.MightThrowJSException ();
1174
1185
JS::Rooted<JSObject*> buffer (
1175
1186
aCx, JS::NewArrayBuffer (aCx, *autoAllocateChunkSize));
1187
+
1176
1188
1177
1189
if (!buffer) {
1178
1190
@@ -1194,8 +1206,19 @@ void ReadableByteStreamController::PullSteps(JSContext* aCx,
1194
1206
}
1195
1207
1196
1208
1209
+
1210
+
1211
+
1212
+
1213
+
1214
+
1215
+
1216
+
1217
+
1197
1218
RefPtr<PullIntoDescriptor> pullIntoDescriptor = new PullIntoDescriptor (
1198
- buffer, *autoAllocateChunkSize, 0 , *autoAllocateChunkSize, 0 , 1 ,
1219
+ buffer, *autoAllocateChunkSize,
1220
+ 0 , *autoAllocateChunkSize,
1221
+ 0 , 1 , 1 ,
1199
1222
PullIntoDescriptor::Constructor::Uint8, ReaderType::Default);
1200
1223
1201
1224
@@ -1281,6 +1304,7 @@ JSObject* ReadableByteStreamControllerConvertPullIntoDescriptor(
1281
1304
MOZ_ASSERT (bytesFilled <= pullIntoDescriptor->ByteLength ());
1282
1305
1283
1306
1307
+
1284
1308
MOZ_ASSERT (bytesFilled % elementSize == 0 );
1285
1309
1286
1310
@@ -1311,7 +1335,9 @@ static void ReadableByteStreamControllerRespondInClosedState(
1311
1335
JSContext* aCx, ReadableByteStreamController* aController,
1312
1336
RefPtr<PullIntoDescriptor>& aFirstDescriptor, ErrorResult& aRv) {
1313
1337
1314
- MOZ_ASSERT (aFirstDescriptor->BytesFilled () == 0 );
1338
+
1339
+ MOZ_ASSERT (
1340
+ (aFirstDescriptor->BytesFilled () % aFirstDescriptor->ElementSize ()) == 0 );
1315
1341
1316
1342
1317
1343
@@ -1398,7 +1424,7 @@ static void ReadableByteStreamControllerRespondInReadableState(
1398
1424
1399
1425
1400
1426
1401
- if (aPullIntoDescriptor->BytesFilled () < aPullIntoDescriptor->ElementSize ()) {
1427
+ if (aPullIntoDescriptor->BytesFilled () < aPullIntoDescriptor->MinimumFill ()) {
1402
1428
return ;
1403
1429
}
1404
1430
@@ -1648,15 +1674,6 @@ bool ReadableByteStreamControllerFillPullIntoDescriptorFromQueue(
1648
1674
JSContext* aCx, ReadableByteStreamController* aController,
1649
1675
PullIntoDescriptor* aPullIntoDescriptor, ErrorResult& aRv) {
1650
1676
1651
- size_t elementSize = aPullIntoDescriptor->ElementSize ();
1652
-
1653
-
1654
-
1655
- size_t currentAlignedBytes =
1656
- aPullIntoDescriptor->BytesFilled () -
1657
- (aPullIntoDescriptor->BytesFilled () % elementSize);
1658
-
1659
-
1660
1677
1661
1678
size_t maxBytesToCopy =
1662
1679
std::min (static_cast <size_t >(aController->QueueTotalSize ()),
@@ -1668,17 +1685,25 @@ bool ReadableByteStreamControllerFillPullIntoDescriptorFromQueue(
1668
1685
size_t maxBytesFilled = aPullIntoDescriptor->BytesFilled () + maxBytesToCopy;
1669
1686
1670
1687
1688
+ size_t totalBytesToCopyRemaining = maxBytesToCopy;
1689
+
1671
1690
1672
- size_t maxAlignedBytes = maxBytesFilled - (maxBytesFilled % elementSize) ;
1691
+ bool ready = false ;
1673
1692
1674
1693
1675
- size_t totalBytesToCopyRemaining = maxBytesToCopy;
1694
+
1695
+ MOZ_ASSERT (aPullIntoDescriptor->BytesFilled () <
1696
+ aPullIntoDescriptor->MinimumFill ());
1676
1697
1677
1698
1678
- bool ready = false ;
1699
+
1700
+ size_t remainderBytes = maxBytesFilled % aPullIntoDescriptor->ElementSize ();
1679
1701
1680
1702
1681
- if (maxAlignedBytes > currentAlignedBytes) {
1703
+ size_t maxAlignedBytes = maxBytesFilled - remainderBytes;
1704
+
1705
+
1706
+ if (maxAlignedBytes >= aPullIntoDescriptor->MinimumFill ()) {
1682
1707
1683
1708
1684
1709
totalBytesToCopyRemaining =
@@ -1759,9 +1784,8 @@ bool ReadableByteStreamControllerFillPullIntoDescriptorFromQueue(
1759
1784
1760
1785
1761
1786
1762
-
1763
1787
MOZ_ASSERT (aPullIntoDescriptor->BytesFilled () <
1764
- aPullIntoDescriptor->ElementSize ());
1788
+ aPullIntoDescriptor->MinimumFill ());
1765
1789
}
1766
1790
1767
1791
@@ -1771,8 +1795,8 @@ bool ReadableByteStreamControllerFillPullIntoDescriptorFromQueue(
1771
1795
1772
1796
void ReadableByteStreamControllerPullInto (
1773
1797
JSContext* aCx, ReadableByteStreamController* aController,
1774
- JS::Handle <JSObject*> aView, ReadIntoRequest* aReadIntoRequest ,
1775
- ErrorResult& aRv) {
1798
+ JS::Handle <JSObject*> aView, uint64_t aMin ,
1799
+ ReadIntoRequest* aReadIntoRequest, ErrorResult& aRv) {
1776
1800
aRv.MightThrowJSException ();
1777
1801
1778
1802
@@ -1799,6 +1823,17 @@ void ReadableByteStreamControllerPullInto(
1799
1823
}
1800
1824
1801
1825
1826
+ uint64_t minimumFill = aMin * elementSize;
1827
+
1828
+
1829
+ MOZ_ASSERT (minimumFill >= 0 &&
1830
+ minimumFill <= JS_GetArrayBufferViewByteLength (aView));
1831
+
1832
+
1833
+
1834
+ MOZ_ASSERT ((minimumFill % elementSize) == 0 );
1835
+
1836
+
1802
1837
size_t byteOffset = JS_GetArrayBufferViewByteOffset (aView);
1803
1838
1804
1839
@@ -1851,9 +1886,10 @@ void ReadableByteStreamControllerPullInto(
1851
1886
1852
1887
1853
1888
1889
+
1854
1890
RefPtr<PullIntoDescriptor> pullIntoDescriptor = new PullIntoDescriptor (
1855
1891
buffer, JS::GetArrayBufferByteLength (buffer), byteOffset, byteLength, 0 ,
1856
- elementSize, ctor, ReaderType::BYOB);
1892
+ minimumFill, elementSize, ctor, ReaderType::BYOB);
1857
1893
1858
1894
1859
1895
if (!aController->PendingPullIntos ().isEmpty ()) {
@@ -1953,7 +1989,6 @@ void ReadableByteStreamControllerPullInto(
1953
1989
ReadableStreamAddReadIntoRequest (stream, aReadIntoRequest);
1954
1990
1955
1991
1956
-
1957
1992
ReadableByteStreamControllerCallPullIfNeeded (aCx, aController, aRv);
1958
1993
}
1959
1994
0 commit comments