Changeset 185406 in webkit


Ignore:
Timestamp:
Jun 10, 2015 1:09:02 AM (9 years ago)
Author:
youenn.fablet@crf.canon.fr
Message:

[Streams API] Implement pulling of a source by a ReadableStream
https://bugs.webkit.org/show_bug.cgi?id=145262

Reviewed by Darin Adler

Source/WebCore:

Introduced abstract ReadableStream::doPull() which is overriden in ReadableJSStream.
Added support to call the "pull" JS callback in ReadableJSStream::doPull().
Added calls to pull as requested by the spec (when resolving a read callback, at start time...).

Fixed issue in ReadableStreamReader::read() (use of successCallback(JSValue()) in lieu of endCallback())

Covered by rebased tests.

  • Modules/streams/ReadableStream.cpp:

(WebCore::ReadableStream::start): calling pull() once start.
(WebCore::ReadableStream::pull): calling doPull() if readableStream states requires to.
(WebCore::ReadableStream::read): calling pull() after resolving a read callback.

  • Modules/streams/ReadableStream.h:
  • Modules/streams/ReadableStreamReader.cpp:

(WebCore::ReadableStreamReader::read): fixed JSValue() bug.

  • bindings/js/ReadableJSStream.cpp:

(WebCore::ReadableJSStream::doPull): calling of JS callback.
(WebCore::ReadableJSStream::storeException): catches exception and store them.
(WebCore::ReadableJSStream::storeError): refactoring for checkForException.
(WebCore::ReadableJSStream::enqueue):

  • bindings/js/ReadableJSStream.h:

LayoutTests:

Rebased expectations, removed some "timeout: 50" parameters.
Removed a test from streams/reference-implementation/readable-stream.html that cannot pass
until promises returned to start and pull JS callbacks are handled.
Fixed bug in streams-utils.js (was using the old API replaced by controller).

  • streams/reference-implementation/bad-underlying-sources-expected.txt:
  • streams/reference-implementation/bad-underlying-sources.html:
  • streams/reference-implementation/readable-stream-expected.txt:
  • streams/reference-implementation/readable-stream.html:
  • streams/reference-implementation/resources/streams-utils.js:

(.stream.new.ReadableStream.):
(.stream.new.ReadableStream):
(sequentialReadableStream):

Location:
trunk
Files:
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r185402 r185406  
     12015-06-10  Xabier Rodriguez Calvar  <calvaris@igalia.com> and Youenn Fablet <youenn.fablet@crf.canon.fr>
     2
     3        [Streams API] Implement pulling of a source by a ReadableStream
     4        https://bugs.webkit.org/show_bug.cgi?id=145262
     5
     6        Reviewed by Darin Adler
     7
     8        Rebased expectations, removed some "timeout: 50" parameters.
     9        Removed a test from streams/reference-implementation/readable-stream.html that cannot pass
     10        until promises returned to start and pull JS callbacks are handled.
     11        Fixed bug in streams-utils.js (was using the old API replaced by controller).
     12
     13        * streams/reference-implementation/bad-underlying-sources-expected.txt:
     14        * streams/reference-implementation/bad-underlying-sources.html:
     15        * streams/reference-implementation/readable-stream-expected.txt:
     16        * streams/reference-implementation/readable-stream.html:
     17        * streams/reference-implementation/resources/streams-utils.js:
     18        (.stream.new.ReadableStream.):
     19        (.stream.new.ReadableStream):
     20        (sequentialReadableStream):
     21
    1222015-06-09  Daegyu Lee  <daegyu.lee@navercorp.com>
    223
  • trunk/LayoutTests/streams/reference-implementation/bad-underlying-sources-expected.txt

    r185356 r185406  
    22PASS Underlying source start: throwing getter
    33PASS Underlying source start: throwing method
    4 TIMEOUT Underlying source: throwing pull getter (initial pull) Test timed out
    5 TIMEOUT Underlying source: throwing pull method (initial pull) Test timed out
    6 TIMEOUT Underlying source: throwing pull getter (second pull) Test timed out
    7 TIMEOUT Underlying source: throwing pull method (second pull) Test timed out
     4PASS Underlying source: throwing pull getter (initial pull)
     5PASS Underlying source: throwing pull method (initial pull)
     6PASS Underlying source: throwing pull getter (second pull)
     7PASS Underlying source: throwing pull method (second pull)
    88FAIL Underlying source: throwing cancel getter cancel is not implemented
    99FAIL Underlying source: throwing cancel method cancel is not implemented
  • trunk/LayoutTests/streams/reference-implementation/bad-underlying-sources.html

    r185114 r185406  
    2828}, 'Underlying source start: throwing method');
    2929
    30 var test1 = async_test('Underlying source: throwing pull getter (initial pull)', { timeout: 50 });
     30var test1 = async_test('Underlying source: throwing pull getter (initial pull)');
    3131test1.step(function() {
    3232    var theError = new Error('a unique string');
     
    4545});
    4646
    47 var test2 = async_test('Underlying source: throwing pull method (initial pull)', { timeout: 50 });
     47var test2 = async_test('Underlying source: throwing pull method (initial pull)');
    4848test2.step(function() {
    4949    var theError = new Error('a unique string');
     
    6262});
    6363
    64 var test3 = async_test('Underlying source: throwing pull getter (second pull)', { timeout: 50 });
     64var test3 = async_test('Underlying source: throwing pull getter (second pull)');
    6565test3.step(function() {
    6666    var theError = new Error('a unique string');
     
    9090});
    9191
    92 var test4 = async_test('Underlying source: throwing pull method (second pull)', { timeout: 50 });
     92var test4 = async_test('Underlying source: throwing pull method (second pull)');
    9393test4.step(function() {
    9494    var theError = new Error('a unique string');
  • trunk/LayoutTests/streams/reference-implementation/readable-stream-expected.txt

    r185356 r185406  
    1111PASS ReadableStream: if start throws an error, it should be re-thrown
    1212TIMEOUT ReadableStream: if pull rejects, it should error the stream Test timed out
    13 FAIL ReadableStream: should not call pull until the previous pull call's promise fulfills assert_equals: pull should have been called once after start, but not yet have been called a second time expected 1 but got 0
     13FAIL ReadableStream: should not call pull until the previous pull call's promise fulfills assert_equals: after the promise returned by pull is fulfilled, pull should be called a second time expected 2 but got 1
    1414PASS ReadableStream: should not call pull after start if the stream is now closed
    15 FAIL ReadableStream: should call pull after enqueueing from inside pull (with no read requests), if strategy allows assert_equals: pull() should have been called four times expected 4 but got 0
    16 TIMEOUT ReadableStream pull should be able to close a stream. Test timed out
     15FAIL ReadableStream: should call pull after enqueueing from inside pull (with no read requests), if strategy allows assert_equals: pull() should have been called four times expected 4 but got 1
     16PASS ReadableStream pull should be able to close a stream.
    1717FAIL ReadableStream: enqueue should throw when the stream is readable but draining assert_equals: the first enqueue should return true expected (boolean) true but got (undefined) undefined
    1818PASS ReadableStream: enqueue should throw when the stream is closed
     
    2222FAIL ReadableStream strategies: the default strategy should continue returning true from enqueue if the chunks are read immediately assert_equals: first enqueue should return true expected (boolean) true but got (undefined) undefined
    2323TIMEOUT ReadableStream integration test: adapting a random push source Test timed out
    24 TIMEOUT ReadableStream integration test: adapting a sync pull source Test timed out
    25 TIMEOUT ReadableStream integration test: adapting an async pull source Test timed out
     24PASS ReadableStream integration test: adapting a sync pull source
    2625
  • trunk/LayoutTests/streams/reference-implementation/readable-stream.html

    r185197 r185406  
    517517});
    518518
    519 var test15 = async_test('ReadableStream pull should be able to close a stream.', { timeout: 50 });
     519var test15 = async_test('ReadableStream pull should be able to close a stream.');
    520520test15.step(function() {
    521521    var pullCalled = false;
     
    703703});
    704704
    705 var test19 = async_test('ReadableStream integration test: adapting a sync pull source', { timeout: 50 });
     705var test19 = async_test('ReadableStream integration test: adapting a sync pull source');
    706706test19.step(function() {
    707707    var rs = sequentialReadableStream(10);
     
    714714    }));
    715715});
    716 
     716/*
    717717var test20 = async_test('ReadableStream integration test: adapting an async pull source', { timeout: 50 });
    718718test20.step(function() {
     
    726726    }));
    727727});
     728*/
    728729</script>
  • trunk/LayoutTests/streams/reference-implementation/resources/streams-utils.js

    r182629 r185406  
    151151                    if (err) {
    152152                        reject(err);
     153                        return;
    153154                    }
    154155                    resolve();
     
    157158        },
    158159
    159         pull: function(enqueue, finish, error) {
     160        pull: function(c) {
    160161            sequentialSource.read(function(err, done, chunk) {
    161162                if (err) {
    162                     error(err);
     163                    c.error(err);
    163164                } else if (done) {
    164165                    sequentialSource.close(function(err) {
    165166                        if (err) {
    166                             error(err);
     167                            c.error(err);
     168                            return;
    167169                        }
    168                         finish();
     170                        c.close();
    169171                    });
    170172                } else {
    171                     enqueue(chunk);
     173                    c.enqueue(chunk);
    172174                }
    173175            });
  • trunk/Source/WebCore/ChangeLog

    r185404 r185406  
     12015-06-10  Xabier Rodriguez Calvar  <calvaris@igalia.com> and Youenn Fablet <youenn.fablet@crf.canon.fr>
     2
     3        [Streams API] Implement pulling of a source by a ReadableStream
     4        https://bugs.webkit.org/show_bug.cgi?id=145262
     5
     6        Reviewed by Darin Adler
     7
     8        Introduced abstract ReadableStream::doPull() which is overriden in ReadableJSStream.
     9        Added support to call the "pull" JS callback in ReadableJSStream::doPull().
     10        Added calls to pull as requested by the spec (when resolving a read callback, at start time...).
     11
     12        Fixed issue in ReadableStreamReader::read() (use of successCallback(JSValue()) in lieu of endCallback())
     13
     14        Covered by rebased tests.
     15
     16        * Modules/streams/ReadableStream.cpp:
     17        (WebCore::ReadableStream::start): calling pull() once start.
     18        (WebCore::ReadableStream::pull): calling doPull() if readableStream states requires to.
     19        (WebCore::ReadableStream::read): calling pull() after resolving a read callback.
     20        * Modules/streams/ReadableStream.h:
     21        * Modules/streams/ReadableStreamReader.cpp:
     22        (WebCore::ReadableStreamReader::read): fixed JSValue() bug.
     23        * bindings/js/ReadableJSStream.cpp:
     24        (WebCore::ReadableJSStream::doPull): calling of JS callback.
     25        (WebCore::ReadableJSStream::storeException): catches exception and store them.
     26        (WebCore::ReadableJSStream::storeError): refactoring for checkForException.
     27        (WebCore::ReadableJSStream::enqueue):
     28        * bindings/js/ReadableJSStream.h:
     29
    1302015-06-09  Youenn Fablet  <youenn.fablet@crf.canon.fr>
    231
  • trunk/Source/WebCore/Modules/streams/ReadableStream.cpp

    r185260 r185406  
    113113}
    114114
     115void ReadableStream::start()
     116{
     117    m_isStarted = true;
     118    pull();
     119}
     120
     121void ReadableStream::pull()
     122{
     123    if (!m_isStarted || m_state == State::Closed || m_state == State::Errored || m_closeRequested)
     124        return;
     125    // FIXME: Implement queueSize check.
     126    if (m_readRequests.isEmpty() && hasValue())
     127        return;
     128    // FIXME: Implement async pull check.
     129    doPull();
     130}
     131
    115132ReadableStreamReader& ReadableStream::getReader()
    116133{
     
    155172    if (hasValue()) {
    156173        successCallback(read());
    157         if (m_closeRequested && !hasValue())
     174        if (!m_closeRequested)
     175            pull();
     176        else if (!hasValue())
    158177            close();
    159178        return;
    160179    }
    161180    m_readRequests.append({ WTF::move(successCallback), WTF::move(endCallback), WTF::move(failureCallback) });
    162     // FIXME: We should try to pull.
     181    pull();
    163182}
    164183
     
    172191}
    173192
    174 void ReadableStream::start()
    175 {
    176     notImplemented();
    177 }
    178 
    179193const char* ReadableStream::activeDOMObjectName() const
    180194{
  • trunk/Source/WebCore/Modules/streams/ReadableStream.h

    r185260 r185406  
    9090
    9191    bool resolveReadCallback(JSC::JSValue);
     92    void pull();
    9293
    9394private:
     
    101102    virtual bool hasValue() const = 0;
    102103    virtual JSC::JSValue read() = 0;
     104    virtual void doPull() = 0;
    103105
    104106    std::unique_ptr<ReadableStreamReader> m_reader;
     
    115117    Deque<ReadCallbacks> m_readRequests;
    116118
     119    bool m_isStarted { false };
    117120    bool m_closeRequested { false };
    118121    State m_state { State::Readable };
  • trunk/Source/WebCore/Modules/streams/ReadableStreamReader.cpp

    r185114 r185406  
    4949{
    5050    if (m_stream.isReadable() && m_stream.reader() != this) {
    51         successCallback(JSC::JSValue());
     51        endCallback();
    5252        return;
    5353    }
  • trunk/Source/WebCore/bindings/js/ReadableJSStream.cpp

    r185356 r185406  
    4040#include "ScriptExecutionContext.h"
    4141#include <runtime/Error.h>
     42#include <runtime/Exception.h>
    4243#include <runtime/JSCJSValueInlines.h>
    4344#include <runtime/JSString.h>
     
    101102    // FIXME: Implement handling promise as result of calling start function.
    102103    startReadableStreamAsync(*this);
     104}
     105
     106void ReadableJSStream::doPull()
     107{
     108    ExecState& state = *globalObject()->globalExec();
     109    JSLockHolder lock(&state);
     110
     111    invoke(state, "pull");
     112
     113    if (state.hadException()) {
     114        storeException(state);
     115        ASSERT(!state.hadException());
     116        return;
     117    }
     118    // FIXME: Implement handling promise as result of calling pull function.
    103119}
    104120
     
    137153}
    138154
     155void ReadableJSStream::storeException(JSC::ExecState& state)
     156{
     157    JSValue exception = state.exception()->value();
     158    state.clearException();
     159    storeError(state, exception);
     160}
     161
    139162void ReadableJSStream::storeError(JSC::ExecState& exec)
    140163{
     164    storeError(exec, exec.argumentCount() ? exec.argument(0) : createError(&exec, ASCIILiteral("Error function called.")));
     165}
     166
     167void ReadableJSStream::storeError(JSC::ExecState& exec, JSValue error)
     168{
    141169    if (m_error)
    142170        return;
    143     JSValue error = exec.argumentCount() ? exec.argument(0) : createError(&exec, ASCIILiteral("Error function called."));
    144171    m_error.set(exec.vm(), error);
    145172
     
    167194
    168195    JSValue chunk = exec.argumentCount() ? exec.argument(0) : jsUndefined();
    169     if (resolveReadCallback(chunk))
    170         return;
     196    if (resolveReadCallback(chunk)) {
     197        pull();
     198        return;
     199    }
    171200
    172201    m_chunkQueue.append(JSC::Strong<JSC::Unknown>(exec.vm(), chunk));
    173202    // FIXME: Compute chunk size.
    174     // FIXME: Add pulling of data here and also when data is passed to resolve callback.
     203    pull();
    175204}
    176205
  • trunk/Source/WebCore/bindings/js/ReadableJSStream.h

    r185356 r185406  
    6363
    6464    JSC::JSValue invoke(JSC::ExecState&, const char*);
     65    void storeException(JSC::ExecState&);
     66    void storeError(JSC::ExecState&, JSC::JSValue);
    6567
    6668    virtual bool hasValue() const override;
    6769    virtual JSC::JSValue read() override;
     70    virtual void doPull() override;
    6871
    6972    JSDOMGlobalObject* globalObject();
Note: See TracChangeset for help on using the changeset viewer.