Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove abortReason property from WritableStream spec #1177

Merged
merged 15 commits into from
Oct 25, 2021
Merged
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 34 additions & 7 deletions index.bs
Original file line number Diff line number Diff line change
@@ -2241,6 +2241,7 @@ create them does not matter.
1. Assert: |cloneForBranch2| is a boolean.
1. Let |reader| be ? [$AcquireReadableStreamDefaultReader$](|stream|).
1. Let |reading| be false.
1. Let |readAgain| be false.
1. Let |canceled1| be false.
1. Let |canceled2| be false.
1. Let |reason1| be undefined.
@@ -2249,13 +2250,15 @@ create them does not matter.
1. Let |branch2| be undefined.
1. Let |cancelPromise| be [=a new promise=].
1. Let |pullAlgorithm| be the following steps:
1. If |reading| is true, return [=a promise resolved with=] undefined.
1. If |reading| is true,
1. Set |readAgain| to true.
1. Return [=a promise resolved with=] undefined.
1. Set |reading| to true.
1. Let |readRequest| be a [=read request=] with the following [=struct/items=]:
: [=read request/chunk steps=], given |chunk|
::
1. [=Queue a microtask=] to perform the following steps:
1. Set |reading| to false.
1. Set |readAgain| to false.
1. Let |chunk1| and |chunk2| be |chunk|.
1. If |canceled2| is false and |cloneForBranch2| is true,
1. Let |cloneResult| be [$StructuredClone$](|chunk2|).
@@ -2271,6 +2274,8 @@ create them does not matter.
1. If |canceled2| is false, perform !
[$ReadableStreamDefaultControllerEnqueue$](|branch2|.[=ReadableStream/[[controller]]=],
|chunk2|).
1. Set |reading| to false.
1. If |readAgain| is true, perform |pullAlgorithm|.

<p class="note">The microtask delay here is necessary because it takes at least a microtask to
detect errors, when we use |reader|.[=ReadableStreamGenericReader/[[closedPromise]]=] below.
@@ -2331,6 +2336,8 @@ create them does not matter.
{{ReadableByteStreamController}}.
1. Let |reader| be ? [$AcquireReadableStreamDefaultReader$](|stream|).
1. Let |reading| be false.
1. Let |readAgainForBranch1| be false.
1. Let |readAgainForBranch2| be false.
1. Let |canceled1| be false.
1. Let |canceled2| be false.
1. Let |reason1| be undefined.
@@ -2357,7 +2364,8 @@ create them does not matter.
: [=read request/chunk steps=], given |chunk|
::
1. [=Queue a microtask=] to perform the following steps:
1. Set |reading| to false.
1. Set |readAgainForBranch1| to false.
1. Set |readAgainForBranch2| to false.
1. Let |chunk1| and |chunk2| be |chunk|.
1. If |canceled1| is false and |canceled2| is false,
1. Let |cloneResult| be [$CloneAsUint8Array$](|chunk|).
@@ -2373,6 +2381,9 @@ create them does not matter.
1. If |canceled2| is false, perform !
[$ReadableByteStreamControllerEnqueue$](|branch2|.[=ReadableStream/[[controller]]=],
|chunk2|).
1. Set |reading| to false.
1. If |readAgainForBranch1| is true, perform |pull1Algorithm|.
1. Otherwise, if |readAgainForBranch2| is true, perform |pull2Algorithm|.

<p class="note">The microtask delay here is necessary because it takes at least a microtask to
detect errors, when we use |reader|.[=ReadableStreamGenericReader/[[closedPromise]]=] below.
@@ -2410,7 +2421,8 @@ create them does not matter.
: [=read-into request/chunk steps=], given |chunk|
::
1. [=Queue a microtask=] to perform the following steps:
1. Set |reading| to false.
1. Set |readAgainForBranch1| to false.
1. Set |readAgainForBranch2| to false.
1. Let |byobCanceled| be |canceled2| if |forBranch2| is true, and |canceled1| otherwise.
1. Let |otherCanceled| be |canceled2| if |forBranch2| is false, and |canceled1| otherwise.
1. If |otherCanceled| is false,
@@ -2429,6 +2441,9 @@ create them does not matter.
1. Otherwise, if |byobCanceled| is false, perform !
[$ReadableByteStreamControllerRespondWithNewView$](|byobBranch|.[=ReadableStream/[[controller]]=],
|chunk|).
1. Set |reading| to false.
1. If |readAgainForBranch1| is true, perform |pull1Algorithm|.
1. Otherwise, if |readAgainForBranch2| is true, perform |pull2Algorithm|.

<p class="note">The microtask delay here is necessary because it takes at least a microtask to
detect errors, when we use |reader|.[=ReadableStreamGenericReader/[[closedPromise]]=] below.
@@ -2460,14 +2475,18 @@ create them does not matter.
1. Set |reading| to false.
1. Perform ! [$ReadableStreamBYOBReaderRead$](|reader|, |view|, |readIntoRequest|).
1. Let |pull1Algorithm| be the following steps:
1. If |reading| is true, return [=a promise resolved with=] undefined.
1. If |reading| is true,
1. Set |readAgainForBranch1| to true.
1. Return [=a promise resolved with=] undefined.
1. Set |reading| to true.
1. Let |byobRequest| be ! [$ReadableByteStreamControllerGetBYOBRequest$](|branch1|.[=ReadableStream/[[controller]]=]).
1. If |byobRequest| is null, perform |pullWithDefaultReader|.
1. Otherwise, perform |pullWithBYOBReader|, given |byobRequest|.[=ReadableStreamBYOBRequest/[[view]]=] and false.
1. Return [=a promise resolved with=] undefined.
1. Let |pull2Algorithm| be the following steps:
1. If |reading| is true, return [=a promise resolved with=] undefined.
1. If |reading| is true,
1. Set |readAgainForBranch2| to true.
1. Return [=a promise resolved with=] undefined.
1. Set |reading| to true.
1. Let |byobRequest| be ! [$ReadableByteStreamControllerGetBYOBRequest$](|branch2|.[=ReadableStream/[[controller]]=]).
1. If |byobRequest| is null, perform |pullWithDefaultReader|.
@@ -3137,10 +3156,17 @@ The following abstract operations support the implementation of the
1. Perform ! [$ReadableByteStreamControllerInvalidateBYOBRequest$](|controller|).
1. If ! [$ReadableStreamHasDefaultReader$](|stream|) is true
1. If ! [$ReadableStreamGetNumReadRequests$](|stream|) is 0,
1. Assert: |controller|.[=ReadableByteStreamController/[[pendingPullIntos]]=] is
[=list/is empty|empty=].
1. Perform ! [$ReadableByteStreamControllerEnqueueChunkToQueue$](|controller|,
|transferredBuffer|, |byteOffset|, |byteLength|).
1. Otherwise,
1. Assert: |controller|.[=ReadableByteStreamController/[[queue]]=] [=list/is empty=].
1. If |controller|.[=ReadableByteStreamController/[[pendingPullIntos]]=] is not
[=list/is empty|empty=],
1. Assert: |controller|.[=ReadableByteStreamController/[[pendingPullIntos]]=][0]'s [=pull-into
descriptor/reader type=] is "`default`".
1. Perform ! [$ReadableByteStreamControllerShiftPendingPullInto$](|controller|).
1. Let |transferredView| be ! [$Construct$]({{%Uint8Array%}}, « |transferredBuffer|,
|byteOffset|, |byteLength| »).
1. Perform ! [$ReadableStreamFulfillReadRequest$](|stream|, |transferredView|, false).
@@ -3489,9 +3515,10 @@ The following abstract operations support the implementation of the
|view|.\[[ViewedArrayBuffer]].\[[ByteLength]], throw a {{RangeError}} exception.
1. If |firstDescriptor|'s [=pull-into descriptor/bytes filled=] + |view|.\[[ByteLength]] >
|firstDescriptor|'s [=pull-into descriptor/byte length=], throw a {{RangeError}} exception.
1. Let |viewByteLength| be |view|.\[[ByteLength]].
1. Set |firstDescriptor|'s [=pull-into descriptor/buffer=] to ?
[$TransferArrayBuffer$](|view|.\[[ViewedArrayBuffer]]).
1. Perform ? [$ReadableByteStreamControllerRespondInternal$](|controller|, |view|.\[[ByteLength]]).
1. Perform ? [$ReadableByteStreamControllerRespondInternal$](|controller|, |viewByteLength|).
</div>

<div algorithm>
44 changes: 38 additions & 6 deletions reference-implementation/lib/abstract-ops/readable-streams.js
Original file line number Diff line number Diff line change
@@ -348,6 +348,7 @@ function ReadableStreamDefaultTee(stream, cloneForBranch2) {
const reader = AcquireReadableStreamDefaultReader(stream);

let reading = false;
let readAgain = false;
let canceled1 = false;
let canceled2 = false;
let reason1;
@@ -359,6 +360,7 @@ function ReadableStreamDefaultTee(stream, cloneForBranch2) {

function pullAlgorithm() {
if (reading === true) {
readAgain = true;
return promiseResolvedWith(undefined);
}

@@ -370,7 +372,7 @@ function ReadableStreamDefaultTee(stream, cloneForBranch2) {
// reader._closedPromise below), and we want errors in stream to error both branches immediately. We cannot let
// successful synchronously-available reads get ahead of asynchronously-available errors.
queueMicrotask(() => {
reading = false;
readAgain = false;
const chunk1 = chunk;
const chunk2 = chunk;

@@ -390,10 +392,14 @@ function ReadableStreamDefaultTee(stream, cloneForBranch2) {
if (canceled1 === false) {
ReadableStreamDefaultControllerEnqueue(branch1._controller, chunk1);
}

if (canceled2 === false) {
ReadableStreamDefaultControllerEnqueue(branch2._controller, chunk2);
}

reading = false;
if (readAgain === true) {
pullAlgorithm();
}
});
},
closeSteps: () => {
@@ -460,6 +466,8 @@ function ReadableByteStreamTee(stream) {
assert(ReadableByteStreamController.isImpl(stream._controller));

let reader = AcquireReadableStreamDefaultReader(stream);
let readAgainForBranch1 = false;
let readAgainForBranch2 = false;
let reading = false;
let canceled1 = false;
let canceled2 = false;
@@ -498,7 +506,8 @@ function ReadableByteStreamTee(stream) {
// reader._closedPromise below), and we want errors in stream to error both branches immediately. We cannot let
// successful synchronously-available reads get ahead of asynchronously-available errors.
queueMicrotask(() => {
reading = false;
readAgainForBranch1 = false;
readAgainForBranch2 = false;

const chunk1 = chunk;
let chunk2 = chunk;
@@ -519,6 +528,13 @@ function ReadableByteStreamTee(stream) {
if (canceled2 === false) {
ReadableByteStreamControllerEnqueue(branch2._controller, chunk2);
}

reading = false;
if (readAgainForBranch1 === true) {
pull1Algorithm();
} else if (readAgainForBranch2 === true) {
pull2Algorithm();
}
});
},
closeSteps: () => {
@@ -564,7 +580,8 @@ function ReadableByteStreamTee(stream) {
// reader._closedPromise below), and we want errors in stream to error both branches immediately. We cannot let
// successful synchronously-available reads get ahead of asynchronously-available errors.
queueMicrotask(() => {
reading = false;
readAgainForBranch1 = false;
readAgainForBranch2 = false;

const byobCanceled = forBranch2 ? canceled2 : canceled1;
const otherCanceled = forBranch2 ? canceled1 : canceled2;
@@ -586,6 +603,13 @@ function ReadableByteStreamTee(stream) {
} else if (byobCanceled === false) {
ReadableByteStreamControllerRespondWithNewView(byobBranch._controller, chunk);
}

reading = false;
if (readAgainForBranch1 === true) {
pull1Algorithm();
} else if (readAgainForBranch2 === true) {
pull2Algorithm();
}
});
},
closeSteps: chunk => {
@@ -625,6 +649,7 @@ function ReadableByteStreamTee(stream) {

function pull1Algorithm() {
if (reading === true) {
readAgainForBranch1 = true;
return promiseResolvedWith(undefined);
}

@@ -642,6 +667,7 @@ function ReadableByteStreamTee(stream) {

function pull2Algorithm() {
if (reading === true) {
readAgainForBranch2 = true;
return promiseResolvedWith(undefined);
}

@@ -1289,10 +1315,14 @@ function ReadableByteStreamControllerEnqueue(controller, chunk) {

if (ReadableStreamHasDefaultReader(stream) === true) {
if (ReadableStreamGetNumReadRequests(stream) === 0) {
assert(controller._pendingPullIntos.length === 0);
ReadableByteStreamControllerEnqueueChunkToQueue(controller, transferredBuffer, byteOffset, byteLength);
} else {
assert(controller._queue.length === 0);

if (controller._pendingPullIntos.length > 0) {
assert(controller._pendingPullIntos[0].readerType === 'default');
ReadableByteStreamControllerShiftPendingPullInto(controller);
}
const transferredView = new Uint8Array(transferredBuffer, byteOffset, byteLength);
ReadableStreamFulfillReadRequest(stream, transferredView, false);
}
@@ -1634,9 +1664,11 @@ function ReadableByteStreamControllerRespondWithNewView(controller, view) {
throw new RangeError('The region specified by view is larger than byobRequest');
}

const viewByteLength = view.byteLength;

firstDescriptor.buffer = TransferArrayBuffer(view.buffer);

ReadableByteStreamControllerRespondInternal(controller, view.byteLength);
ReadableByteStreamControllerRespondInternal(controller, viewByteLength);
}

function ReadableByteStreamControllerShiftPendingPullInto(controller) {