Changeset 182591 in webkit


Ignore:
Timestamp:
Apr 8, 2015 11:48:16 PM (9 years ago)
Author:
youenn.fablet@crf.canon.fr
Message:

[Streams API] Support the start function parameter in ReadableStream constructor
https://bugs.webkit.org/show_bug.cgi?id=141160

Source/WebCore:

Reviewed by Benjamin Poulain.

Stores the JS source object in ReadableStreamJSSource and calls its "start" function.
This function takes a controller object that has three JS functions as members: close, enqueue and error.
This controller is stored in ReadableStreamJSSource as it will be reused as "pull" parameter.
All three JS functions do not currently do anything.

Test: streams/readablestream-start.html

  • Modules/streams/ReadableStream.cpp:

(WebCore::ReadableStream::start): Place holder for step 11 of https://streams.spec.whatwg.org/#rs-constructor.

  • Modules/streams/ReadableStream.h:
  • bindings/js/JSReadableStreamCustom.cpp:

(WebCore::constructJSReadableStream):

  • bindings/js/ReadableStreamJSSource.cpp:

(WebCore::getPropertyFromObject): Helper function to get a public property from an object.
(WebCore::setPropertyToObject): Helper function to set a public property to an object.
(WebCore::callFunction): Helper function to call a JS function from C++.
(WebCore::ReadableStreamJSSource::ReadableStreamJSSource):
(WebCore::notImplementedFunction):
(WebCore::createReadableStreamEnqueueFunction): Creates the JS function for enqueue.
(WebCore::createReadableStreamCloseFunction): Creates the JS function for close.
(WebCore::createReadableStreamErrorFunction): Creates the JS function for error.
(WebCore::startReadableStreamAsync): Equivalent of promise resolution for start.
(WebCore::ReadableStreamJSSource::start): Calls the "start" function of the JS source with all three JS functions (enqueue, close, error) as parameters.

  • bindings/js/ReadableStreamJSSource.h:

LayoutTests:

Reviewed by Benjamin Poulain.

Added tests to check that start JS function is called with the right parameters and can throw errors.

  • streams/readablestream-start-expected.txt: Added.
  • streams/readablestream-start.html: Added.
Location:
trunk
Files:
2 added
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r182582 r182591  
     12015-04-04 Xabier Rodriguez Calvar <calvaris@igalia.com> and Youenn Fablet <youenn.fablet@crf.canon.fr>
     2
     3        [Streams API] Support the start function parameter in ReadableStream constructor
     4        https://bugs.webkit.org/show_bug.cgi?id=141160
     5
     6        Reviewed by Benjamin Poulain.
     7
     8        Added tests to check that start JS function is called with the right parameters and can throw errors.
     9
     10        * streams/readablestream-start-expected.txt: Added.
     11        * streams/readablestream-start.html: Added.
     12
    1132015-04-08  Brent Fulgham  <bfulgham@apple.com>
    214
  • trunk/LayoutTests/streams/readablestream-constructor.html

    r182140 r182591  
    77    assert_throws(new TypeError(), function() {
    88        new ReadableStream('potato');
     9    });
     10    var x
     11    assert_throws(new TypeError(), function() {
     12        new ReadableStream(x);
     13    });
     14    assert_throws(new TypeError(), function() {
     15        new ReadableStream(null);
    916    });
    1017}, 'ReadableStream constructor should get an object as argument');
  • trunk/Source/WebCore/ChangeLog

    r182589 r182591  
     12015-04-08  Xabier Rodriguez Calvar  <calvaris@igalia.com> and Youenn Fablet  <youenn.fablet@crf.canon.fr>
     2
     3        [Streams API] Support the start function parameter in ReadableStream constructor
     4        https://bugs.webkit.org/show_bug.cgi?id=141160
     5
     6        Reviewed by Benjamin Poulain.
     7
     8        Stores the JS source object in ReadableStreamJSSource and calls its "start" function.
     9        This function takes a controller object that has three JS functions as members: close, enqueue and error.
     10        This controller is stored in ReadableStreamJSSource as it will be reused as "pull" parameter.
     11        All three JS functions do not currently do anything.
     12
     13        Test: streams/readablestream-start.html
     14
     15        * Modules/streams/ReadableStream.cpp:
     16        (WebCore::ReadableStream::start): Place holder for step 11 of https://streams.spec.whatwg.org/#rs-constructor.
     17        * Modules/streams/ReadableStream.h:
     18        * bindings/js/JSReadableStreamCustom.cpp:
     19        (WebCore::constructJSReadableStream):
     20        * bindings/js/ReadableStreamJSSource.cpp:
     21        (WebCore::getPropertyFromObject): Helper function to get a public property from an object.
     22        (WebCore::setPropertyToObject): Helper function to set a public property to an object.
     23        (WebCore::callFunction): Helper function to call a JS function from C++.
     24        (WebCore::ReadableStreamJSSource::ReadableStreamJSSource):
     25        (WebCore::notImplementedFunction):
     26        (WebCore::createReadableStreamEnqueueFunction): Creates the JS function for enqueue.
     27        (WebCore::createReadableStreamCloseFunction): Creates the JS function for close.
     28        (WebCore::createReadableStreamErrorFunction): Creates the JS function for error.
     29        (WebCore::startReadableStreamAsync): Equivalent of promise resolution for start.
     30        (WebCore::ReadableStreamJSSource::start): Calls the "start" function of the JS source with all three JS functions (enqueue, close, error) as parameters.
     31        * bindings/js/ReadableStreamJSSource.h:
     32
    1332015-04-08  Brent Fulgham  <bfulgham@apple.com>
    234
  • trunk/Source/WebCore/Modules/streams/ReadableStream.cpp

    r182544 r182591  
    5959}
    6060
     61void ReadableStream::start()
     62{
     63    notImplemented();
     64}
     65
    6166const char* ReadableStream::activeDOMObjectName() const
    6267{
  • trunk/Source/WebCore/Modules/streams/ReadableStream.h

    r182544 r182591  
    6868    State internalState() { return m_state; }
    6969
     70    void start();
     71
    7072protected:
    7173    ReadableStream(ScriptExecutionContext&, Ref<ReadableStreamSource>&&);
  • trunk/Source/WebCore/bindings/js/JSReadableStreamCustom.cpp

    r182344 r182591  
    8888    JSReadableStream* jsReadableStream = JSReadableStream::create(JSReadableStream::createStructure(vm, globalObject, JSReadableStream::createPrototype(vm, globalObject)), jsCast<JSDOMGlobalObject*>(globalObject), readableStream.releaseNonNull());
    8989
    90     source->start(exec);
     90    source->start(exec, jsReadableStream);
    9191
    9292    return JSValue::encode(jsReadableStream);
  • trunk/Source/WebCore/bindings/js/ReadableStreamJSSource.cpp

    r182309 r182591  
    2929
    3030#include "config.h"
     31#include "ReadableStreamJSSource.h"
    3132
    3233#if ENABLE(STREAMS_API)
    33 #include "ReadableStreamJSSource.h"
    3434
    3535#include "DOMWrapperWorld.h"
     
    3737#include "JSReadableStream.h"
    3838#include "NotImplemented.h"
     39#include "ScriptExecutionContext.h"
    3940#include <runtime/Error.h>
    4041#include <runtime/JSCJSValueInlines.h>
     
    6465}
    6566
     67static inline JSValue getPropertyFromObject(ExecState* exec, JSObject* object, const char* identifier)
     68{
     69    return object->get(exec, Identifier::fromString(exec, identifier));
     70}
     71
     72static inline void setPropertyToObject(ExecState* exec, JSValue objectValue, const char* name, JSValue value)
     73{
     74    JSObject* object = objectValue.toObject(exec);
     75    PutPropertySlot propertySlot(objectValue);
     76    object->put(object, exec, Identifier::fromString(exec, name), value, propertySlot);
     77}
     78
     79static inline JSValue callFunction(ExecState* exec, JSValue jsFunction, JSValue thisValue, const ArgList& arguments, JSValue* exception)
     80{
     81    CallData callData;
     82    CallType callType = getCallData(jsFunction, callData);
     83    return call(exec, jsFunction, callType, callData, thisValue, arguments, exception);
     84}
     85
    6686Ref<ReadableStreamJSSource> ReadableStreamJSSource::create(JSC::ExecState* exec)
    6787{
     
    7191ReadableStreamJSSource::ReadableStreamJSSource(JSC::ExecState* exec)
    7292{
    73     if (exec->argumentCount()) {
    74         ASSERT_WITH_MESSAGE(exec->argument(0).isObject(), "Caller of ReadableStreamJSSource constructor should ensure that passed argument is an object.");
    75         // FIXME: Implement parameters support;
     93    ASSERT_WITH_MESSAGE(!exec->argumentCount() || exec->argument(0).isObject(), "Caller of ReadableStreamJSSource constructor should ensure that passed argument if any is an object.");
     94    JSObject* source =  exec->argumentCount() ? exec->argument(0).getObject() : JSFinalObject::create(exec->vm(), JSFinalObject::createStructure(exec->vm(), exec->callee()->globalObject(), jsNull(), 1));
     95    m_source.set(exec->vm(), source);
     96}
     97
     98static EncodedJSValue JSC_HOST_CALL notImplementedFunction(ExecState*)
     99{
     100    notImplemented();
     101    return JSValue::encode(jsUndefined());
     102}
     103
     104static inline JSFunction* createReadableStreamEnqueueFunction(ExecState* exec)
     105{
     106    return JSFunction::create(exec->vm(), exec->callee()->globalObject(), 1, String(), notImplementedFunction);
     107}
     108
     109static inline JSFunction* createReadableStreamCloseFunction(ExecState* exec)
     110{
     111    return JSFunction::create(exec->vm(), exec->callee()->globalObject(), 0, String(), notImplementedFunction);
     112}
     113
     114static inline JSFunction* createReadableStreamErrorFunction(ExecState* exec)
     115{
     116    return JSFunction::create(exec->vm(), exec->callee()->globalObject(), 1, String(), notImplementedFunction);
     117}
     118
     119static void startReadableStreamAsync(ReadableStream& readableStream)
     120{
     121    RefPtr<ReadableStream> stream = &readableStream;
     122    stream->scriptExecutionContext()->postTask([stream](ScriptExecutionContext&) {
     123        stream->start();
     124    });
     125}
     126
     127static inline JSObject* createReadableStreamController(JSC::ExecState* exec)
     128{
     129    JSFunction* enqueueFunction = createReadableStreamEnqueueFunction(exec);
     130    JSFunction* closeFunction = createReadableStreamCloseFunction(exec);
     131    JSFunction* errorFunction = createReadableStreamErrorFunction(exec);
     132
     133    JSObject* controller =  JSFinalObject::create(exec->vm(), JSFinalObject::createStructure(exec->vm(), exec->callee()->globalObject(), jsNull(), 3));
     134    setPropertyToObject(exec, controller, "enqueue", enqueueFunction);
     135    setPropertyToObject(exec, controller, "close", closeFunction);
     136    setPropertyToObject(exec, controller, "error", errorFunction);
     137    return controller;
     138}
     139
     140void ReadableStreamJSSource::start(JSC::ExecState* exec, JSReadableStream* readableStream)
     141{
     142    JSLockHolder lock(exec);
     143
     144    m_controller.set(exec->vm(), createReadableStreamController(exec));
     145
     146    JSValue startFunction = getPropertyFromObject(exec, m_source.get(), "start");
     147    if (!startFunction.isFunction()) {
     148        if (!startFunction.isUndefined())
     149            throwVMError(exec, createTypeError(exec, ASCIILiteral("ReadableStream constructor object start property should be a function.")));
     150        else
     151            startReadableStreamAsync(readableStream->impl());
     152        return;
    76153    }
    77 }
    78 
    79 void ReadableStreamJSSource::start(JSC::ExecState*)
    80 {
    81     notImplemented();
     154
     155    MarkedArgumentBuffer arguments;
     156    arguments.append(m_controller.get());
     157
     158    JSValue exception;
     159    callFunction(exec, startFunction, m_source.get(), arguments, &exception);
     160
     161    if (exception) {
     162        throwVMError(exec, exception);
     163        return;
     164    }
     165
     166    // FIXME: Implement handling promise as result of calling start function.
     167    startReadableStreamAsync(readableStream->impl());
    82168}
    83169
  • trunk/Source/WebCore/bindings/js/ReadableStreamJSSource.h

    r182309 r182591  
    5151    ~ReadableStreamJSSource() { }
    5252
    53     void start(JSC::ExecState*);
     53    void start(JSC::ExecState*, JSReadableStream*);
    5454
    5555private:
    5656    ReadableStreamJSSource(JSC::ExecState*);
     57
     58    // Object passed to constructor.
     59    JSC::Strong<JSC::JSObject> m_source;
     60
     61    JSC::Strong<JSC::JSObject> m_controller;
    5762};
    5863
Note: See TracChangeset for help on using the changeset viewer.