[Readable Streams API] Implement generic reader functions
https://bugs.webkit.org/show_bug.cgi?id=163003

Patch by Romain Bellessort <romain.bellessort@crf.canon.fr> on 2016-10-07
Reviewed by Darin Adler.

Implements reader generic functions defined by spec in order to prepare BYOBReader integration.
Generic functions factorize some code that is used by both DefaultReader and BYOBReader.

No change in behaviour.

* Modules/streams/ReadableStreamDefaultReader.js:
(cancel): Rely on readableStreamReaderGenericCancel.
(releaseLock): Rely on readableStreamReaderGenericRelease.
* Modules/streams/ReadableStreamInternals.js:
(privateInitializeReadableStreamDefaultReader): Rely on readableStreamReaderGenericInitialize.
(readableStreamReaderGenericInitialize): Added.
(readableStreamReaderGenericCancel): Added.
(readableStreamReaderGenericRelease): Added.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@206912 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/Modules/streams/ReadableStreamInternals.js b/Source/WebCore/Modules/streams/ReadableStreamInternals.js
index 61fdcba..29c3dd4 100644
--- a/Source/WebCore/Modules/streams/ReadableStreamInternals.js
+++ b/Source/WebCore/Modules/streams/ReadableStreamInternals.js
@@ -36,23 +36,28 @@
     if (@isReadableStreamLocked(stream))
        @throwTypeError("ReadableStream is locked");
 
+    @readableStreamReaderGenericInitialize(this, stream);
     this.@readRequests = [];
-    this.@ownerReadableStream = stream;
-    stream.@reader = this;
-    if (stream.@state === @streamReadable) {
-        this.@closedPromiseCapability = @newPromiseCapability(@Promise);
-        return this;
-    }
-    if (stream.@state === @streamClosed) {
-        this.@closedPromiseCapability = { @promise: @Promise.@resolve() };
-        return this;
-    }
-    @assert(stream.@state === @streamErrored);
-    this.@closedPromiseCapability = { @promise: @Promise.@reject(stream.@storedError) };
 
     return this;
 }
 
+function readableStreamReaderGenericInitialize(reader, stream)
+{
+    "use strict";
+
+    reader.@ownerReadableStream = stream;
+    stream.@reader = reader;
+    if (stream.@state === @streamReadable)
+        reader.@closedPromiseCapability = @newPromiseCapability(@Promise);
+    else if (stream.@state === @streamClosed)
+        reader.@closedPromiseCapability = { @promise: @Promise.@resolve() };
+    else {
+        @assert(stream.@state === @streamErrored);
+        reader.@closedPromiseCapability = { @promise: @Promise.@reject(stream.@storedError) };
+    }
+}
+
 function privateInitializeReadableStreamDefaultController(stream, underlyingSource, size, highWaterMark)
 {
     "use strict";
@@ -323,6 +328,16 @@
    return controller.@strategy.highWaterMark - controller.@queue.size;
 }
 
+
+function readableStreamReaderGenericCancel(reader, reason)
+{
+    "use strict";
+
+    const stream = reader.@ownerReadableStream;
+    @assert(!!stream);
+    return @readableStreamCancel(stream, reason);
+}
+
 function readableStreamCancel(stream, reason)
 {
     "use strict";
@@ -460,3 +475,19 @@
     @assert(@isReadableStream(stream));
     return stream.@disturbed;
 }
+
+function readableStreamReaderGenericRelease(reader)
+{
+    "use strict";
+
+    @assert(!!reader.@ownerReadableStream);
+    @assert(reader.@ownerReadableStream.@reader === reader);
+
+    if (reader.@ownerReadableStream.@state === @streamReadable)
+        reader.@closedPromiseCapability.@reject.@call(@undefined, new @TypeError("releasing lock of reader whose stream is still in readable state"));
+    else
+        reader.@closedPromiseCapability = { @promise: @Promise.@reject(new @TypeError("reader released lock")) };
+
+    reader.@ownerReadableStream.@reader = @undefined;
+    reader.@ownerReadableStream = null;
+}