Changeset 185872 in webkit


Ignore:
Timestamp:
Jun 23, 2015 4:29:32 AM (9 years ago)
Author:
youenn.fablet@crf.canon.fr
Message:

[Streams API] Implement ReadableStream js source "'cancel" callback
https://bugs.webkit.org/show_bug.cgi?id=146204

Reviewed by Darin Adler.

Source/WebCore:

Calling "cancel" JS function when web app is cancelling a JS readable stream.
Handling of promise returned value in case of async cancel.

Covered by rebased tests.

  • bindings/js/ReadableJSStream.cpp:

(WebCore::ReadableJSStream::invoke): Refactoring to pass cancel reason or controller to the JS function.
(WebCore::ReadableJSStream::doStart): Ditto.
(WebCore::startReadableStreamAsync): Renaming readableStream as protectedStream.
(WebCore::createPullResultFulfilledFunction): Ditto.
(WebCore::ReadableJSStream::doPull): Refactoring to pass cancel reason or controller to the JS function.
(WebCore::createCancelResultFulfilledFunction): Cancel promise fullfil callback.
(WebCore::createCancelResultRejectedFunction): Cancel promise reject callback.
(WebCore::ReadableJSStream::doCancel): Calling cancel JS callback and handling promise returned value.

  • bindings/js/ReadableJSStream.h: Refactoring to pass cancel reason or controller to the JS function.

LayoutTests:

  • streams/reference-implementation/bad-underlying-sources-expected.txt:
  • streams/reference-implementation/readable-stream-cancel-expected.txt:
  • streams/reference-implementation/readable-stream-expected.txt:
  • streams/reference-implementation/readable-stream-reader-expected.txt:
Location:
trunk
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r185870 r185872  
     12015-06-23  Xabier Rodriguez Calvar  <calvaris@igalia.com> and Youenn Fablet  <youenn.fablet@crf.canon.fr>
     2
     3        [Streams API] Implement ReadableStream js source "'cancel" callback
     4        https://bugs.webkit.org/show_bug.cgi?id=146204
     5
     6        Reviewed by Darin Adler.
     7
     8        * streams/reference-implementation/bad-underlying-sources-expected.txt:
     9        * streams/reference-implementation/readable-stream-cancel-expected.txt:
     10        * streams/reference-implementation/readable-stream-expected.txt:
     11        * streams/reference-implementation/readable-stream-reader-expected.txt:
     12
    1132015-06-23  Gyuyoung Kim  <gyuyoung.kim@webkit.org>
    214
  • trunk/LayoutTests/streams/reference-implementation/bad-underlying-sources-expected.txt

    r185826 r185872  
    66PASS Underlying source: throwing pull getter (second pull)
    77PASS Underlying source: throwing pull method (second pull)
    8 FAIL Underlying source: throwing cancel getter assert_unreached: cancel should not fulfill Reached unreachable code
    9 FAIL Underlying source: throwing cancel method assert_unreached: cancel should not fulfill Reached unreachable code
     8PASS Underlying source: throwing cancel getter
     9PASS Underlying source: throwing cancel method
    1010PASS Underlying source: calling enqueue on an empty canceled stream should not throw
    1111PASS Underlying source: calling enqueue on a non-empty canceled stream should not throw
  • trunk/LayoutTests/streams/reference-implementation/readable-stream-cancel-expected.txt

    r185826 r185872  
    11
    2 FAIL ReadableStream cancellation: integration test on an infinite stream derived from a random push source assert_equals: it returns a promise that is fulfilled when the cancellation finishes expected true but got false
    3 FAIL ReadableStream cancellation: cancel(reason) should pass through the given reason to the underlying source assert_equals: the error passed to the underlying source's cancel method should equal the one passed to the stream's cancel expected (object) object "Error: Sorry, it just wasn't meant to be." but got (undefined) undefined
     2PASS ReadableStream cancellation: integration test on an infinite stream derived from a random push source
     3PASS ReadableStream cancellation: cancel(reason) should pass through the given reason to the underlying source
    44PASS ReadableStream cancellation: cancel() on a locked stream should fail and not call the underlying source cancel
    5 FAIL ReadableStream cancellation: should fulfill promise when cancel callback went fine assert_true: expected true got false
     5PASS ReadableStream cancellation: should fulfill promise when cancel callback went fine
    66PASS ReadableStream cancellation: returning a value from the underlying source's cancel should not affect the fulfillment value of the promise returned by the stream's cancel
    7 FAIL ReadableStream cancellation: should reject promise when cancel callback raises an exception assert_unreached: cancel should reject Reached unreachable code
     7PASS ReadableStream cancellation: should reject promise when cancel callback raises an exception
    88PASS ReadableStream cancellation: if the underlying source's cancel method returns a promise, the promise returned by the stream's cancel should fulfill when that one does (1)
    9 FAIL ReadableStream cancellation: if the underlying source's cancel method returns a promise, the promise returned by the stream's cancel should fulfill when that one does (2) assert_true: cancel() return value should be fulfilled only after the promise returned by the underlying source's cancel expected true got false
    10 FAIL ReadableStream cancellation: if the underlying source's cancel method returns a promise, the promise returned by the stream's cancel should reject when that one does assert_unreached: cancel() return value should not be rejected Reached unreachable code
     9PASS ReadableStream cancellation: if the underlying source's cancel method returns a promise, the promise returned by the stream's cancel should fulfill when that one does (2)
     10PASS ReadableStream cancellation: if the underlying source's cancel method returns a promise, the promise returned by the stream's cancel should reject when that one does
    1111PASS ReadableStream cancellation: cancelling before start finishes should prevent pull() from being called
    1212
  • trunk/LayoutTests/streams/reference-implementation/readable-stream-expected.txt

    r185826 r185872  
    2626PASS ReadableStream: enqueue should throw when the stream is closed
    2727PASS ReadableStream: enqueue should throw the stored error when the stream is errored
    28 FAIL ReadableStream: should call underlying source methods as methods assert_equals: expected 1 but got 0
     28PASS ReadableStream: should call underlying source methods as methods
    2929FAIL ReadableStream strategies: the default strategy should give desiredSize of 1 to start, decreasing by 1 per enqueue assert_equals: expected (number) 1 but got (undefined) undefined
    3030FAIL ReadableStream strategies: the default strategy should continue giving desiredSize of 1 if the chunks are read immediately assert_equals: desiredSize should start at 1 expected (number) 1 but got (undefined) undefined
  • trunk/LayoutTests/streams/reference-implementation/readable-stream-reader-expected.txt

    r185826 r185872  
    1111PASS Constructing a ReadableStreamReader directly should be OK if the stream is errored
    1212PASS Reading from a reader for an empty stream will wait until a chunk is available
    13 FAIL cancel() on a reader releases the reader before calling through assert_true: expected true got false
     13PASS cancel() on a reader releases the reader before calling through
    1414PASS closed should be fulfilled after stream is closed (.closed access before acquiring)
    1515PASS closed should be fulfilled after reader releases its lock (multiple stream locks)
  • trunk/Source/WebCore/ChangeLog

    r185862 r185872  
     12015-06-23  Xabier Rodriguez Calvar  <calvaris@igalia.com> and Youenn Fablet  <youenn.fablet@crf.canon.fr>
     2
     3        [Streams API] Implement ReadableStream js source "'cancel" callback
     4        https://bugs.webkit.org/show_bug.cgi?id=146204
     5
     6        Reviewed by Darin Adler.
     7
     8        Calling "cancel" JS function when web app is cancelling a JS readable stream.
     9        Handling of promise returned value in case of async cancel.
     10
     11        Covered by rebased tests.
     12
     13        * bindings/js/ReadableJSStream.cpp:
     14        (WebCore::ReadableJSStream::invoke): Refactoring to pass cancel reason or controller to the JS function.
     15        (WebCore::ReadableJSStream::doStart): Ditto.
     16        (WebCore::startReadableStreamAsync): Renaming readableStream as protectedStream.
     17        (WebCore::createPullResultFulfilledFunction): Ditto.
     18        (WebCore::ReadableJSStream::doPull): Refactoring to pass cancel reason or controller to the JS function.
     19        (WebCore::createCancelResultFulfilledFunction): Cancel promise fullfil callback.
     20        (WebCore::createCancelResultRejectedFunction): Cancel promise reject callback.
     21        (WebCore::ReadableJSStream::doCancel): Calling cancel JS callback and handling promise returned value.
     22        * bindings/js/ReadableJSStream.h: Refactoring to pass cancel reason or controller to the JS function.
     23
    1242015-06-22  Ryuan Choi  <ryuan.choi@navercorp.com>
    225
  • trunk/Source/WebCore/bindings/js/ReadableJSStream.cpp

    r185826 r185872  
    6161}
    6262
    63 JSPromise* ReadableJSStream::invoke(ExecState& state, const char* propertyName)
     63JSPromise* ReadableJSStream::invoke(ExecState& state, const char* propertyName, JSValue parameter)
    6464{
    6565    JSValue function = getPropertyFromObject(state, m_source.get(), propertyName);
     
    7474
    7575    MarkedArgumentBuffer arguments;
    76     arguments.append(jsController(state, globalObject()));
     76    arguments.append(parameter);
    7777
    7878    JSPromise* promise = jsDynamicCast<JSPromise*>(callFunction(state, function, m_source.get(), arguments));
     
    109109}
    110110
    111 static inline void startReadableStreamAsync(ReadableStream& readableStream)
    112 {
    113     RefPtr<ReadableStream> stream = &readableStream;
    114     stream->scriptExecutionContext()->postTask([stream](ScriptExecutionContext&) {
    115         stream->start();
     111static inline void startReadableStreamAsync(ReadableStream& stream)
     112{
     113    RefPtr<ReadableStream> protectedStream = &stream;
     114    stream.scriptExecutionContext()->postTask([protectedStream](ScriptExecutionContext&) {
     115        protectedStream->start();
    116116    });
    117117}
     
    121121    JSLockHolder lock(&exec);
    122122
    123     JSPromise* promise = invoke(exec, "start");
     123    JSPromise* promise = invoke(exec, "start", jsController(exec, globalObject()));
    124124
    125125    if (exec.hadException())
     
    136136static inline JSFunction* createPullResultFulfilledFunction(ExecState& exec, ReadableJSStream& stream)
    137137{
    138     RefPtr<ReadableJSStream> readableStream = &stream;
    139     return JSFunction::create(exec.vm(), exec.callee()->globalObject(), 0, String(), [readableStream](ExecState*) {
    140         readableStream->finishPulling();
     138    RefPtr<ReadableJSStream> protectedStream = &stream;
     139    return JSFunction::create(exec.vm(), exec.callee()->globalObject(), 0, String(), [protectedStream](ExecState*) {
     140        protectedStream->finishPulling();
    141141        return JSValue::encode(jsUndefined());
    142142    });
     
    148148    JSLockHolder lock(&state);
    149149
    150     JSPromise* promise = invoke(state, "pull");
     150    JSPromise* promise = invoke(state, "pull", jsController(state, globalObject()));
    151151
    152152    if (promise)
     
    159159    }
    160160
     161    return !promise;
     162}
     163
     164static JSFunction* createCancelResultFulfilledFunction(ExecState& exec, ReadableJSStream& stream)
     165{
     166    RefPtr<ReadableJSStream> protectedStream = &stream;
     167    return JSFunction::create(exec.vm(), exec.callee()->globalObject(), 1, String(), [protectedStream](ExecState*) {
     168        protectedStream->notifyCancelSucceeded();
     169        return JSValue::encode(jsUndefined());
     170    });
     171}
     172
     173static JSFunction* createCancelResultRejectedFunction(ExecState& exec, ReadableJSStream& stream)
     174{
     175    RefPtr<ReadableJSStream> protectedStream = &stream;
     176    return JSFunction::create(exec.vm(), exec.callee()->globalObject(), 1, String(), [protectedStream](ExecState* exec) {
     177        protectedStream->storeError(*exec, exec->argument(0));
     178        protectedStream->notifyCancelFailed();
     179        return JSValue::encode(jsUndefined());
     180    });
     181}
     182
     183bool ReadableJSStream::doCancel(JSValue reason)
     184{
     185    ExecState& exec = *globalObject()->globalExec();
     186    JSLockHolder lock(&exec);
     187
     188    JSPromise* promise = invoke(exec, "cancel", reason);
     189
     190    if (promise)
     191        thenPromise(exec, promise, createCancelResultFulfilledFunction(exec, *this), createCancelResultRejectedFunction(exec, *this));
     192
     193    if (exec.hadException()) {
     194        storeException(exec);
     195        ASSERT(!exec.hadException());
     196        return true;
     197    }
    161198    return !promise;
    162199}
     
    183220}
    184221
    185 bool ReadableJSStream::doCancel(JSValue)
    186 {
    187     // FIXME: Implement it.
    188     return true;
    189 }
    190 
    191222ReadableJSStream::ReadableJSStream(ScriptExecutionContext& scriptExecutionContext, ExecState& state, JSObject* source)
    192223    : ReadableStream(scriptExecutionContext)
  • trunk/Source/WebCore/bindings/js/ReadableJSStream.h

    r185826 r185872  
    6767    void doStart(JSC::ExecState&);
    6868
    69     JSC::JSPromise* invoke(JSC::ExecState&, const char*);
     69    JSC::JSPromise* invoke(JSC::ExecState&, const char*, JSC::JSValue parameter);
    7070    void storeException(JSC::ExecState&);
    7171
Note: See TracChangeset for help on using the changeset viewer.