From be7d6b0f2596a1ffbc8a22e1886026dcd0d29e39 Mon Sep 17 00:00:00 2001 From: Jason Orendorff Date: Mon, 26 Nov 2018 14:34:02 -0600 Subject: [PATCH] Treat forAuthorCode as an internal slot of reader object. This editorial change doesn't affect any observable behavior. Closes #964. --- index.bs | 88 +++++++++++++++++++++++++++++--------------------------- 1 file changed, 46 insertions(+), 42 deletions(-) diff --git a/index.bs b/index.bs index 35f66b84f..09eb7ae12 100644 --- a/index.bs +++ b/index.bs @@ -625,9 +625,9 @@ option. If type is set to unde 1. If ! IsReadableStream(*this*) is *false*, throw a *TypeError* exception. - 1. If _mode_ is *undefined*, return ? AcquireReadableStreamDefaultReader(*this*). + 1. If _mode_ is *undefined*, return ? Construct(`ReadableStreamDefaultReader`, « *this* »). 1. Set _mode_ to ? ToString(_mode_). - 1. If _mode_ is `"byob"`, return ? AcquireReadableStreamBYOBReader(*this*). + 1. If _mode_ is `"byob"`, return ? Construct(`ReadableStreamBYOBReader`, « *this* »). 1. Throw a *RangeError* exception. @@ -902,7 +902,9 @@ This abstract operation is meant to be called from other specifications that may for a given stream. - 1. Return ? Construct(`ReadableStreamBYOBReader`, « _stream_ »). + 1. Let _reader_ be ? Construct(`ReadableStreamBYOBReader`, « _stream_ »). + 1. Set _reader_.[[forAuthorCode]] to *false*. + 1. Return _reader_.

for a given stream. - 1. Return ? Construct(`ReadableStreamDefaultReader`, « _stream_ »). + 1. Let _reader_ be ? Construct(`ReadableStreamDefaultReader`, « _stream_ »). + 1. Set _reader_.[[forAuthorCode]] to *false*. + 1. Return _reader_.

CreateReadableStream ( @@ -1113,25 +1117,25 @@ implementations to affect their associated {{ReadableStream}} object. This trans controller into developer-facing results visible through the {{ReadableStream}}'s public API.

ReadableStreamAddReadIntoRequest ( stream, forAuthorCode )

+nothrow>ReadableStreamAddReadIntoRequest ( stream ) 1. Assert: ! IsReadableStreamBYOBReader(_stream_.[[reader]]) is *true*. 1. Assert: _stream_.[[state]] is `"readable"` or `"closed"`. 1. Let _promise_ be a new promise. - 1. Let _readIntoRequest_ be Record {[[promise]]: _promise_, [[forAuthorCode]]: _forAuthorCode_}. + 1. Let _readIntoRequest_ be Record {[[promise]]: _promise_}. 1. Append _readIntoRequest_ as the last element of _stream_.[[reader]].[[readIntoRequests]]. 1. Return _promise_.

ReadableStreamAddReadRequest ( -stream, forAuthorCode )

+stream ) 1. Assert: ! IsReadableStreamDefaultReader(_stream_.[[reader]]) is *true*. 1. Assert: _stream_.[[state]] is `"readable"`. 1. Let _promise_ be a new promise. - 1. Let _readRequest_ be Record {[[promise]]: _promise_, [[forAuthorCode]]: _forAuthorCode_}. + 1. Let _readRequest_ be Record {[[promise]]: _promise_}. 1. Append _readRequest_ as the last element of _stream_.[[reader]].[[readRequests]]. 1. Return _promise_. @@ -1157,8 +1161,7 @@ nothrow>ReadableStreamAddReadIntoRequest ( stream, forAuthorCode 1. If _reader_ is *undefined*, return. 1. If ! IsReadableStreamDefaultReader(_reader_) is *true*, 1. Repeat for each _readRequest_ that is an element of _reader_.[[readRequests]], - 1. Resolve _readRequest_.[[promise]] with ! ReadableStreamCreateReadResult(*undefined*, *true*, - _readRequest_.[[forAuthorCode]]). + 1. Resolve _readRequest_.[[promise]] with ! ReadableStreamCreateReadResult(*undefined*, *true*, _reader_). 1. Set _reader_.[[readRequests]] to an empty List. 1. Resolve _reader_.[[closedPromise]] with *undefined*. @@ -1172,10 +1175,10 @@ nothrow>ReadableStreamAddReadIntoRequest ( stream, forAuthorCode

ReadableStreamCreateReadResult -( value, done, forAuthorCode )

+( value, done, reader )
- When forAuthorCode is true, this abstract operation gives the same result + When reader.\[[forAuthorCode]] is true, this abstract operation gives the same result as CreateIterResultObject(value, done). This provides the expected semantics when the object is to be returned from the {{ReadableStreamDefaultReader/read()|defaultReader.read()}} or {{ReadableStreamBYOBReader/read()|byobReader.read()}} methods. @@ -1183,8 +1186,9 @@ nothrow>ReadableStreamAddReadIntoRequest ( stream, forAuthorCode However, resolving promises with such objects will unavoidably result in an access to Object.prototype.then. For internal use, particularly in {{ReadableStream/pipeTo()}} and in other specifications, it is important that reads not be observable by author code—even if that author code has tampered with - Object.prototype. For this reason, a false value of forAuthorCode results - in an object with a null prototype, keeping promise resolution unobservable. + Object.prototype. For this reason, a false value of + reader.\[[forAuthorCode]] results in an object with a null prototype, keeping promise + resolution unobservable. The underlying issue here is that reading from streams always uses promises for { value, done } objects, even in specifications. Although it is conceivable we could rephrase all of the internal algorithms to not use @@ -1195,7 +1199,7 @@ nothrow>ReadableStreamAddReadIntoRequest ( stream, forAuthorCode 1. Let _prototype_ be *null*. - 1. If _forAuthorCode_ is *true*, set _prototype_ to %ObjectPrototype%. + 1. If _reader_.[[forAuthorCode]] is *true*, set _prototype_ to %ObjectPrototype%. 1. Assert: Type(_done_) is Boolean. 1. Let _obj_ be ObjectCreate(_prototype_). 1. Perform CreateDataProperty(_obj_, `"value"`, _value_). @@ -1234,8 +1238,7 @@ nothrow>ReadableStreamFulfillReadIntoRequest ( stream, chunkResolve _readIntoRequest_.[[promise]] with ! ReadableStreamCreateReadResult(_chunk_, _done_, - _readIntoRequest_.[[forAuthorCode]]). + 1. Resolve _readIntoRequest_.[[promise]] with ! ReadableStreamCreateReadResult(_chunk_, _done_, _reader_).

ReadableStreamFulfillReadRequest ( stream, chunk, 1. Let _readRequest_ be the first element of _reader_.[[readRequests]]. 1. Remove _readRequest_ from _reader_.[[readRequests]], shifting all other elements downward (so that the second becomes the first, and so on). - 1. Resolve _readRequest_.[[promise]] with ! ReadableStreamCreateReadResult(_chunk_, _done_, - _readRequest_.[[forAuthorCode]]). + 1. Resolve _readRequest_.[[promise]] with ! ReadableStreamCreateReadResult(_chunk_, _done_, _reader_).

\[[closedPromise]] A promise returned by the reader's {{ReadableStreamDefaultReader/closed}} getter + + \[[forAuthorCode]] + A boolean flag indicating whether this reader is visible to author code + \[[ownerReadableStream]] A {{ReadableStream}} instance that owns this reader @@ -1470,6 +1476,10 @@ Instances of {{ReadableStreamBYOBReader}} are created with the internal slots de \[[closedPromise]] A promise returned by the reader's {{ReadableStreamBYOBReader/closed}} getter + + \[[forAuthorCode]] + A boolean flag indicating whether this reader is visible to author code + \[[ownerReadableStream]] A {{ReadableStream}} instance that owns this reader @@ -1609,6 +1619,7 @@ nothrow>ReadableStreamReaderGenericCancel ( reader, reason nothrow>ReadableStreamReaderGenericInitialize ( reader, stream )

+ 1. Set _reader_.[[forAuthorCode]] to *true*. 1. Set _reader_.[[ownerReadableStream]] to _stream_. 1. Set _stream_.[[reader]] to _reader_. 1. If _stream_.[[state]] is `"readable"`, @@ -1636,35 +1647,28 @@ nothrow>ReadableStreamReaderGenericRelease ( reader )

ReadableStreamBYOBReaderRead -( reader, view [, forAuthorCode ] )

+( reader, view ) - 1. If _forAuthorCode_ was not passed, set it to *false*. 1. Let _stream_ be _reader_.[[ownerReadableStream]]. 1. Assert: _stream_ is not *undefined*. 1. Set _stream_.[[disturbed]] to *true*. 1. If _stream_.[[state]] is `"errored"`, return a promise rejected with _stream_.[[storedError]]. - 1. Return ! ReadableByteStreamControllerPullInto(_stream_.[[readableStreamController]], _view_, _forAuthorCode_). + 1. Return ! ReadableByteStreamControllerPullInto(_stream_.[[readableStreamController]], _view_).

ReadableStreamDefaultReaderRead ( reader [, forAuthorCode ] )

- -

Other specifications ought to leave forAuthorCode as its default value of -false, unless they are planning to directly expose the resulting { value, done } object -to authors. See the note regarding ReadableStreamCreateReadResult for more -information.

+export>ReadableStreamDefaultReaderRead ( reader ) - 1. If _forAuthorCode_ was not passed, set it to *false*. 1. Let _stream_ be _reader_.[[ownerReadableStream]]. 1. Assert: _stream_ is not *undefined*. 1. Set _stream_.[[disturbed]] to *true*. 1. If _stream_.[[state]] is `"closed"`, return a promise resolved with ! - ReadableStreamCreateReadResult(*undefined*, *true*, _forAuthorCode_). + ReadableStreamCreateReadResult(*undefined*, *true*, _reader_). 1. If _stream_.[[state]] is `"errored"`, return a promise rejected with _stream_.[[storedError]]. 1. Assert: _stream_.[[state]] is `"readable"`. - 1. Return ! _stream_.[[readableStreamController]].[[PullSteps]](_forAuthorCode_). + 1. Return ! _stream_.[[readableStreamController]].[[PullSteps]]().

Class @@ -1840,7 +1844,7 @@ readable stream implementation will polymorphically call to either these or thei 1. Return _result_. -

\[[PullSteps]]( forAuthorCode )
+
\[[PullSteps]]( )
1. Let _stream_ be *this*.[[controlledReadableStream]]. @@ -1850,8 +1854,8 @@ readable stream implementation will polymorphically call to either these or thei 1. Perform ! ReadableStreamDefaultControllerClearAlgorithms(*this*). 1. Perform ! ReadableStreamClose(_stream_). 1. Otherwise, perform ! ReadableStreamDefaultControllerCallPullIfNeeded(*this*). - 1. Return a promise resolved with ! ReadableStreamCreateReadResult(_chunk_, *false*, _forAuthorCode_). - 1. Let _pendingPromise_ be ! ReadableStreamAddReadRequest(_stream_, _forAuthorCode_). + 1. Return a promise resolved with ! ReadableStreamCreateReadResult(_chunk_, *false*, _stream_.[[reader]]). + 1. Let _pendingPromise_ be ! ReadableStreamAddReadRequest(_stream_). 1. Perform ! ReadableStreamDefaultControllerCallPullIfNeeded(*this*). 1. Return _pendingPromise_. @@ -2281,7 +2285,7 @@ readable stream implementation will polymorphically call to either these or thei 1. Return _result_. -
\[[PullSteps]]( forAuthorCode )
+
\[[PullSteps]]( )
1. Let _stream_ be *this*.[[controlledReadableByteStream]]. @@ -2295,7 +2299,7 @@ readable stream implementation will polymorphically call to either these or thei 1. Perform ! ReadableByteStreamControllerHandleQueueDrain(*this*). 1. Let _view_ be ! Construct(%Uint8Array%, « _entry_.[[buffer]], _entry_.[[byteOffset]], _entry_.[[byteLength]] »). - 1. Return a promise resolved with ! ReadableStreamCreateReadResult(_view_, *false*, _forAuthorCode_). + 1. Return a promise resolved with ! ReadableStreamCreateReadResult(_view_, *false*, _stream_.[[reader]]). 1. Let _autoAllocateChunkSize_ be *this*.[[autoAllocateChunkSize]]. 1. If _autoAllocateChunkSize_ is not *undefined*, 1. Let _buffer_ be Construct(%ArrayBuffer%, « _autoAllocateChunkSize_ »). @@ -2304,7 +2308,7 @@ readable stream implementation will polymorphically call to either these or thei _autoAllocateChunkSize_, [[bytesFilled]]: *0*, [[elementSize]]: *1*, [[ctor]]: %Uint8Array%, [[readerType]]: `"default"`}. 1. Append _pullIntoDescriptor_ as the last element of *this*.[[pendingPullIntos]]. - 1. Let _promise_ be ! ReadableStreamAddReadRequest(_stream_, _forAuthorCode_). + 1. Let _promise_ be ! ReadableStreamAddReadRequest(_stream_). 1. Perform ! ReadableByteStreamControllerCallPullIfNeeded(*this*). 1. Return _promise_. @@ -2671,7 +2675,7 @@ nothrow>ReadableByteStreamControllerProcessPullIntoDescriptorsUsingQueue (

ReadableByteStreamControllerPullInto ( controller, view, forAuthorCode )

+nothrow>ReadableByteStreamControllerPullInto ( controller, view ) 1. Let _stream_ be _controller_.[[controlledReadableByteStream]]. @@ -2690,21 +2694,21 @@ nothrow>ReadableByteStreamControllerPullInto ( controller, view< [[ctor]]: _ctor_, [[readerType]]: `"byob"`}. 1. If _controller_.[[pendingPullIntos]] is not empty, 1. Append _pullIntoDescriptor_ as the last element of _controller_.[[pendingPullIntos]]. - 1. Return ! ReadableStreamAddReadIntoRequest(_stream_, _forAuthorCode_). + 1. Return ! ReadableStreamAddReadIntoRequest(_stream_). 1. If _stream_.[[state]] is `"closed"`, 1. Let _emptyView_ be ! Construct(_ctor_, « _pullIntoDescriptor_.[[buffer]], _pullIntoDescriptor_.[[byteOffset]], *0* »). - 1. Return a promise resolved with ! ReadableStreamCreateReadResult(_emptyView_, *true*, _forAuthorCode_). + 1. Return a promise resolved with ! ReadableStreamCreateReadResult(_emptyView_, *true*, _stream_.[[reader]]). 1. If _controller_.[[queueTotalSize]] > *0*, 1. If ! ReadableByteStreamControllerFillPullIntoDescriptorFromQueue(_controller_, _pullIntoDescriptor_) is *true*, 1. Let _filledView_ be ! ReadableByteStreamControllerConvertPullIntoDescriptor(_pullIntoDescriptor_). 1. Perform ! ReadableByteStreamControllerHandleQueueDrain(_controller_). - 1. Return a promise resolved with ! ReadableStreamCreateReadResult(_filledView_, *false*, _forAuthorCode_). + 1. Return a promise resolved with ! ReadableStreamCreateReadResult(_filledView_, *false*, _stream_.[[reader]]). 1. If _controller_.[[closeRequested]] is *true*, 1. Let _e_ be a *TypeError* exception. 1. Perform ! ReadableByteStreamControllerError(_controller_, _e_). 1. Return a promise rejected with _e_. 1. Append _pullIntoDescriptor_ as the last element of _controller_.[[pendingPullIntos]]. - 1. Let _promise_ be ! ReadableStreamAddReadIntoRequest(_stream_, _forAuthorCode_). + 1. Let _promise_ be ! ReadableStreamAddReadIntoRequest(_stream_). 1. Perform ! ReadableByteStreamControllerCallPullIfNeeded(_controller_). 1. Return _promise_.