@@ -94,6 +94,7 @@ const { |
94 | 94 | ArrayBufferViewGetByteLength, |
95 | 95 | ArrayBufferViewGetByteOffset, |
96 | 96 | AsyncIterator, |
| 97 | + canCopyArrayBuffer, |
97 | 98 | cloneAsUint8Array, |
98 | 99 | copyArrayBuffer, |
99 | 100 | createPromiseCallback, |
@@ -2552,6 +2553,15 @@ function readableByteStreamControllerCommitPullIntoDescriptor(stream, desc) { |
2552 | 2553 | } |
2553 | 2554 | } |
2554 | 2555 |
|
| 2556 | +function readableByteStreamControllerCommitPullIntoDescriptors(stream, descriptors) { |
| 2557 | + for (let i = 0; i < descriptors.length; ++i) { |
| 2558 | + readableByteStreamControllerCommitPullIntoDescriptor( |
| 2559 | + stream, |
| 2560 | + descriptors[i], |
| 2561 | + ); |
| 2562 | + } |
| 2563 | +} |
| 2564 | + |
2555 | 2565 | function readableByteStreamControllerInvalidateBYOBRequest(controller) { |
2556 | 2566 | if (controller[kState].byobRequest === null) |
2557 | 2567 | return; |
@@ -2758,11 +2768,11 @@ function readableByteStreamControllerRespondInClosedState(controller, desc) { |
2758 | 2768 | stream, |
2759 | 2769 | } = controller[kState]; |
2760 | 2770 | if (readableStreamHasBYOBReader(stream)) { |
2761 | | - while (readableStreamGetNumReadIntoRequests(stream) > 0) { |
2762 | | - readableByteStreamControllerCommitPullIntoDescriptor( |
2763 | | - stream, |
2764 | | - readableByteStreamControllerShiftPendingPullInto(controller)); |
| 2771 | + const filledPullIntos = []; |
| 2772 | + for (let i = 0; i < readableStreamGetNumReadIntoRequests(stream); ++i) { |
| 2773 | + ArrayPrototypePush(filledPullIntos, readableByteStreamControllerShiftPendingPullInto(controller)); |
2765 | 2774 | } |
| 2775 | + readableByteStreamControllerCommitPullIntoDescriptors(stream, filledPullIntos); |
2766 | 2776 | } |
2767 | 2777 | } |
2768 | 2778 |
|
@@ -2843,8 +2853,9 @@ function readableByteStreamControllerEnqueue(controller, chunk) { |
2843 | 2853 | transferredBuffer, |
2844 | 2854 | byteOffset, |
2845 | 2855 | byteLength); |
2846 | | - readableByteStreamControllerProcessPullIntoDescriptorsUsingQueue( |
| 2856 | + const filledPullIntos = readableByteStreamControllerProcessPullIntoDescriptorsUsingQueue( |
2847 | 2857 | controller); |
| 2858 | + readableByteStreamControllerCommitPullIntoDescriptors(stream, filledPullIntos); |
2848 | 2859 | } else { |
2849 | 2860 | assert(!isReadableStreamLocked(stream)); |
2850 | 2861 | readableByteStreamControllerEnqueueChunkToQueue( |
@@ -2937,6 +2948,7 @@ function readableByteStreamControllerFillPullIntoDescriptorFromQueue( |
2937 | 2948 | const maxAlignedBytes = maxBytesFilled - (maxBytesFilled % elementSize); |
2938 | 2949 | let totalBytesToCopyRemaining = maxBytesToCopy; |
2939 | 2950 | let ready = false; |
| 2951 | + assert(!ArrayBufferPrototypeGetDetached(buffer)); |
2940 | 2952 | assert(bytesFilled < minimumFill); |
2941 | 2953 | if (maxAlignedBytes >= minimumFill) { |
2942 | 2954 | totalBytesToCopyRemaining = maxAlignedBytes - bytesFilled; |
@@ -2952,12 +2964,12 @@ function readableByteStreamControllerFillPullIntoDescriptorFromQueue( |
2952 | 2964 | totalBytesToCopyRemaining, |
2953 | 2965 | headOfQueue.byteLength); |
2954 | 2966 | const destStart = byteOffset + desc.bytesFilled; |
2955 | | - const arrayBufferByteLength = ArrayBufferPrototypeGetByteLength(buffer); |
2956 | | - if (arrayBufferByteLength - destStart < bytesToCopy) { |
2957 | | - throw new ERR_INVALID_STATE.RangeError( |
2958 | | - 'view ArrayBuffer size is invalid'); |
2959 | | - } |
2960 | | - assert(arrayBufferByteLength - destStart >= bytesToCopy); |
| 2967 | + assert(canCopyArrayBuffer( |
| 2968 | + buffer, |
| 2969 | + destStart, |
| 2970 | + headOfQueue.buffer, |
| 2971 | + headOfQueue.byteOffset, |
| 2972 | + bytesToCopy)); |
2961 | 2973 | copyArrayBuffer( |
2962 | 2974 | buffer, |
2963 | 2975 | destStart, |
@@ -2991,26 +3003,30 @@ function readableByteStreamControllerProcessPullIntoDescriptorsUsingQueue( |
2991 | 3003 | const { |
2992 | 3004 | closeRequested, |
2993 | 3005 | pendingPullIntos, |
2994 | | - stream, |
2995 | 3006 | } = controller[kState]; |
2996 | 3007 | assert(!closeRequested); |
| 3008 | + const filledPullIntos = []; |
2997 | 3009 | while (pendingPullIntos.length) { |
2998 | 3010 | if (!controller[kState].queueTotalSize) |
2999 | | - return; |
| 3011 | + break; |
3000 | 3012 | const desc = pendingPullIntos[0]; |
3001 | 3013 | if (readableByteStreamControllerFillPullIntoDescriptorFromQueue( |
3002 | 3014 | controller, |
3003 | 3015 | desc)) { |
3004 | 3016 | readableByteStreamControllerShiftPendingPullInto(controller); |
3005 | | - readableByteStreamControllerCommitPullIntoDescriptor(stream, desc); |
| 3017 | + ArrayPrototypePush(filledPullIntos, desc); |
3006 | 3018 | } |
3007 | 3019 | } |
| 3020 | + return filledPullIntos; |
3008 | 3021 | } |
3009 | 3022 |
|
3010 | 3023 | function readableByteStreamControllerRespondInReadableState( |
3011 | 3024 | controller, |
3012 | 3025 | bytesWritten, |
3013 | 3026 | desc) { |
| 3027 | + const { |
| 3028 | + stream, |
| 3029 | + } = controller[kState]; |
3014 | 3030 | const { |
3015 | 3031 | buffer, |
3016 | 3032 | bytesFilled, |
@@ -3031,9 +3047,10 @@ function readableByteStreamControllerRespondInReadableState( |
3031 | 3047 | controller, |
3032 | 3048 | desc, |
3033 | 3049 | ); |
3034 | | - readableByteStreamControllerProcessPullIntoDescriptorsUsingQueue( |
| 3050 | + const filledPullIntos = readableByteStreamControllerProcessPullIntoDescriptorsUsingQueue( |
3035 | 3051 | controller, |
3036 | 3052 | ); |
| 3053 | + readableByteStreamControllerCommitPullIntoDescriptors(stream, filledPullIntos); |
3037 | 3054 | return; |
3038 | 3055 | } |
3039 | 3056 |
|
@@ -3059,10 +3076,10 @@ function readableByteStreamControllerRespondInReadableState( |
3059 | 3076 | ArrayBufferPrototypeGetByteLength(remainder)); |
3060 | 3077 | } |
3061 | 3078 | desc.bytesFilled -= remainderSize; |
3062 | | - readableByteStreamControllerCommitPullIntoDescriptor( |
3063 | | - controller[kState].stream, |
3064 | | - desc); |
3065 | | - readableByteStreamControllerProcessPullIntoDescriptorsUsingQueue(controller); |
| 3079 | + const filledPullIntos = readableByteStreamControllerProcessPullIntoDescriptorsUsingQueue(controller); |
| 3080 | + |
| 3081 | + readableByteStreamControllerCommitPullIntoDescriptor(stream, desc); |
| 3082 | + readableByteStreamControllerCommitPullIntoDescriptors(stream, filledPullIntos); |
3066 | 3083 | } |
3067 | 3084 |
|
3068 | 3085 | function readableByteStreamControllerRespondWithNewView(controller, view) { |
|