Title: [249058] trunk/Source
Revision
249058
Author
ross.kirsl...@sony.com
Date
2019-08-23 11:51:20 -0700 (Fri, 23 Aug 2019)

Log Message

JSC should have public API for unhandled promise rejections
https://bugs.webkit.org/show_bug.cgi?id=197172

Reviewed by Keith Miller.

Source/_javascript_Core:

This patch makes it possible to register a unhandled promise rejection callback via the JSC API.
Since there is no event loop in such an environment, this callback fires off of the microtask queue.
The callback receives the promise and rejection reason as arguments and its return value is ignored.

* API/JSContextRef.cpp:
(JSGlobalContextSetUnhandledRejectionCallback): Added.
* API/JSContextRefPrivate.h:
Add new C++ API call.

* API/tests/testapi.cpp:
(TestAPI::promiseResolveTrue): Clean up test output.
(TestAPI::promiseRejectTrue): Clean up test output.
(TestAPI::promiseUnhandledRejection): Added.
(TestAPI::promiseUnhandledRejectionFromUnhandledRejectionCallback): Added.
(TestAPI::promiseEarlyHandledRejections): Added.
(testCAPIViaCpp):
Add new C++ API test.

* jsc.cpp:
(GlobalObject::finishCreation):
(functionSetUnhandledRejectionCallback): Added.
Add corresponding global to JSC shell.

* runtime/JSGlobalObject.h:
(JSC::JSGlobalObject::setUnhandledRejectionCallback): Added.
(JSC::JSGlobalObject::unhandledRejectionCallback const): Added.
Keep a strong reference to the callback.

* runtime/JSGlobalObjectFunctions.cpp:
(JSC::globalFuncHostPromiseRejectionTracker):
Add default behavior.

* runtime/VM.cpp:
(JSC::VM::callPromiseRejectionCallback): Added.
(JSC::VM::didExhaustMicrotaskQueue): Added.
(JSC::VM::promiseRejected): Added.
(JSC::VM::drainMicrotasks):
When microtask queue is exhausted, deal with any pending unhandled rejections
(in a manner based on RejectedPromiseTracker's reportUnhandledRejections),
then make sure this didn't cause any new microtasks to be added to the queue.

* runtime/VM.h:
Store unhandled rejections.
(This collection will always be empty in the presence of WebCore.)

Source/WebCore:

* bindings/js/JSDOMGlobalObject.cpp:
(WebCore::JSDOMGlobalObject::promiseRejectionTracker):
Move JSInternalPromise early-out to JSC side.

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/API/JSContextRef.cpp (249057 => 249058)


--- trunk/Source/_javascript_Core/API/JSContextRef.cpp	2019-08-23 18:29:59 UTC (rev 249057)
+++ trunk/Source/_javascript_Core/API/JSContextRef.cpp	2019-08-23 18:51:20 UTC (rev 249058)
@@ -28,6 +28,7 @@
 #include "JSContextRefInternal.h"
 
 #include "APICast.h"
+#include "APIUtils.h"
 #include "CallFrame.h"
 #include "InitializeThreading.h"
 #include "JSAPIGlobalObject.h"
@@ -37,6 +38,7 @@
 #include "JSCInlines.h"
 #include "SourceProvider.h"
 #include "StackVisitor.h"
+#include "StrongInlines.h"
 #include "Watchdog.h"
 #include <wtf/text/StringBuilder.h>
 #include <wtf/text/StringHash.h>
@@ -252,7 +254,26 @@
     vm.vmEntryGlobalObject(exec)->setName(name ? name->string() : String());
 }
 
+void JSGlobalContextSetUnhandledRejectionCallback(JSGlobalContextRef ctx, JSObjectRef function, JSValueRef* exception)
+{
+    if (!ctx) {
+        ASSERT_NOT_REACHED();
+        return;
+    }
 
+    ExecState* exec = toJS(ctx);
+    VM& vm = exec->vm();
+    JSLockHolder locker(vm);
+
+    JSObject* object = toJS(function);
+    if (!object->isFunction(vm)) {
+        *exception = toRef(createTypeError(exec));
+        return;
+    }
+
+    vm.vmEntryGlobalObject(exec)->setUnhandledRejectionCallback(vm, object);
+}
+
 class BacktraceFunctor {
 public:
     BacktraceFunctor(StringBuilder& builder, unsigned remainingCapacityForFrameCapture)

Modified: trunk/Source/_javascript_Core/API/JSContextRefPrivate.h (249057 => 249058)


--- trunk/Source/_javascript_Core/API/JSContextRefPrivate.h	2019-08-23 18:29:59 UTC (rev 249057)
+++ trunk/Source/_javascript_Core/API/JSContextRefPrivate.h	2019-08-23 18:51:20 UTC (rev 249058)
@@ -128,6 +128,16 @@
 */
 JS_EXPORT void JSGlobalContextSetIncludesNativeCallStackWhenReportingExceptions(JSGlobalContextRef ctx, bool includesNativeCallStack) JSC_API_AVAILABLE(macos(10.10), ios(8.0));
 
+/*!
+@function
+@abstract Sets the unhandled promise rejection callback for a context.
+@discussion Similar to window.addEventListener('unhandledrejection'), but for contexts not associated with a web view.
+@param ctx The JSGlobalContext to set the callback on.
+@param function The callback function to set, which receives the promise and rejection reason as arguments.
+@param exception A pointer to a JSValueRef in which to store an exception, if any. Pass NULL if you do not care to store an exception.
+*/
+JS_EXPORT void JSGlobalContextSetUnhandledRejectionCallback(JSGlobalContextRef ctx, JSObjectRef function, JSValueRef* exception) JSC_API_AVAILABLE(macos(JSC_MAC_TBA), ios(JSC_IOS_TBA));
+
 #ifdef __cplusplus
 }
 #endif

Modified: trunk/Source/_javascript_Core/API/tests/testapi.cpp (249057 => 249058)


--- trunk/Source/_javascript_Core/API/tests/testapi.cpp	2019-08-23 18:29:59 UTC (rev 249057)
+++ trunk/Source/_javascript_Core/API/tests/testapi.cpp	2019-08-23 18:51:20 UTC (rev 249058)
@@ -29,6 +29,7 @@
 #include "JSCJSValueInlines.h"
 #include "JSObject.h"
 
+#include <_javascript_Core/JSContextRefPrivate.h>
 #include <_javascript_Core/JSObjectRefPrivate.h>
 #include <_javascript_Core/_javascript_.h>
 #include <wtf/DataLog.h>
@@ -137,6 +138,9 @@
     void symbolsDeletePropertyForKey();
     void promiseResolveTrue();
     void promiseRejectTrue();
+    void promiseUnhandledRejection();
+    void promiseUnhandledRejectionFromUnhandledRejectionCallback();
+    void promiseEarlyHandledRejections();
 
     int failed() const { return m_failed; }
 
@@ -454,7 +458,7 @@
 
     auto trueValue = JSValueMakeBoolean(context, true);
     JSObjectCallAsFunction(context, resolve, resolve, 1, &trueValue, &exception);
-    check(!exception, "No exception should be thrown resolve promise");
+    check(!exception, "No exception should be thrown resolving promise");
     check(passedTrueCalled, "then response function should have been called.");
 }
 
@@ -479,7 +483,7 @@
 
     APIString catchString("catch");
     JSValueRef catchFunction = JSObjectGetProperty(context, promise, catchString, &exception);
-    check(!exception && catchFunction && JSValueIsObject(context, catchFunction), "Promise should have a then object property");
+    check(!exception && catchFunction && JSValueIsObject(context, catchFunction), "Promise should have a catch object property");
 
     JSValueRef passedTrueFunction = JSObjectMakeFunctionWithCallback(context, trueString, passedTrue);
     JSObjectCallAsFunction(context, const_cast<JSObjectRef>(catchFunction), promise, 1, &passedTrueFunction, &exception);
@@ -487,10 +491,80 @@
 
     auto trueValue = JSValueMakeBoolean(context, true);
     JSObjectCallAsFunction(context, reject, reject, 1, &trueValue, &exception);
-    check(!exception, "No exception should be thrown resolve promise");
-    check(passedTrueCalled, "then response function should have been called.");
+    check(!exception, "No exception should be thrown rejecting promise");
+    check(passedTrueCalled, "catch response function should have been called.");
 }
 
+void TestAPI::promiseUnhandledRejection()
+{
+    JSObjectRef reject;
+    JSValueRef exception = nullptr;
+    static auto promise = JSObjectMakeDeferredPromise(context, nullptr, &reject, &exception);
+    check(!exception, "creating a (reject-only) deferred promise should not throw");
+    static auto reason = JSValueMakeString(context, APIString("reason"));
+
+    static TestAPI* tester = this;
+    static bool callbackCalled = false;
+    auto callback = [](JSContextRef ctx, JSObjectRef, JSObjectRef, size_t argumentCount, const JSValueRef arguments[], JSValueRef*) -> JSValueRef {
+        tester->check(argumentCount && JSValueIsStrictEqual(ctx, arguments[0], promise), "callback should receive rejected promise as first argument");
+        tester->check(argumentCount > 1 && JSValueIsStrictEqual(ctx, arguments[1], reason), "callback should receive rejection reason as second argument");
+        tester->check(argumentCount == 2, "callback should not receive a third argument");
+        callbackCalled = true;
+        return JSValueMakeUndefined(ctx);
+    };
+    auto callbackFunction = JSObjectMakeFunctionWithCallback(context, APIString("callback"), callback);
+
+    JSGlobalContextSetUnhandledRejectionCallback(context, callbackFunction, &exception);
+    check(!exception, "setting unhandled rejection callback should not throw");
+
+    JSObjectCallAsFunction(context, reject, reject, 1, &reason, &exception);
+    check(!exception && callbackCalled, "unhandled rejection callback should be called upon unhandled rejection");
+}
+
+void TestAPI::promiseUnhandledRejectionFromUnhandledRejectionCallback()
+{
+    static JSObjectRef reject;
+    static JSValueRef exception = nullptr;
+    JSObjectMakeDeferredPromise(context, nullptr, &reject, &exception);
+    check(!exception, "creating a (reject-only) deferred promise should not throw");
+
+    static auto callbackCallCount = 0;
+    auto callback = [](JSContextRef ctx, JSObjectRef, JSObjectRef, size_t, const JSValueRef[], JSValueRef*) -> JSValueRef {
+        if (!callbackCallCount)
+            JSObjectCallAsFunction(ctx, reject, reject, 0, nullptr, &exception);
+        callbackCallCount++;
+        return JSValueMakeUndefined(ctx);
+    };
+    auto callbackFunction = JSObjectMakeFunctionWithCallback(context, APIString("callback"), callback);
+
+    JSGlobalContextSetUnhandledRejectionCallback(context, callbackFunction, &exception);
+    check(!exception, "setting unhandled rejection callback should not throw");
+
+    callFunction("(function () { Promise.reject(); })");
+    check(!exception && callbackCallCount == 2, "unhandled rejection from unhandled rejection callback should also trigger the callback");
+}
+
+void TestAPI::promiseEarlyHandledRejections()
+{
+    JSValueRef exception = nullptr;
+    
+    static bool callbackCalled = false;
+    auto callback = [](JSContextRef ctx, JSObjectRef, JSObjectRef, size_t, const JSValueRef[], JSValueRef*) -> JSValueRef {
+        callbackCalled = true;
+        return JSValueMakeUndefined(ctx);
+    };
+    auto callbackFunction = JSObjectMakeFunctionWithCallback(context, APIString("callback"), callback);
+
+    JSGlobalContextSetUnhandledRejectionCallback(context, callbackFunction, &exception);
+    check(!exception, "setting unhandled rejection callback should not throw");
+
+    callFunction("(function () { const p = Promise.reject(); p.catch(() => {}); })");
+    check(!callbackCalled, "unhandled rejection callback should not be called for synchronous early-handled rejection");
+
+    callFunction("(function () { const p = Promise.reject(); Promise.resolve().then(() => { p.catch(() => {}); }); })");
+    check(!callbackCalled, "unhandled rejection callback should not be called for asynchronous early-handled rejection");
+}
+
 #define RUN(test) do {                                 \
         if (!shouldRun(#test))                         \
             break;                                     \
@@ -521,6 +595,9 @@
     RUN(symbolsDeletePropertyForKey());
     RUN(promiseResolveTrue());
     RUN(promiseRejectTrue());
+    RUN(promiseUnhandledRejection());
+    RUN(promiseUnhandledRejectionFromUnhandledRejectionCallback());
+    RUN(promiseEarlyHandledRejections());
 
     if (tasks.isEmpty()) {
         dataLogLn("Filtered all tests: ERROR");

Modified: trunk/Source/_javascript_Core/ChangeLog (249057 => 249058)


--- trunk/Source/_javascript_Core/ChangeLog	2019-08-23 18:29:59 UTC (rev 249057)
+++ trunk/Source/_javascript_Core/ChangeLog	2019-08-23 18:51:20 UTC (rev 249058)
@@ -1,3 +1,55 @@
+2019-08-23  Ross Kirsling  <ross.kirsl...@sony.com>
+
+        JSC should have public API for unhandled promise rejections
+        https://bugs.webkit.org/show_bug.cgi?id=197172
+
+        Reviewed by Keith Miller.
+
+        This patch makes it possible to register a unhandled promise rejection callback via the JSC API.
+        Since there is no event loop in such an environment, this callback fires off of the microtask queue.
+        The callback receives the promise and rejection reason as arguments and its return value is ignored.
+
+        * API/JSContextRef.cpp:
+        (JSGlobalContextSetUnhandledRejectionCallback): Added.
+        * API/JSContextRefPrivate.h:
+        Add new C++ API call.
+
+        * API/tests/testapi.cpp:
+        (TestAPI::promiseResolveTrue): Clean up test output.
+        (TestAPI::promiseRejectTrue): Clean up test output.
+        (TestAPI::promiseUnhandledRejection): Added.
+        (TestAPI::promiseUnhandledRejectionFromUnhandledRejectionCallback): Added.
+        (TestAPI::promiseEarlyHandledRejections): Added.
+        (testCAPIViaCpp):
+        Add new C++ API test.
+
+        * jsc.cpp:
+        (GlobalObject::finishCreation):
+        (functionSetUnhandledRejectionCallback): Added.
+        Add corresponding global to JSC shell.
+
+        * runtime/JSGlobalObject.h:
+        (JSC::JSGlobalObject::setUnhandledRejectionCallback): Added.
+        (JSC::JSGlobalObject::unhandledRejectionCallback const): Added.
+        Keep a strong reference to the callback.
+
+        * runtime/JSGlobalObjectFunctions.cpp:
+        (JSC::globalFuncHostPromiseRejectionTracker):
+        Add default behavior.
+
+        * runtime/VM.cpp:
+        (JSC::VM::callPromiseRejectionCallback): Added.
+        (JSC::VM::didExhaustMicrotaskQueue): Added.
+        (JSC::VM::promiseRejected): Added.
+        (JSC::VM::drainMicrotasks):
+        When microtask queue is exhausted, deal with any pending unhandled rejections
+        (in a manner based on RejectedPromiseTracker's reportUnhandledRejections),
+        then make sure this didn't cause any new microtasks to be added to the queue.
+
+        * runtime/VM.h:
+        Store unhandled rejections.
+        (This collection will always be empty in the presence of WebCore.)
+
 2019-08-22  Mark Lam  <mark....@apple.com>
 
         VirtualRegister::dump() can use more informative CallFrame header slot names.

Modified: trunk/Source/_javascript_Core/jsc.cpp (249057 => 249058)


--- trunk/Source/_javascript_Core/jsc.cpp	2019-08-23 18:29:59 UTC (rev 249057)
+++ trunk/Source/_javascript_Core/jsc.cpp	2019-08-23 18:51:20 UTC (rev 249058)
@@ -384,6 +384,8 @@
 static EncodedJSValue JSC_HOST_CALL functionMallocInALoop(ExecState*);
 static EncodedJSValue JSC_HOST_CALL functionTotalCompileTime(ExecState*);
 
+static EncodedJSValue JSC_HOST_CALL functionSetUnhandledRejectionCallback(ExecState*);
+
 struct Script {
     enum class StrictMode {
         Strict,
@@ -638,6 +640,8 @@
         addFunction(vm, "disableRichSourceInfo", functionDisableRichSourceInfo, 0);
         addFunction(vm, "mallocInALoop", functionMallocInALoop, 0);
         addFunction(vm, "totalCompileTime", functionTotalCompileTime, 0);
+
+        addFunction(vm, "setUnhandledRejectionCallback", functionSetUnhandledRejectionCallback, 1);
     }
     
     void addFunction(VM& vm, JSObject* object, const char* name, NativeFunction function, unsigned arguments)
@@ -2384,6 +2388,19 @@
 
 #endif // ENABLE(WEBASSEMBLY)
 
+EncodedJSValue JSC_HOST_CALL functionSetUnhandledRejectionCallback(ExecState* exec)
+{
+    VM& vm = exec->vm();
+    JSObject* object = exec->argument(0).getObject();
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    if (!object || !object->isFunction(vm))
+        return throwVMTypeError(exec, scope);
+
+    exec->lexicalGlobalObject()->setUnhandledRejectionCallback(vm, object);
+    return JSValue::encode(jsUndefined());
+}
+
 // Use SEH for Release builds only to get rid of the crash report dialog
 // (luckily the same tests fail in Release and Debug builds so far). Need to
 // be in a separate main function because the jscmain function requires object

Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObject.h (249057 => 249058)


--- trunk/Source/_javascript_Core/runtime/JSGlobalObject.h	2019-08-23 18:29:59 UTC (rev 249057)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObject.h	2019-08-23 18:51:20 UTC (rev 249058)
@@ -425,6 +425,8 @@
 
     String m_name;
 
+    Strong<JSObject> m_unhandledRejectionCallback;
+
     Debugger* m_debugger;
 
     VM& m_vm;
@@ -807,6 +809,9 @@
     void setName(const String&);
     const String& name() const { return m_name; }
 
+    void setUnhandledRejectionCallback(VM& vm, JSObject* function) { m_unhandledRejectionCallback.set(vm, function); }
+    JSObject* unhandledRejectionCallback() const { return m_unhandledRejectionCallback.get(); }
+
     JSObject* arrayBufferConstructor() const { return m_arrayBufferStructure.constructor(this); }
 
     JSObject* arrayBufferPrototype(ArrayBufferSharingMode sharingMode) const

Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObjectFunctions.cpp (249057 => 249058)


--- trunk/Source/_javascript_Core/runtime/JSGlobalObjectFunctions.cpp	2019-08-23 18:29:59 UTC (rev 249057)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObjectFunctions.cpp	2019-08-23 18:51:20 UTC (rev 249058)
@@ -766,10 +766,12 @@
     VM& vm = globalObject->vm();
     auto scope = DECLARE_THROW_SCOPE(vm);
 
-    if (!globalObject->globalObjectMethodTable()->promiseRejectionTracker)
+    JSPromise* promise = jsCast<JSPromise*>(exec->argument(0));
+
+    // InternalPromises should not be exposed to user scripts.
+    if (jsDynamicCast<JSInternalPromise*>(vm, promise))
         return JSValue::encode(jsUndefined());
 
-    JSPromise* promise = jsCast<JSPromise*>(exec->argument(0));
     JSValue operationValue = exec->argument(1);
 
     ASSERT(operationValue.isNumber());
@@ -777,7 +779,18 @@
     ASSERT(operation == JSPromiseRejectionOperation::Reject || operation == JSPromiseRejectionOperation::Handle);
     scope.assertNoException();
 
-    globalObject->globalObjectMethodTable()->promiseRejectionTracker(globalObject, exec, promise, operation);
+    if (globalObject->globalObjectMethodTable()->promiseRejectionTracker)
+        globalObject->globalObjectMethodTable()->promiseRejectionTracker(globalObject, exec, promise, operation);
+    else {
+        switch (operation) {
+        case JSPromiseRejectionOperation::Reject:
+            vm.promiseRejected(promise);
+            break;
+        case JSPromiseRejectionOperation::Handle:
+            // do nothing
+            break;
+        }
+    }
     RETURN_IF_EXCEPTION(scope, { });
 
     return JSValue::encode(jsUndefined());

Modified: trunk/Source/_javascript_Core/runtime/VM.cpp (249057 => 249058)


--- trunk/Source/_javascript_Core/runtime/VM.cpp	2019-08-23 18:29:59 UTC (rev 249057)
+++ trunk/Source/_javascript_Core/runtime/VM.cpp	2019-08-23 18:51:20 UTC (rev 249058)
@@ -1090,13 +1090,51 @@
     m_microtaskQueue.append(makeUnique<QueuedTask>(*this, &globalObject, WTFMove(task)));
 }
 
+void VM::callPromiseRejectionCallback(Strong<JSPromise>& promise)
+{
+    JSObject* callback = promise->globalObject()->unhandledRejectionCallback();
+    if (!callback)
+        return;
+
+    auto scope = DECLARE_CATCH_SCOPE(*this);
+
+    CallData callData;
+    CallType callType = getCallData(*this, callback, callData);
+    ASSERT(callType != CallType::None);
+
+    MarkedArgumentBuffer args;
+    args.append(promise.get());
+    args.append(promise->result(*this));
+    call(promise->globalObject()->globalExec(), callback, callType, callData, jsNull(), args);
+    scope.clearException();
+}
+
+void VM::didExhaustMicrotaskQueue()
+{
+    auto unhandledRejections = WTFMove(m_aboutToBeNotifiedRejectedPromises);
+    for (auto& promise : unhandledRejections) {
+        if (promise->isHandled(*this))
+            continue;
+
+        callPromiseRejectionCallback(promise);
+    }
+}
+
+void VM::promiseRejected(JSPromise* promise)
+{
+    m_aboutToBeNotifiedRejectedPromises.constructAndAppend(*this, promise);
+}
+
 void VM::drainMicrotasks()
 {
-    while (!m_microtaskQueue.isEmpty()) {
-        m_microtaskQueue.takeFirst()->run();
-        if (m_onEachMicrotaskTick)
-            m_onEachMicrotaskTick(*this);
-    }
+    do {
+        while (!m_microtaskQueue.isEmpty()) {
+            m_microtaskQueue.takeFirst()->run();
+            if (m_onEachMicrotaskTick)
+                m_onEachMicrotaskTick(*this);
+        }
+        didExhaustMicrotaskQueue();
+    } while (!m_microtaskQueue.isEmpty());
     finalizeSynchronousJSExecution();
 }
 

Modified: trunk/Source/_javascript_Core/runtime/VM.h (249057 => 249058)


--- trunk/Source/_javascript_Core/runtime/VM.h	2019-08-23 18:29:59 UTC (rev 249057)
+++ trunk/Source/_javascript_Core/runtime/VM.h	2019-08-23 18:51:20 UTC (rev 249058)
@@ -123,6 +123,7 @@
 class JSDestructibleObjectHeapCellType;
 class JSGlobalObject;
 class JSObject;
+class JSPromise;
 class JSPropertyNameEnumerator;
 class JSRunLoopTimer;
 class JSStringHeapCellType;
@@ -922,6 +923,8 @@
     void notifyNeedTermination() { m_traps.fireTrap(VMTraps::NeedTermination); }
     void notifyNeedWatchdogCheck() { m_traps.fireTrap(VMTraps::NeedWatchdogCheck); }
 
+    void promiseRejected(JSPromise*);
+
 #if ENABLE(EXCEPTION_SCOPE_VERIFICATION)
     StackTrace* nativeStackTraceOfLastThrow() const { return m_nativeStackTraceOfLastThrow.get(); }
     Thread* throwingThread() const { return m_throwingThread.get(); }
@@ -1008,6 +1011,9 @@
     static void primitiveGigacageDisabledCallback(void*);
     void primitiveGigacageDisabled();
 
+    void callPromiseRejectionCallback(Strong<JSPromise>&);
+    void didExhaustMicrotaskQueue();
+
 #if ENABLE(GC_VALIDATION)
     const ClassInfo* m_initializingObjectClass;
 #endif
@@ -1063,6 +1069,9 @@
     std::unique_ptr<ShadowChicken> m_shadowChicken;
     std::unique_ptr<BytecodeIntrinsicRegistry> m_bytecodeIntrinsicRegistry;
 
+    // FIXME: We should remove handled promises from this list at GC flip. <https://webkit.org/b/201005>
+    Vector<Strong<JSPromise>> m_aboutToBeNotifiedRejectedPromises;
+
     WTF::Function<void(VM&)> m_onEachMicrotaskTick;
     uintptr_t m_currentWeakRefVersion { 0 };
 

Modified: trunk/Source/WebCore/ChangeLog (249057 => 249058)


--- trunk/Source/WebCore/ChangeLog	2019-08-23 18:29:59 UTC (rev 249057)
+++ trunk/Source/WebCore/ChangeLog	2019-08-23 18:51:20 UTC (rev 249058)
@@ -1,3 +1,14 @@
+2019-08-23  Ross Kirsling  <ross.kirsl...@sony.com>
+
+        JSC should have public API for unhandled promise rejections
+        https://bugs.webkit.org/show_bug.cgi?id=197172
+
+        Reviewed by Keith Miller.
+
+        * bindings/js/JSDOMGlobalObject.cpp:
+        (WebCore::JSDOMGlobalObject::promiseRejectionTracker):
+        Move JSInternalPromise early-out to JSC side.
+
 2019-08-23  Kate Cheney  <katherine_che...@apple.com>
 
         Support ITP on a per-session basis (198923)

Modified: trunk/Source/WebCore/bindings/js/JSDOMGlobalObject.cpp (249057 => 249058)


--- trunk/Source/WebCore/bindings/js/JSDOMGlobalObject.cpp	2019-08-23 18:29:59 UTC (rev 249057)
+++ trunk/Source/WebCore/bindings/js/JSDOMGlobalObject.cpp	2019-08-23 18:51:20 UTC (rev 249058)
@@ -216,16 +216,11 @@
 {
     // https://html.spec.whatwg.org/multipage/webappapis.html#the-hostpromiserejectiontracker-implementation
 
-    VM& vm = exec->vm();
     auto& globalObject = *JSC::jsCast<JSDOMGlobalObject*>(jsGlobalObject);
     auto* context = globalObject.scriptExecutionContext();
     if (!context)
         return;
 
-    // InternalPromises should not be exposed to user scripts.
-    if (JSC::jsDynamicCast<JSC::JSInternalPromise*>(vm, promise))
-        return;
-
     // FIXME: If script has muted errors (cross origin), terminate these steps.
     // <https://webkit.org/b/171415> Implement the `muted-errors` property of Scripts to avoid onerror/onunhandledrejection for cross-origin scripts
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to