[Streams API] Add support for chunks with customized sizes
authoryouenn.fablet@crf.canon.fr <youenn.fablet@crf.canon.fr@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 28 Jun 2015 12:39:48 +0000 (12:39 +0000)
committeryouenn.fablet@crf.canon.fr <youenn.fablet@crf.canon.fr@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 28 Jun 2015 12:39:48 +0000 (12:39 +0000)
https://bugs.webkit.org/show_bug.cgi?id=146312

Reviewed by Darin Adler.

Source/WebCore:

Covered by rebased tests.

* bindings/js/ReadableJSStream.cpp:
(WebCore::ReadableJSStream::read): Decrement totalQueueSize with the chunk specific size.
(WebCore::ReadableJSStream::enqueue): Calls retrieveSize, enqueue chunk with its size and increment totalQueueSize.
(WebCore::ReadableJSStream::retrieveChunkSize): Calls size JS callback and convert it to double.
* bindings/js/ReadableJSStream.h:

LayoutTests:

* streams/reference-implementation/bad-strategies-expected.txt:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@186044 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/streams/reference-implementation/bad-strategies-expected.txt
Source/WebCore/ChangeLog
Source/WebCore/bindings/js/ReadableJSStream.cpp
Source/WebCore/bindings/js/ReadableJSStream.h

index 00c9687..642231c 100644 (file)
@@ -1,3 +1,12 @@
+2015-06-28  Xabier Rodriguez Calvar  <calvaris@igalia.com> and Youenn Fablet  <youenn.fablet@crf.canon.fr>
+
+        [Streams API] Add support for chunks with customized sizes
+        https://bugs.webkit.org/show_bug.cgi?id=146312
+
+        Reviewed by Darin Adler.
+
+        * streams/reference-implementation/bad-strategies-expected.txt:
+
 2015-06-27  David Kilzer  <ddkilzer@apple.com>
 
         fast/canvas/webgl/tex-*.html flakily timeout on Mavericks Debug WK1
 2015-06-27  David Kilzer  <ddkilzer@apple.com>
 
         fast/canvas/webgl/tex-*.html flakily timeout on Mavericks Debug WK1
index d2880a4..c86d384 100644 (file)
@@ -1,22 +1,10 @@
 
 PASS Readable stream: throwing strategy.size getter 
 
 PASS Readable stream: throwing strategy.size getter 
-FAIL Readable stream: throwing strategy.size method assert_throws: enqueue should throw the error function "function () { c.enqueue('a'); }" did not throw
+PASS Readable stream: throwing strategy.size method 
 PASS Readable stream: throwing strategy.highWaterMark getter 
 PASS Readable stream: invalid strategy.highWaterMark 
 PASS Readable stream: negative strategy.highWaterMark 
 PASS Readable stream: throwing strategy.highWaterMark getter 
 PASS Readable stream: invalid strategy.highWaterMark 
 PASS Readable stream: negative strategy.highWaterMark 
-FAIL Readable stream: strategy.size returning NaN assert_equals: enqueue should throw a RangeError expected function "function RangeError() {
-    [native code]
-}" but got function "function AssertionError(message)
-    {
-        this.messa..."
-FAIL Readable stream: strategy.size returning -Infinity assert_equals: enqueue should throw a RangeError expected function "function RangeError() {
-    [native code]
-}" but got function "function AssertionError(message)
-    {
-        this.messa..."
-FAIL Readable stream: strategy.size returning +Infinity assert_equals: enqueue should throw a RangeError expected function "function RangeError() {
-    [native code]
-}" but got function "function AssertionError(message)
-    {
-        this.messa..."
+PASS Readable stream: strategy.size returning NaN 
+PASS Readable stream: strategy.size returning -Infinity 
+PASS Readable stream: strategy.size returning +Infinity 
 
 
index dbfece1..7ae9924 100644 (file)
@@ -1,3 +1,18 @@
+2015-06-28  Xabier Rodriguez Calvar  <calvaris@igalia.com> and Youenn Fablet  <youenn.fablet@crf.canon.fr>
+
+        [Streams API] Add support for chunks with customized sizes
+        https://bugs.webkit.org/show_bug.cgi?id=146312
+
+        Reviewed by Darin Adler.
+
+        Covered by rebased tests.
+
+        * bindings/js/ReadableJSStream.cpp:
+        (WebCore::ReadableJSStream::read): Decrement totalQueueSize with the chunk specific size.
+        (WebCore::ReadableJSStream::enqueue): Calls retrieveSize, enqueue chunk with its size and increment totalQueueSize.
+        (WebCore::ReadableJSStream::retrieveChunkSize): Calls size JS callback and convert it to double.
+        * bindings/js/ReadableJSStream.h:
+
 2015-06-28  Youenn Fablet  <youenn.fablet@crf.canon.fr>
 
         [Streams API]Remove ReadableStreamController.close custom binding
 2015-06-28  Youenn Fablet  <youenn.fablet@crf.canon.fr>
 
         [Streams API]Remove ReadableStreamController.close custom binding
index 4f78db0..7281705 100644 (file)
@@ -323,27 +323,61 @@ JSValue ReadableJSStream::read()
 {
     ASSERT(hasValue());
 
 {
     ASSERT(hasValue());
 
-    return m_chunkQueue.takeFirst().get();
+    Chunk chunk = m_chunkQueue.takeFirst();
+    m_totalQueueSize -= chunk.size;
+
+    return chunk.value.get();
 }
 
 }
 
-void ReadableJSStream::enqueue(ExecState& exec)
+void ReadableJSStream::enqueue(ExecState& state)
 {
     ASSERT(!isCloseRequested());
 
     if (!isReadable())
         return;
 
 {
     ASSERT(!isCloseRequested());
 
     if (!isReadable())
         return;
 
-    JSValue chunk = exec.argumentCount() ? exec.argument(0) : jsUndefined();
+    JSValue chunk = state.argument(0);
     if (resolveReadCallback(chunk)) {
         pull();
         return;
     }
 
     if (resolveReadCallback(chunk)) {
         pull();
         return;
     }
 
-    m_chunkQueue.append(JSC::Strong<JSC::Unknown>(exec.vm(), chunk));
-    // FIXME: Compute chunk size.
+    double size = retrieveChunkSize(state, chunk);
+    if (state.hadException()) {
+        storeError(state, state.exception()->value());
+        return;
+    }
+
+    m_chunkQueue.append({ JSC::Strong<JSC::Unknown>(state.vm(), chunk), size });
+    m_totalQueueSize += size;
+
     pull();
 }
 
     pull();
 }
 
+double ReadableJSStream::retrieveChunkSize(ExecState& state, JSValue chunk)
+{
+    if (!m_sizeFunction)
+        return 1;
+
+    MarkedArgumentBuffer arguments;
+    arguments.append(chunk);
+
+    JSValue sizeValue = callFunction(state, m_sizeFunction.get(), jsUndefined(), arguments);
+    if (state.hadException())
+        return 0;
+
+    double size = sizeValue.toNumber(&state);
+    if (state.hadException())
+        return 0;
+
+    if (!std::isfinite(size)) {
+        throwVMError(&state, createRangeError(&state, ASCIILiteral("Incorrect double value")));
+        return 0;
+    }
+
+    return size;
+}
+
 } // namespace WebCore
 
 #endif
 } // namespace WebCore
 
 #endif
index 02e0a98..3dc166e 100644 (file)
@@ -64,7 +64,7 @@ public:
 
     void enqueue(JSC::ExecState&);
 
 
     void enqueue(JSC::ExecState&);
 
-    double desiredSize() const { return m_highWaterMark - m_chunkQueue.size(); }
+    double desiredSize() const { return m_highWaterMark - m_totalQueueSize; }
 
 private:
     ReadableJSStream(ScriptExecutionContext&, JSC::ExecState&, JSC::JSObject*, double, JSC::JSFunction*);
 
 private:
     ReadableJSStream(ScriptExecutionContext&, JSC::ExecState&, JSC::JSObject*, double, JSC::JSFunction*);
@@ -82,12 +82,21 @@ private:
 
     JSDOMGlobalObject* globalObject();
 
 
     JSDOMGlobalObject* globalObject();
 
+    double retrieveChunkSize(JSC::ExecState&, JSC::JSValue);
+
     std::unique_ptr<ReadableStreamController> m_controller;
     // FIXME: we should consider not using JSC::Strong, see https://bugs.webkit.org/show_bug.cgi?id=146278
     JSC::Strong<JSC::Unknown> m_error;
     JSC::Strong<JSC::JSFunction> m_errorFunction;
     JSC::Strong<JSC::JSObject> m_source;
     std::unique_ptr<ReadableStreamController> m_controller;
     // FIXME: we should consider not using JSC::Strong, see https://bugs.webkit.org/show_bug.cgi?id=146278
     JSC::Strong<JSC::Unknown> m_error;
     JSC::Strong<JSC::JSFunction> m_errorFunction;
     JSC::Strong<JSC::JSObject> m_source;
-    Deque<JSC::Strong<JSC::Unknown>> m_chunkQueue;
+
+    struct Chunk {
+        JSC::Strong<JSC::Unknown> value;
+        double size;
+    };
+    Deque<Chunk> m_chunkQueue;
+
+    double m_totalQueueSize { 0 };
     double m_highWaterMark;
     JSC::Strong<JSC::JSFunction> m_sizeFunction;
 };
     double m_highWaterMark;
     JSC::Strong<JSC::JSFunction> m_sizeFunction;
 };