Changeset 223725 in webkit


Ignore:
Timestamp:
Oct 19, 2017 4:31:03 PM (6 years ago)
Author:
weinig@apple.com
Message:

[Bindings] Standardize on DOMPromise as the way to store passed in promises
https://bugs.webkit.org/show_bug.cgi?id=178533

Reviewed by Youenn Fablet.

This standardizes on RefPtr<DOMPromise> as the canonical way to store a promise
that has been passed in from JS. This does not change promises that start off in
WebCore and are passed to JS; they remain using DOMPromiseDeferred and DOMPromiseProxy.

  • Modules/paymentrequest/PaymentRequestUpdateEvent.cpp:
  • Modules/paymentrequest/PaymentRequestUpdateEvent.h:
  • dom/PromiseRejectionEvent.cpp:
  • dom/PromiseRejectionEvent.h:
  • dom/RejectedPromiseTracker.cpp:

Use a RefPtr<DOMPromise> rather than a JSPromise* to hold onto the promise.

  • bindings/IDLTypes.h:

Use IDLWrapper to get better defaults, since DOMPromise is refcounted.

  • bindings/js/JSDOMConvertPromise.h:

(WebCore::Converter<IDLPromise<T>>::convert):

Switch default conversion to return a RefPtr<DOMPromise> rather than a JSPromise*

(WebCore::JSConverter<IDLPromise<T>>::convert):

Add support for converting from a DOMPromise to a JSValue.

  • bindings/js/JSDOMPromise.cpp:
  • bindings/js/JSDOMPromise.h:

(WebCore::DOMPromise::create): Deleted.

Remove now unused constructor.

  • workers/service/ExtendableEvent.cpp:

(WebCore::ExtendableEvent::waitUntil):

  • workers/service/ExtendableEvent.h:
  • workers/service/ExtendableEvent.idl:
  • workers/service/FetchEvent.cpp:

(WebCore::FetchEvent::respondWith):
(WebCore::FetchEvent::promiseIsSettled):

  • workers/service/FetchEvent.h:
  • workers/service/FetchEvent.idl:

Address FIXMEs and remove need for passing an ExecState to ExtendableEvent
and FetchEvent by using the new default conversion to DOMPromise.

Location:
trunk/Source/WebCore
Files:
17 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r223720 r223725  
     12017-10-19  Sam Weinig  <sam@webkit.org>
     2
     3        [Bindings] Standardize on DOMPromise as the way to store passed in promises
     4        https://bugs.webkit.org/show_bug.cgi?id=178533
     5
     6        Reviewed by Youenn Fablet.
     7
     8        This standardizes on RefPtr<DOMPromise> as the canonical way to store a promise
     9        that has been passed in from JS. This does not change promises that start off in
     10        WebCore and are passed to JS; they remain using DOMPromiseDeferred and DOMPromiseProxy.
     11
     12        * Modules/paymentrequest/PaymentRequestUpdateEvent.cpp:
     13        * Modules/paymentrequest/PaymentRequestUpdateEvent.h:
     14        * dom/PromiseRejectionEvent.cpp:
     15        * dom/PromiseRejectionEvent.h:
     16        * dom/RejectedPromiseTracker.cpp:
     17
     18            Use a RefPtr<DOMPromise> rather than a JSPromise* to hold onto the promise.
     19
     20        * bindings/IDLTypes.h:
     21
     22            Use IDLWrapper to get better defaults, since DOMPromise is refcounted.
     23
     24        * bindings/js/JSDOMConvertPromise.h:
     25        (WebCore::Converter<IDLPromise<T>>::convert):
     26
     27            Switch default conversion to return a RefPtr<DOMPromise> rather than a JSPromise*
     28
     29        (WebCore::JSConverter<IDLPromise<T>>::convert):
     30
     31            Add support for converting from a DOMPromise to a JSValue.
     32
     33        * bindings/js/JSDOMPromise.cpp:
     34        * bindings/js/JSDOMPromise.h:
     35        (WebCore::DOMPromise::create): Deleted.
     36
     37            Remove now unused constructor.   
     38
     39        * workers/service/ExtendableEvent.cpp:
     40        (WebCore::ExtendableEvent::waitUntil):
     41        * workers/service/ExtendableEvent.h:
     42        * workers/service/ExtendableEvent.idl:
     43        * workers/service/FetchEvent.cpp:
     44        (WebCore::FetchEvent::respondWith):
     45        (WebCore::FetchEvent::promiseIsSettled):
     46        * workers/service/FetchEvent.h:
     47        * workers/service/FetchEvent.idl:
     48
     49            Address FIXMEs and remove need for passing an ExecState to ExtendableEvent
     50            and FetchEvent by using the new default conversion to DOMPromise.
     51
    1522017-10-19  Sam Weinig  <sam@webkit.org>
    253
  • trunk/Source/WebCore/Modules/paymentrequest/PaymentRequestUpdateEvent.cpp

    r220955 r223725  
    3535}
    3636
    37 void PaymentRequestUpdateEvent::updateWith(JSC::JSPromise*)
     37void PaymentRequestUpdateEvent::updateWith(Ref<DOMPromise>&&)
    3838{
    3939}
  • trunk/Source/WebCore/Modules/paymentrequest/PaymentRequestUpdateEvent.h

    r220955 r223725  
    3030#include "Event.h"
    3131
    32 namespace JSC {
    33 class JSPromise;
    34 }
     32namespace WebCore {
    3533
    36 namespace WebCore {
     34class DOMPromise;
    3735
    3836class PaymentRequestUpdateEvent final : public Event {
    3937public:
    4038    ~PaymentRequestUpdateEvent();
    41     void updateWith(JSC::JSPromise*);
     39    void updateWith(Ref<DOMPromise>&&);
    4240};
    4341
  • trunk/Source/WebCore/bindings/IDLTypes.h

    r220620 r223725  
    221221};
    222222
    223 template<typename T> struct IDLPromise : IDLType<DOMPromise> {
     223template<typename T> struct IDLPromise : IDLWrapper<DOMPromise> {
    224224    using InnerType = T;
    225225};
  • trunk/Source/WebCore/bindings/js/JSDOMConvertPromise.h

    r220433 r223725  
    3333
    3434template<typename T> struct Converter<IDLPromise<T>> : DefaultConverter<IDLPromise<T>> {
    35     using ReturnType = JSC::JSPromise*;
     35    using ReturnType = RefPtr<DOMPromise>;
    3636
    3737    // https://heycam.github.io/webidl/#es-promise
     
    5555
    5656        // 3. Return the IDL promise type value that is a reference to the same object as promise.
    57         return promise;
     57        return DOMPromise::create(*globalObject, *promise);
    5858    }
    5959};
     
    6363    static constexpr bool needsGlobalObject = true;
    6464
    65     static JSC::JSValue convert(JSC::ExecState&, JSDOMGlobalObject&, JSC::JSPromise& promise)
     65    static JSC::JSValue convert(JSC::ExecState&, JSDOMGlobalObject&, DOMPromise& promise)
    6666    {
    67         return &promise;
     67        return promise.promise();
    6868    }
    6969
  • trunk/Source/WebCore/bindings/js/JSDOMPromise.cpp

    r223562 r223725  
    5050}
    5151
    52 Ref<DOMPromise> DOMPromise::create(JSC::ExecState& state, JSC::JSValue value)
    53 {
    54     auto& globalObject = *JSC::jsCast<JSDOMGlobalObject*>(state.lexicalGlobalObject());
    55 
    56     auto promiseConstructor = globalObject.promiseConstructor();
    57     auto resolveFunction = promiseConstructor->get(&state, state.vm().propertyNames->builtinNames().resolvePrivateName());
    58     ASSERT(resolveFunction.isFunction());
    59 
    60     JSC::MarkedArgumentBuffer arguments;
    61     arguments.append(value);
    62     auto result = callFunction(state, resolveFunction, promiseConstructor, arguments);
    63 
    64     auto* promise = JSC::jsCast<JSC::JSPromise*>(result);
    65     ASSERT(promise);
    66 
    67     return create(globalObject, *promise);
    68 }
    69 
    7052void DOMPromise::whenSettled(std::function<void()>&& callback)
    7153{
  • trunk/Source/WebCore/bindings/js/JSDOMPromise.h

    r223562 r223725  
    3434class DOMPromise : public DOMGuarded<JSC::JSPromise> {
    3535public:
    36     static Ref<DOMPromise> create(JSC::ExecState&, JSC::JSValue);
    3736    static Ref<DOMPromise> create(JSDOMGlobalObject& globalObject, JSC::JSPromise& promise)
    3837    {
  • trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm

    r223476 r223725  
    15451545    }
    15461546
    1547     return "${name}.releaseNonNull()" if $codeGenerator->IsCallbackInterface($type) || $codeGenerator->IsCallbackFunction($type);
     1547    return "${name}.releaseNonNull()" if $codeGenerator->IsCallbackInterface($type) || $codeGenerator->IsCallbackFunction($type) || $codeGenerator->IsPromiseType($type);
    15481548    return "*${name}" if $codeGenerator->IsWrapperType($type);
    15491549    return "WTFMove(${name})";
  • trunk/Source/WebCore/dom/PromiseRejectionEvent.cpp

    r223476 r223725  
    2828
    2929#include "DOMWrapperWorld.h"
     30#include "JSDOMPromise.h"
    3031#include <heap/HeapInlines.h>
    3132#include <heap/StrongInlines.h>
    32 
    3333
    3434namespace WebCore {
     
    3737PromiseRejectionEvent::PromiseRejectionEvent(ExecState& state, const AtomicString& type, const Init& initializer, IsTrusted isTrusted)
    3838    : Event(type, initializer, isTrusted)
    39     , m_promise(state.vm(), initializer.promise)
     39    , m_promise(*(initializer.promise))
    4040    , m_reason(state.vm(), initializer.reason)
    4141{
  • trunk/Source/WebCore/dom/PromiseRejectionEvent.h

    r218593 r223725  
    2828#include "Event.h"
    2929#include <heap/Strong.h>
    30 #include <runtime/JSPromise.h>
    3130
    3231namespace WebCore {
     32
     33class DOMPromise;
    3334
    3435class PromiseRejectionEvent final : public Event {
    3536public:
    3637    struct Init : EventInit {
    37         JSC::JSPromise* promise;
     38        RefPtr<DOMPromise> promise;
    3839        JSC::JSValue reason;
    3940    };
     
    4647    virtual ~PromiseRejectionEvent();
    4748
    48     JSC::JSPromise& promise() const { return *m_promise.get(); }
     49    DOMPromise& promise() const { return m_promise.get(); }
    4950    JSC::JSValue reason() const { return m_reason.get(); }
    5051
     
    5455    PromiseRejectionEvent(JSC::ExecState&, const AtomicString&, const Init&, IsTrusted);
    5556
    56     JSC::Strong<JSC::JSPromise> m_promise;
     57    Ref<DOMPromise> m_promise;
    5758    JSC::Strong<JSC::Unknown> m_reason;
    5859};
  • trunk/Source/WebCore/dom/RejectedPromiseTracker.cpp

    r223476 r223725  
    167167        PromiseRejectionEvent::Init initializer;
    168168        initializer.cancelable = true;
    169         initializer.promise = &promise;
     169        initializer.promise = &domPromise;
    170170        initializer.reason = promise.result(vm);
    171171
     
    196196
    197197    PromiseRejectionEvent::Init initializer;
    198     initializer.promise = &promise;
     198    initializer.promise = rejectedPromise.ptr();
    199199    initializer.reason = promise.result(vm);
    200200
  • trunk/Source/WebCore/workers/service/ExtendableEvent.cpp

    r223562 r223725  
    2929#if ENABLE(SERVICE_WORKER)
    3030
     31#include "JSDOMPromise.h"
     32
    3133namespace WebCore {
    3234
     
    3638}
    3739
    38 ExceptionOr<void> ExtendableEvent::waitUntil(JSC::ExecState& state, JSC::JSValue promise)
     40ExceptionOr<void> ExtendableEvent::waitUntil(Ref<DOMPromise>&& promise)
    3941{
    4042    if (!isTrusted())
     
    4446        return Exception { InvalidStateError, ASCIILiteral("Event is being dispatched") };
    4547
    46     addPendingPromise(DOMPromise::create(state, promise));
    47 
     48    addPendingPromise(WTFMove(promise));
    4849    return { };
    4950}
  • trunk/Source/WebCore/workers/service/ExtendableEvent.h

    r223562 r223725  
    3030#include "Event.h"
    3131#include "ExtendableEventInit.h"
    32 #include "JSDOMPromise.h"
    3332#include <wtf/WeakPtr.h>
    3433
    3534namespace WebCore {
     35
     36class DOMPromise;
    3637
    3738class ExtendableEvent : public Event {
     
    4445    EventInterface eventInterface() const override { return ExtendableEventInterfaceType; }
    4546
    46     ExceptionOr<void> waitUntil(JSC::ExecState&, JSC::JSValue);
     47    ExceptionOr<void> waitUntil(Ref<DOMPromise>&&);
    4748
    4849    WEBCORE_EXPORT void onFinishedWaitingForTesting(WTF::Function<void()>&&);
  • trunk/Source/WebCore/workers/service/ExtendableEvent.idl

    r223562 r223725  
    2424*/
    2525
    26 //FIXME: Should be exposed on ServiceWorker only.
     26// FIXME: Should be exposed on ServiceWorker only.
    2727[
    2828    Constructor(DOMString type, optional ExtendableEventInit eventInitDict),
     
    3232    ExportMacro=WEBCORE_EXPORT,
    3333    JSGenerateToNativeObject,
    34 ]
    35 interface ExtendableEvent : Event {
    36     // FIXME: Binding generator should be able to wrap any non Promise value into a promise and pass it to waitUntil.
    37     [CallWith=ScriptState, MayThrowException] void waitUntil(any f);
     34] interface ExtendableEvent : Event {
     35    [MayThrowException] void waitUntil(Promise<any> f);
    3836};
  • trunk/Source/WebCore/workers/service/FetchEvent.cpp

    r223577 r223725  
    2727#include "FetchEvent.h"
    2828
     29#include "JSDOMPromise.h"
    2930#include "JSFetchResponse.h"
    3031
     
    4243}
    4344
    44 ExceptionOr<void> FetchEvent::respondWith(JSC::ExecState& state, JSC::JSValue promise)
     45ExceptionOr<void> FetchEvent::respondWith(Ref<DOMPromise>&& promise)
    4546{
    4647    if (isBeingDispatched())
     
    5051        return Exception { InvalidStateError, ASCIILiteral("Event respondWith flag is set") };
    5152
    52     m_respondPromise = DOMPromise::create(state, promise);
     53    m_respondPromise = WTFMove(promise);
    5354    addPendingPromise(*m_respondPromise);
    5455
     
    134135
    135136    auto body = m_response->consumeBody();
    136     WTF::switchOn(body, [] (Ref<FormData>&) {
    137         // FIXME: Support FormData response bodies.
    138     }, [this] (Ref<SharedBuffer>& buffer) {
    139         m_responseBody = WTFMove(buffer);
    140     }, [] (std::nullptr_t&) {
    141     });
     137    WTF::switchOn(body,
     138        [] (Ref<FormData>&) {
     139            // FIXME: Support FormData response bodies.
     140        },
     141        [this] (Ref<SharedBuffer>& buffer) {
     142            m_responseBody = WTFMove(buffer);
     143        },
     144        [] (std::nullptr_t&) {
     145        }
     146    );
    142147
    143148    processResponse();
  • trunk/Source/WebCore/workers/service/FetchEvent.h

    r223562 r223725  
    5050    EventInterface eventInterface() const final { return FetchEventInterfaceType; }
    5151
    52     ExceptionOr<void> respondWith(JSC::ExecState&, JSC::JSValue);
     52    ExceptionOr<void> respondWith(Ref<DOMPromise>&&);
    5353
    5454    WEBCORE_EXPORT void onResponse(WTF::Function<void()>&&);
  • trunk/Source/WebCore/workers/service/FetchEvent.idl

    r223562 r223725  
    2424*/
    2525
    26 //FIXME: Should be exposed on ServiceWorker only.
     26// FIXME: Should be exposed on ServiceWorker only.
    2727[
    2828    Constructor(DOMString type, FetchEventInit eventInitDict),
     
    3333    ExportToWrappedFunction,
    3434    JSGenerateToNativeObject
    35 ]
    36 interface FetchEvent : ExtendableEvent {
     35] interface FetchEvent : ExtendableEvent {
    3736    [SameObject] readonly attribute FetchRequest request;
    3837    readonly attribute DOMString clientId;
     
    4039    readonly attribute DOMString targetClientId;
    4140
    42     // FIXME: Binding generator should be able to wrap any non Promise value into a promise and pass it to respondWith.
    43     [CallWith=ScriptState, MayThrowException] void respondWith(any r);
     41    [MayThrowException] void respondWith(Promise<FetchResponse> r);
    4442};
    4543
Note: See TracChangeset for help on using the changeset viewer.