Title: [205289] trunk
Revision
205289
Author
commit-qu...@webkit.org
Date
2016-09-01 07:14:05 -0700 (Thu, 01 Sep 2016)

Log Message

[Streams API] Align internal structure of ReadableStream with spec
https://bugs.webkit.org/show_bug.cgi?id=160299

Patch by Romain Bellessort <romain.belless...@crf.canon.fr> on 2016-09-01
Reviewed by Xabier Rodriguez-Calvar.

LayoutTests/imported/w3c:

Aligned internal structure of ReadableStream with spec. Fixed one expectation
that was set to FAIL while it is now PASSing.

* web-platform-tests/streams/readable-streams/general.https-expected.txt:

Source/WebCore:

Aligned internal structure of ReadableStream with spec. Various
internal properties have been moved to ReadableStreamDefaultController.
In addition, various behaviors had to be updated. Several other changes
will have to be performed in order to align with spec, e.g. changing
functions names. This patch does not change them in order to make the
structural changes easier to follow.

No change in functionality except support for 1 specific case where
an error was not thrown while it should have been. Changed corresponding
test expectation (now PASS instead of FAIL).
Modified test expectation: web-platform-tests/streams/readable-streams/general.https-expected.txt

* Modules/fetch/FetchResponse.js:
(initializeFetchResponse): Replaced reference to underlyingSource as no
more a property of readableStream (use readableStreamController instead,
as defined by spec).
* Modules/streams/ReadableStream.js:
(initializeReadableStream): Removed various properties now hanlded by
ReadableStreamDefaultController.
* Modules/streams/ReadableStreamDefaultController.js:
(enqueue): Updated based on new properties repartition between reader and controller.
(error): Updated based on new properties repartition between reader and controller.
(close): Updated based on new properties repartition between reader and controller.
(desiredSize): Updated based on new properties repartition between reader and controller.
* Modules/streams/ReadableStreamInternals.js:
(privateInitializeReadableStreamDefaultController): Added various properties now handled by
ReadableStreamDefaultController, as well as an internal pull function defined by spec.
(readableStreamDefaultControllerError): Added based on spec (error handling at controller level).
(teeReadableStream): Fixed typo and use readableStreamDefaultControllerError instead of errorReadableStream.
(doStructuredClone): Added "use strict";.
(teeReadableStreamPullFunction): Use readableStreamDefaultControllerClose instead of closeReadableStream.
(isReadableStream): Replaced check of underlyingSource by check that object is actually an instance of
ReadableStream (spec requires checking that readableStreamController slot is present, but this cannot
be checked).
(isReadableStreamDefaultReader): Replaced check of ownerReadableStream presence by check of readRequests,
in line with spec.
(isReadableStreamDefaultController): Replaced check of controlledReadableStream presence by check of unerlyingSource,
in line with spec.
(errorReadableStream): Updated based on new properties repartition between reader and controller.
(requestReadableStreamPull): Updated based on new properties repartition between reader and controller.
(readableStreamDefaultControllerGetDesiredSize): Replaces getReadableStreamDesiredSize (size now depends
on controller; new function name aligned with spec).
(cancelReadableStream): Updated based on new properties repartition between reader and controller.
(readableStreamDefaultControllerClose): Added based on spec (closing controller).
(closeReadableStream): Updated based on new properties repartition between reader and controller.
(enqueueInReadableStream): Updated based on new properties repartition between reader and controller.
(readFromReadableStreamDefaultReader): Updated based on new properties repartition between reader and controller.
* bindings/js/WebCoreBuiltinNames.h: Added pull (internal function of ReadableStreamDefaultController)
and readableStreamController (defined by spec)

Modified Paths

Diff

Modified: trunk/LayoutTests/imported/w3c/ChangeLog (205288 => 205289)


--- trunk/LayoutTests/imported/w3c/ChangeLog	2016-09-01 12:01:00 UTC (rev 205288)
+++ trunk/LayoutTests/imported/w3c/ChangeLog	2016-09-01 14:14:05 UTC (rev 205289)
@@ -1,3 +1,16 @@
+2016-09-01  Romain Bellessort  <romain.belless...@crf.canon.fr>
+
+        [Streams API] Align internal structure of ReadableStream with spec
+        https://bugs.webkit.org/show_bug.cgi?id=160299
+
+        Reviewed by Xabier Rodriguez-Calvar.
+
+        Aligned internal structure of ReadableStream with spec. Fixed one expectation
+        that was set to FAIL while it is now PASSing.
+
+        * web-platform-tests/streams/readable-streams/general.https-expected.txt:
+
+
 2016-08-31  Youenn Fablet  <you...@apple.com>
 
         [Fetch API] Fetch API should be able to load data URL in Same Origin mode

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/general.https-expected.txt (205288 => 205289)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/general.https-expected.txt	2016-09-01 12:01:00 UTC (rev 205288)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/general.https-expected.txt	2016-09-01 14:14:05 UTC (rev 205289)
@@ -1,7 +1,7 @@
 
 PASS ReadableStream can be constructed with no errors 
 PASS ReadableStream can't be constructed with garbage 
-FAIL ReadableStream can't be constructed with an invalid type assert_throws: constructor should throw when the type is null function "() => new ReadableStream({ type: null })" did not throw
+PASS ReadableStream can't be constructed with an invalid type 
 FAIL ReadableStream instances should have the correct list of properties assert_equals: getReader should have no parameters expected 0 but got 1
 PASS ReadableStream constructor should throw for non-function start arguments 
 PASS ReadableStream constructor can get initial garbage as cancel argument 
@@ -38,7 +38,7 @@
 FAIL Untitled undefined is not an object (evaluating 'navigator.serviceWorker.getRegistration')
 PASS ReadableStream can be constructed with no errors 
 PASS ReadableStream can't be constructed with garbage 
-FAIL ReadableStream can't be constructed with an invalid type assert_throws: constructor should throw when the type is null function "() => new ReadableStream({ type: null })" did not throw
+PASS ReadableStream can't be constructed with an invalid type 
 FAIL ReadableStream instances should have the correct list of properties assert_equals: getReader should have no parameters expected 0 but got 1
 PASS ReadableStream constructor should throw for non-function start arguments 
 PASS ReadableStream constructor can get initial garbage as cancel argument 

Modified: trunk/Source/WebCore/ChangeLog (205288 => 205289)


--- trunk/Source/WebCore/ChangeLog	2016-09-01 12:01:00 UTC (rev 205288)
+++ trunk/Source/WebCore/ChangeLog	2016-09-01 14:14:05 UTC (rev 205289)
@@ -1,3 +1,60 @@
+2016-09-01  Romain Bellessort  <romain.belless...@crf.canon.fr>
+
+        [Streams API] Align internal structure of ReadableStream with spec
+        https://bugs.webkit.org/show_bug.cgi?id=160299
+
+        Reviewed by Xabier Rodriguez-Calvar.
+
+        Aligned internal structure of ReadableStream with spec. Various
+        internal properties have been moved to ReadableStreamDefaultController.
+        In addition, various behaviors had to be updated. Several other changes
+        will have to be performed in order to align with spec, e.g. changing
+        functions names. This patch does not change them in order to make the
+        structural changes easier to follow.
+
+        No change in functionality except support for 1 specific case where
+        an error was not thrown while it should have been. Changed corresponding
+        test expectation (now PASS instead of FAIL).
+        Modified test expectation: web-platform-tests/streams/readable-streams/general.https-expected.txt
+
+        * Modules/fetch/FetchResponse.js:
+        (initializeFetchResponse): Replaced reference to underlyingSource as no
+        more a property of readableStream (use readableStreamController instead,
+        as defined by spec).
+        * Modules/streams/ReadableStream.js:
+        (initializeReadableStream): Removed various properties now hanlded by
+        ReadableStreamDefaultController.
+        * Modules/streams/ReadableStreamDefaultController.js:
+        (enqueue): Updated based on new properties repartition between reader and controller. 
+        (error): Updated based on new properties repartition between reader and controller. 
+        (close): Updated based on new properties repartition between reader and controller. 
+        (desiredSize): Updated based on new properties repartition between reader and controller. 
+        * Modules/streams/ReadableStreamInternals.js:
+        (privateInitializeReadableStreamDefaultController): Added various properties now handled by
+        ReadableStreamDefaultController, as well as an internal pull function defined by spec.
+        (readableStreamDefaultControllerError): Added based on spec (error handling at controller level).
+        (teeReadableStream): Fixed typo and use readableStreamDefaultControllerError instead of errorReadableStream.
+        (doStructuredClone): Added "use strict";.
+        (teeReadableStreamPullFunction): Use readableStreamDefaultControllerClose instead of closeReadableStream.
+        (isReadableStream): Replaced check of underlyingSource by check that object is actually an instance of
+        ReadableStream (spec requires checking that readableStreamController slot is present, but this cannot
+        be checked).
+        (isReadableStreamDefaultReader): Replaced check of ownerReadableStream presence by check of readRequests,
+        in line with spec.
+        (isReadableStreamDefaultController): Replaced check of controlledReadableStream presence by check of unerlyingSource,
+        in line with spec.
+        (errorReadableStream): Updated based on new properties repartition between reader and controller.
+        (requestReadableStreamPull): Updated based on new properties repartition between reader and controller.
+        (readableStreamDefaultControllerGetDesiredSize): Replaces getReadableStreamDesiredSize (size now depends
+        on controller; new function name aligned with spec).
+        (cancelReadableStream): Updated based on new properties repartition between reader and controller. 
+        (readableStreamDefaultControllerClose): Added based on spec (closing controller).
+        (closeReadableStream): Updated based on new properties repartition between reader and controller. 
+        (enqueueInReadableStream): Updated based on new properties repartition between reader and controller. 
+        (readFromReadableStreamDefaultReader): Updated based on new properties repartition between reader and controller. 
+        * bindings/js/WebCoreBuiltinNames.h: Added pull (internal function of ReadableStreamDefaultController)
+        and readableStreamController (defined by spec)
+
 2016-09-01  Csaba Osztrogonác  <o...@webkit.org>
 
         Unreviewed, fix the !ENABLE(SVG_FONTS) and !ENABLE(XSLT) build after r205269.

Modified: trunk/Source/WebCore/Modules/fetch/FetchResponse.js (205288 => 205289)


--- trunk/Source/WebCore/Modules/fetch/FetchResponse.js	2016-09-01 12:01:00 UTC (rev 205288)
+++ trunk/Source/WebCore/Modules/fetch/FetchResponse.js	2016-09-01 14:14:05 UTC (rev 205289)
@@ -50,7 +50,7 @@
             throw new @TypeError("Response cannot have a body with the given status");
 
         // FIXME: Use @isReadableStream once it is no longer guarded by STREAMS_API guard.
-        let isBodyReadableStream = (@isObject(body) && !!body.@underlyingSource);
+        let isBodyReadableStream = (@isObject(body) && !!body.@readableStreamController);
         if (isBodyReadableStream)
           this.@body = body;
 

Modified: trunk/Source/WebCore/Modules/streams/ReadableStream.js (205288 => 205289)


--- trunk/Source/WebCore/Modules/streams/ReadableStream.js	2016-09-01 12:01:00 UTC (rev 205288)
+++ trunk/Source/WebCore/Modules/streams/ReadableStream.js	2016-09-01 14:14:05 UTC (rev 205289)
@@ -41,28 +41,26 @@
     if (strategy !== @undefined && !@isObject(strategy))
         throw new @TypeError("ReadableStream constructor takes an object as second argument, if any");
 
-    this.@underlyingSource = underlyingSource;
-
-    this.@queue = @newQueue();
     this.@state = @streamReadable;
-    this.@started = false;
-    this.@closeRequested = false;
-    this.@pullAgain = false;
-    this.@pulling = false;
     this.@reader = @undefined;
     this.@storedError = @undefined;
     this.@disturbed = false;
-    this.@controller = new @ReadableStreamDefaultController(this);
-    this.@strategy = @validateAndNormalizeQueuingStrategy(strategy.size, strategy.highWaterMark);
+    // Initialized with null value to enable distinction with undefined case.
+    this.@readableStreamController = null;
 
-    @promiseInvokeOrNoopNoCatch(underlyingSource, "start", [this.@controller]).@then(() => {
-        this.@started = true;
-        @requestReadableStreamPull(this);
-    }, (error) => {
-        if (this.@state === @streamReadable)
-            @errorReadableStream(this, error);
-    });
+    const type = underlyingSource.type;
+    const typeString = @String(type);
 
+    if (typeString === "bytes") {
+         // FIXME: Implement support of ReadableByteStreamController.
+        throw new @TypeError("ReadableByteStreamController is not implemented");
+    } else if (type === @undefined) {
+        if (strategy.highWaterMark === @undefined)
+            strategy.highWaterMark = 1;
+        this.@readableStreamController = new @ReadableStreamDefaultController(this, underlyingSource, strategy.size, strategy.highWaterMark);
+    } else
+        throw new @RangeError("Invalid type for underlying source");
+
     return this;
 }
 

Modified: trunk/Source/WebCore/Modules/streams/ReadableStreamDefaultController.js (205288 => 205289)


--- trunk/Source/WebCore/Modules/streams/ReadableStreamDefaultController.js	2016-09-01 12:01:00 UTC (rev 205288)
+++ trunk/Source/WebCore/Modules/streams/ReadableStreamDefaultController.js	2016-09-01 14:14:05 UTC (rev 205289)
@@ -32,15 +32,13 @@
     if (!@isReadableStreamDefaultController(this))
         throw @makeThisTypeError("ReadableStreamDefaultController", "enqueue");
 
-    const stream = this.@controlledReadableStream;
+    if (this.@closeRequested)
+        throw new @TypeError("ReadableStreamDefaultController is requested to close");
 
-    if (stream.@closeRequested)
-        throw new @TypeError("ReadableStream is requested to close");
-
-    if (stream.@state !== @streamReadable)
+    if (this.@controlledReadableStream.@state !== @streamReadable)
         throw new @TypeError("ReadableStream is not readable");
 
-    return @enqueueInReadableStream(stream, chunk);
+    return @enqueueInReadableStream(this, chunk);
 }
 
 function error(error)
@@ -64,14 +62,13 @@
     if (!@isReadableStreamDefaultController(this))
         throw @makeThisTypeError("ReadableStreamDefaultController", "close");
 
-    const stream = this.@controlledReadableStream;
-    if (stream.@closeRequested)
-        throw new @TypeError("ReadableStream is already requested to close");
+    if (this.@closeRequested)
+        throw new @TypeError("ReadableStreamDefaultController is already requested to close");
 
-    if (stream.@state !== @streamReadable)
+    if (this.@controlledReadableStream.@state !== @streamReadable)
         throw new @TypeError("ReadableStream is not readable");
 
-    @closeReadableStream(stream);
+    @readableStreamDefaultControllerClose(this);
 }
 
 function desiredSize()
@@ -81,5 +78,6 @@
     if (!@isReadableStreamDefaultController(this))
         throw @makeGetterTypeError("ReadableStreamDefaultController", "desiredSize");
 
-    return @getReadableStreamDesiredSize(this.@controlledReadableStream);
+    return @readableStreamDefaultControllerGetDesiredSize(this);
 }
+

Modified: trunk/Source/WebCore/Modules/streams/ReadableStreamInternals.js (205288 => 205289)


--- trunk/Source/WebCore/Modules/streams/ReadableStreamInternals.js	2016-09-01 12:01:00 UTC (rev 205288)
+++ trunk/Source/WebCore/Modules/streams/ReadableStreamInternals.js	2016-09-01 14:14:05 UTC (rev 205289)
@@ -53,19 +53,65 @@
     return this;
 }
 
-function privateInitializeReadableStreamDefaultController(stream)
+function privateInitializeReadableStreamDefaultController(stream, underlyingSource, size, highWaterMark)
 {
     "use strict";
 
     if (!@isReadableStream(stream))
         throw new @TypeError("ReadableStreamDefaultController needs a ReadableStream");
-    if (stream.@controller !== @undefined)
+
+    // readableStreamController is initialized with null value.
+    if (stream.@readableStreamController !== null)
         throw new @TypeError("ReadableStream already has a controller");
+
     this.@controlledReadableStream = stream;
+    this.@underlyingSource = underlyingSource;
+    this.@queue = @newQueue();
+    this.@started = false;
+    this.@closeRequested = false;
+    this.@pullAgain = false;
+    this.@pulling = false;
+    this.@strategy = @validateAndNormalizeQueuingStrategy(size, highWaterMark);
 
+    const controller = this;
+    const startResult = @promiseInvokeOrNoopNoCatch(underlyingSource, "start", [this]).@then(() => {
+        controller.@started = true;
+        @requestReadableStreamPull(controller);
+    }, (error) => {
+        if (stream.@state === @streamReadable)
+            @readableStreamDefaultControllerError(controller, error);
+    });
+
+    this.@pull = function() {
+        "use strict";
+
+        const stream = controller.@controlledReadableStream;
+        if (controller.@queue.content.length) {
+            const chunk = @dequeueValue(controller.@queue);
+            if (controller.@closeRequested && controller.@queue.content.length === 0)
+                @closeReadableStream(stream);
+            else
+                @requestReadableStreamPull(controller);
+            return @Promise.@resolve({value: chunk, done: false});
+        }
+        const pendingPromise = @readableStreamAddReadRequest(stream);
+        @requestReadableStreamPull(controller);
+        return pendingPromise;
+    }
+
     return this;
 }
 
+function readableStreamDefaultControllerError(controller, error)
+{
+    "use strict";
+
+    const stream = controller.@controlledReadableStream;
+    @assert(stream.@state === @streamReadable);
+    controller.@queue = @newQueue();
+    @errorReadableStream(stream, error);
+}
+
 function teeReadableStream(stream, shouldClone)
 {
     "use strict";
@@ -80,7 +126,7 @@
         canceled1: false,
         canceled2: false,
         reason1: @undefined,
-        reason: @undefined,
+        reason2: @undefined,
     };
 
     teeState.cancelPromiseCapability = @newPromiseCapability(@InternalPromise);
@@ -99,8 +145,8 @@
     reader.@closedPromiseCapability.@promise.@then(@undefined, function(e) {
         if (teeState.closedOrErrored)
             return;
-        @errorReadableStream(branch1, e);
-        @errorReadableStream(branch2, e);
+        @readableStreamDefaultControllerError(branch1.@readableStreamController, e);
+        @readableStreamDefaultControllerError(branch2.@readableStreamController, e);
         teeState.closedOrErrored = true;
     });
 
@@ -113,6 +159,8 @@
 
 function doStructuredClone(object)
 {
+    "use strict";
+
     // FIXME: We should implement http://w3c.github.io/html/infrastructure.html#ref-for-structured-clone-4
     // Implementation is currently limited to ArrayBuffer/ArrayBufferView to meet Fetch API needs.
 
@@ -134,16 +182,18 @@
             @assert(@isObject(result));
             @assert(typeof result.done === "boolean");
             if (result.done && !teeState.closedOrErrored) {
-                @closeReadableStream(teeState.branch1);
-                @closeReadableStream(teeState.branch2);
+                if (!teeState.canceled1)
+                    @readableStreamDefaultControllerClose(teeState.branch1.@readableStreamController);
+                if (!teeState.canceled2)
+                    @readableStreamDefaultControllerClose(teeState.branch2.@readableStreamController);
                 teeState.closedOrErrored = true;
             }
             if (teeState.closedOrErrored)
                 return;
             if (!teeState.canceled1)
-                @enqueueInReadableStream(teeState.branch1, shouldClone ? @doStructuredClone(result.value) : result.value);
+                @enqueueInReadableStream(teeState.branch1.@readableStreamController, shouldClone ? @doStructuredClone(result.value) : result.value);
             if (!teeState.canceled2)
-                @enqueueInReadableStream(teeState.branch2, shouldClone ? @doStructuredClone(result.value) : result.value);
+                @enqueueInReadableStream(teeState.branch2.@readableStreamController, shouldClone ? @doStructuredClone(result.value) : result.value);
         });
     }
 }
@@ -184,7 +234,10 @@
 {
     "use strict";
 
-    return @isObject(stream) && !!stream.@underlyingSource;
+    // Spec tells to return true only if stream has a readableStreamController internal slot.
+    // However, since it is a private slot, it cannot be checked using hasOwnProperty().
+    // Therefore, readableStreamController is initialized with null value.
+    return @isObject(stream) && stream.@readableStreamController !== @undefined;
 }
 
 function isReadableStreamDefaultReader(reader)
@@ -191,9 +244,10 @@
 {
     "use strict";
 
-    // To reset @ownerReadableStream it must be set to null instead of undefined because there is no way to distinguish
-    // between a non-existent slot and an slot set to undefined.
-    return @isObject(reader) && reader.@ownerReadableStream !== @undefined;
+    // Spec tells to return true only if reader has a readRequests internal slot.
+    // However, since it is a private slot, it cannot be checked using hasOwnProperty().
+    // Since readRequests is initialized with an empty array, the following test is ok.
+    return @isObject(reader) && !!reader.@readRequests;
 }
 
 function isReadableStreamDefaultController(controller)
@@ -200,7 +254,11 @@
 {
     "use strict";
 
-    return @isObject(controller) && !!controller.@controlledReadableStream;
+    // Spec tells to return true only if controller has an underlyingSource internal slot.
+    // However, since it is a private slot, it cannot be checked using hasOwnProperty().
+    // underlyingSource is obtained in ReadableStream constructor: if undefined, it is set
+    // to an empty object. Therefore, following test is ok.
+    return @isObject(controller) && !!controller.@underlyingSource;
 }
 
 function errorReadableStream(stream, error)
@@ -207,52 +265,59 @@
 {
     "use strict";
 
+    @assert(@isReadableStream(stream));
     @assert(stream.@state === @streamReadable);
-    stream.@queue = @newQueue();
+    stream.@state = @streamErrored;
     stream.@storedError = error;
-    stream.@state = @streamErrored;
 
     if (!stream.@reader)
         return;
+
     const reader = stream.@reader;
 
-    const requests = reader.@readRequests;
-    for (let index = 0, length = requests.length; index < length; ++index)
-        requests[index].@reject.@call(@undefined, error);
-    reader.@readRequests = [];
+    if (@isReadableStreamDefaultReader(reader)) {
+        const requests = reader.@readRequests;
+        for (let index = 0, length = requests.length; index < length; ++index)
+            requests[index].@reject.@call(@undefined, error);
+        reader.@readRequests = [];
+    } else
+        // FIXME: Implement ReadableStreamBYOBReader.
+        throw new @TypeError("Only ReadableStreamDefaultReader is currently supported");
 
     reader.@closedPromiseCapability.@reject.@call(@undefined, error);
 }
 
-function requestReadableStreamPull(stream)
+function requestReadableStreamPull(controller)
 {
     "use strict";
 
+    const stream = controller.@controlledReadableStream;
+
     if (stream.@state === @streamClosed || stream.@state === @streamErrored)
         return;
-    if (stream.@closeRequested)
+    if (controller.@closeRequested)
         return;
-    if (!stream.@started)
+    if (!controller.@started)
         return;
-    if ((!@isReadableStreamLocked(stream) || !stream.@reader.@readRequests.length) && @getReadableStreamDesiredSize(stream) <= 0)
+    if ((!@isReadableStreamLocked(stream) || !stream.@reader.@readRequests.length) && @readableStreamDefaultControllerGetDesiredSize(controller) <= 0)
         return;
 
-    if (stream.@pulling) {
-        stream.@pullAgain = true;
+    if (controller.@pulling) {
+        controller.@pullAgain = true;
         return;
     }
 
-    stream.@pulling = true;
+    controller.@pulling = true;
 
-    @promiseInvokeOrNoop(stream.@underlyingSource, "pull", [stream.@controller]).@then(function() {
-        stream.@pulling = false;
-        if (stream.@pullAgain) {
-            stream.@pullAgain = false;
-            @requestReadableStreamPull(stream);
+    @promiseInvokeOrNoop(controller.@underlyingSource, "pull", [controller]).@then(function() {
+        controller.@pulling = false;
+        if (controller.@pullAgain) {
+            controller.@pullAgain = false;
+            @requestReadableStreamPull(controller);
         }
     }, function(error) {
         if (stream.@state === @streamReadable)
-            @errorReadableStream(stream, error);
+            @readableStreamDefaultControllerError(controller, error);
     });
 }
 
@@ -264,11 +329,11 @@
     return !!stream.@reader;
 }
 
-function getReadableStreamDesiredSize(stream)
+function readableStreamDefaultControllerGetDesiredSize(controller)
 {
    "use strict";
 
-   return stream.@strategy.highWaterMark - stre...@queue.size;
+   return controller.@strategy.highWaterMark - controll...@queue.size;
 }
 
 function cancelReadableStream(stream, reason)
@@ -280,69 +345,78 @@
         return @Promise.@resolve();
     if (stream.@state === @streamErrored)
         return @Promise.@reject(stream.@storedError);
-    stream.@queue = @newQueue();
-    @finishClosingReadableStream(stream);
-    return @promiseInvokeOrNoop(stream.@underlyingSource, "cancel", [reason]).@then(function() { });
+    @closeReadableStream(stream);
+    // FIXME: Fix below, which is a temporary solution to the case where controller is undefined.
+    // This issue is due to the fact that in previous version of the spec, cancel was associated
+    // to underlyingSource, whereas in new version it is associated to controller. As this patch
+    // does not yet fully implement the new version, this solution is used.
+    const controller = stream.@readableStreamController;
+    var underlyingSource = @undefined;
+    if (controller !== @undefined)
+        underlyingSource = controller.@underlyingSource;
+    return @promiseInvokeOrNoop(underlyingSource, "cancel", [reason]).@then(function() { });
 }
 
-function finishClosingReadableStream(stream)
+
+function readableStreamDefaultControllerClose(controller)
 {
     "use strict";
 
+    const stream = controller.@controlledReadableStream;
+    @assert(!controller.@closeRequested);
     @assert(stream.@state === @streamReadable);
+    controller.@closeRequested = true;
+    if (controller.@queue.content.length === 0)
+        @closeReadableStream(stream);
+}
+
+function closeReadableStream(stream)
+{
+    "use strict";
+
+    @assert(stream.@state === @streamReadable);
     stream.@state = @streamClosed;
     const reader = stream.@reader;
+
     if (!reader)
         return;
 
-    const requests = reader.@readRequests;
-    for (let index = 0, length = requests.length; index < length; ++index)
-        requests[index].@resolve.@call(@undefined, {value:@undefined, done: true});
-    reader.@readRequests = [];
+    if (@isReadableStreamDefaultReader(reader)) {
+        const requests = reader.@readRequests;
+        for (let index = 0, length = requests.length; index < length; ++index)
+            requests[index].@resolve.@call(@undefined, {value:@undefined, done: true});
+        reader.@readRequests = [];
+    }
+
     reader.@closedPromiseCapability.@resolve.@call();
 }
 
-function closeReadableStream(stream)
+function enqueueInReadableStream(controller, chunk)
 {
     "use strict";
 
-    @assert(!stream.@closeRequested);
-    @assert(stream.@state !== @streamErrored);
-    if (stream.@state === @streamClosed)
-        return;
-    stream.@closeRequested = true;
-    if (!stream.@queue.content.length)
-        @finishClosingReadableStream(stream);
-}
+    const stream = controller.@controlledReadableStream;
+    @assert(!controller.@closeRequested);
+    @assert(stream.@state === @streamReadable);
 
-function enqueueInReadableStream(stream, chunk)
-{
-    "use strict";
-
-    @assert(!stream.@closeRequested);
-    @assert(stream.@state !== @streamErrored);
-    if (stream.@state === @streamClosed)
-        return;
     if (@isReadableStreamLocked(stream) && stream.@reader.@readRequests.length) {
         stream.@reader.@readRequests.@shift().@resolve.@call(@undefined, {value: chunk, done: false});
-        @requestReadableStreamPull(stream);
+        @requestReadableStreamPull(controller);
         return;
     }
+
     try {
-        let size = 1;
-        if (stre...@strategy.size) {
-            size = @Number(stre...@strategy.size(chunk));
-            if (!@isFinite(size) || size < 0)
-                throw new @RangeError("Chunk size is not valid");
-        }
-        @enqueueValueWithSize(stream.@queue, chunk, size);
+        let chunkSize = 1;
+        if (controll...@strategy.size !== @undefined)
+            chunkSize = controll...@strategy.size(chunk);
+        @enqueueValueWithSize(controller.@queue, chunk, chunkSize);
     }
     catch(error) {
         if (stream.@state === @streamReadable)
-            @errorReadableStream(stream, error);
+            @readableStreamDefaultControllerError(controller, error);
         throw error;
     }
-    @requestReadableStreamPull(stream);
+    @requestReadableStreamPull(controller);
 }
 
 function readFromReadableStreamDefaultReader(reader)
@@ -353,8 +427,8 @@
     @assert(!!stream);
 
     // Native sources may want to start enqueueing at the time of the first read request.
-    if (!stream.@disturbed && stream.@state === @streamReadable && stream.@underlyingSource.@firstReadCallback)
-        stream.@underlyingSource.@firstReadCallback();
+    if (!stream.@disturbed && stream.@state === @streamReadable && stream.@readableStreamController.@underlyingSource.@firstReadCallback)
+        stream.@readableStreamController.@underlyingSource.@firstReadCallback();
 
     stream.@disturbed = true;
     if (stream.@state === @streamClosed)
@@ -362,20 +436,23 @@
     if (stream.@state === @streamErrored)
         return @Promise.@reject(stream.@storedError);
     @assert(stream.@state === @streamReadable);
-    if (stream.@queue.content.length) {
-        const chunk = @dequeueValue(stream.@queue);
-        if (stream.@closeRequested && stream.@queue.content.length === 0)
-            @finishClosingReadableStream(stream);
-        else
-            @requestReadableStreamPull(stream);
-        return @Promise.@resolve({value: chunk, done: false});
-    }
-    const readPromiseCapability = @newPromiseCapability(@Promise);
-    reader.@readRequests.@push(readPromiseCapability);
-    @requestReadableStreamPull(stream);
-    return readPromiseCapability.@promise;
+
+    return stream.@readableStreamController.@pull();
 }
 
+function readableStreamAddReadRequest(stream)
+{
+    "use strict";
+
+    @assert(@isReadableStreamDefaultReader(stream.@reader));
+    @assert(stream.@state == @streamReadable);
+
+    const readRequest = @newPromiseCapability(@Promise);
+    stream.@reader.@readRequests.@push(readRequest);
+
+    return readRequest.@promise;
+}
+
 function isReadableStreamDisturbed(stream)
 {
     "use strict";

Modified: trunk/Source/WebCore/bindings/js/WebCoreBuiltinNames.h (205288 => 205289)


--- trunk/Source/WebCore/bindings/js/WebCoreBuiltinNames.h	2016-09-01 12:01:00 UTC (rev 205288)
+++ trunk/Source/WebCore/bindings/js/WebCoreBuiltinNames.h	2016-09-01 14:14:05 UTC (rev 205289)
@@ -61,6 +61,7 @@
     macro(operations) \
     macro(ownerReadableStream) \
     macro(privateGetStats) \
+    macro(pull) \
     macro(pulling) \
     macro(pullAgain) \
     macro(queue) \
@@ -71,6 +72,7 @@
     macro(queuedSetRemoteDescription) \
     macro(reader) \
     macro(readRequests) \
+    macro(readableStreamController) \
     macro(readyPromiseCapability) \
     macro(removeTrack) \
     macro(responseCacheIsValid) \
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to