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
- trunk/LayoutTests/imported/w3c/ChangeLog
- trunk/LayoutTests/imported/w3c/web-platform-tests/streams/readable-streams/general.https-expected.txt
- trunk/Source/WebCore/ChangeLog
- trunk/Source/WebCore/Modules/fetch/FetchResponse.js
- trunk/Source/WebCore/Modules/streams/ReadableStream.js
- trunk/Source/WebCore/Modules/streams/ReadableStreamDefaultController.js
- trunk/Source/WebCore/Modules/streams/ReadableStreamInternals.js
- trunk/Source/WebCore/bindings/js/WebCoreBuiltinNames.h
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