WebKit Bugzilla
Attachment 373561 Details for
Bug 197172
: JSC should have public API for unhandled promise rejections
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Finish Yusuke's PoC
bug-197172-20190705202718.patch (text/plain), 21.66 KB, created by
Ross Kirsling
on 2019-07-05 20:27:19 PDT
(
hide
)
Description:
Finish Yusuke's PoC
Filename:
MIME Type:
Creator:
Ross Kirsling
Created:
2019-07-05 20:27:19 PDT
Size:
21.66 KB
patch
obsolete
>Subversion Revision: 247173 >diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog >index 18765fef0ecd412dbfefbbd6a51a976c10b04d49..09e8772ade886de576abb977f2262860953c2d1a 100644 >--- a/Source/JavaScriptCore/ChangeLog >+++ b/Source/JavaScriptCore/ChangeLog >@@ -1,3 +1,54 @@ >+2019-07-05 Ross Kirsling <ross.kirsling@sony.com> >+ >+ Uncaught Promise Exceptions in JavaScriptCore >+ https://bugs.webkit.org/show_bug.cgi?id=197172 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ This patch allows callbacks for unhandled and late-handled promise rejections to be set via JSC's public C API. >+ Since there is no event loop in such an environment, these callbacks fire off of the microtask queue. >+ Callbacks receive the promise and rejection reason as arguments and their return value is ignored. >+ >+ * API/JSContextRef.cpp: >+ (JSGlobalContextSetUnhandledRejectionCallback): >+ (JSGlobalContextSetRejectionHandledCallback): >+ * API/JSContextRef.h: >+ Add new public APIs. >+ >+ * API/tests/testapi.cpp: >+ (TestAPI::promiseResolveTrue): Clean up test output. >+ (TestAPI::promiseRejectTrue): Clean up test output. >+ (TestAPI::promiseRejectionCallbacks): Added. >+ (testCAPIViaCpp): >+ Add new C++ API test. >+ >+ * jsc.cpp: >+ (GlobalObject::finishCreation): >+ (functionSetUnhandledRejectionCallback): >+ (functionSetRejectionHandledCallback): >+ Add corresponding globals to JSC shell. >+ >+ * runtime/JSGlobalObject.h: >+ (JSC::JSGlobalObject::setUnhandledRejectionCallback): >+ (JSC::JSGlobalObject::unhandledRejectionCallback const): >+ (JSC::JSGlobalObject::setRejectionHandledCallback): >+ (JSC::JSGlobalObject::rejectionHandledCallback const): >+ Keep strong references to the callbacks. >+ >+ * runtime/JSGlobalObjectFunctions.cpp: >+ (JSC::globalFuncHostPromiseRejectionTracker): >+ Add default behavior (based on promiseRejected and promiseHandled in RejectedPromiseTracker). >+ >+ * runtime/VM.cpp: >+ (JSC::VM::VM): >+ (JSC::VM::callPromiseRejectionCallback): >+ (JSC::VM::didExhaustMicrotaskQueue): >+ (JSC::VM::drainMicrotasks): >+ * runtime/VM.h: >+ Store rejections of various states (these collections will always be empty in the presence of WebCore). >+ When microtask queue is exhausted, deal with any pending unhandled / late-handled rejections, >+ then make sure this didn't cause anything new microtasks to be added to the queue. >+ > 2019-07-05 Alexey Shvayka <shvaikalesh@gmail.com> > > [JSC] Clean up ArraySpeciesCreate >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index a31221fe7f6ad9dd7bb1b2fc0078c6838b56f6ae..bd9f5d366a12d84cb8782a592de228877404606d 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,14 @@ >+2019-07-05 Ross Kirsling <ross.kirsling@sony.com> >+ >+ Uncaught Promise Exceptions in JavaScriptCore >+ https://bugs.webkit.org/show_bug.cgi?id=197172 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * bindings/js/JSDOMGlobalObject.cpp: >+ (WebCore::JSDOMGlobalObject::promiseRejectionTracker): >+ Move JSInternalPromise early-out to JSC side. >+ > 2019-07-05 Youenn Fablet <youenn@apple.com> > > Add fetch quirk for www.bnz.co.nz >diff --git a/Source/JavaScriptCore/API/JSContextRef.cpp b/Source/JavaScriptCore/API/JSContextRef.cpp >index 9f5fdafc78196fe448c18d07915e04fa38684aaa..72d00e3984074b0608e74a14d4ad6640f9c794ac 100644 >--- a/Source/JavaScriptCore/API/JSContextRef.cpp >+++ b/Source/JavaScriptCore/API/JSContextRef.cpp >@@ -37,6 +37,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> >@@ -249,6 +250,47 @@ void JSGlobalContextSetName(JSGlobalContextRef ctx, JSStringRef name) > vm.vmEntryGlobalObject(exec)->setName(name ? name->string() : String()); > } > >+void JSGlobalContextSetUnhandledRejectionCallback(JSGlobalContextRef ctx, JSObjectRef function) >+{ >+ if (!ctx) { >+ ASSERT_NOT_REACHED(); >+ return; >+ } >+ >+ ExecState* exec = toJS(ctx); >+ VM& vm = exec->vm(); >+ JSLockHolder locker(vm); >+ auto scope = DECLARE_THROW_SCOPE(vm); >+ >+ JSObject* jsObject = toJS(function); >+ if (!jsObject->isFunction(vm)) { >+ throwTypeError(exec, scope); >+ return; >+ } >+ >+ vm.vmEntryGlobalObject(exec)->setUnhandledRejectionCallback(vm, jsCast<JSFunction*>(jsObject)); >+} >+ >+void JSGlobalContextSetRejectionHandledCallback(JSGlobalContextRef ctx, JSObjectRef function) >+{ >+ if (!ctx) { >+ ASSERT_NOT_REACHED(); >+ return; >+ } >+ >+ ExecState* exec = toJS(ctx); >+ VM& vm = exec->vm(); >+ JSLockHolder locker(vm); >+ auto scope = DECLARE_THROW_SCOPE(vm); >+ >+ JSObject* jsObject = toJS(function); >+ if (!jsObject->isFunction(vm)) { >+ throwTypeError(exec, scope); >+ return; >+ } >+ >+ vm.vmEntryGlobalObject(exec)->setRejectionHandledCallback(vm, jsCast<JSFunction*>(jsObject)); >+} > > class BacktraceFunctor { > public: >diff --git a/Source/JavaScriptCore/API/JSContextRef.h b/Source/JavaScriptCore/API/JSContextRef.h >index 1ce7435804ebb9bc47f7c1f0d9e94fc078988c0b..8355fcc1a8c43ee8f1202d55a0a0de9da0c65150 100644 >--- a/Source/JavaScriptCore/API/JSContextRef.h >+++ b/Source/JavaScriptCore/API/JSContextRef.h >@@ -156,6 +156,24 @@ JS_EXPORT JSStringRef JSGlobalContextCopyName(JSGlobalContextRef ctx) JSC_API_AV > */ > JS_EXPORT void JSGlobalContextSetName(JSGlobalContextRef ctx, JSStringRef name) JSC_API_AVAILABLE(macos(10.10), ios(8.0)); > >+/*! >+@function >+@abstract Sets the "unhandled promise rejection" callback for a context. >+@discussion JSC-only alternative to window.addEventListener('unhandledrejection'). >+@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. >+*/ >+JS_EXPORT void JSGlobalContextSetUnhandledRejectionCallback(JSGlobalContextRef ctx, JSObjectRef function); >+ >+/*! >+@function >+@abstract Sets the "late-handled promise rejection" callback for a context. >+@discussion JSC-only alternative to window.addEventListener('rejectionhandled'). >+@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. >+*/ >+JS_EXPORT void JSGlobalContextSetRejectionHandledCallback(JSGlobalContextRef ctx, JSObjectRef function); >+ > #ifdef __cplusplus > } > #endif >diff --git a/Source/JavaScriptCore/API/tests/testapi.cpp b/Source/JavaScriptCore/API/tests/testapi.cpp >index 1cfd4c03a08bad422e94141885bc97c0e8d0eb66..9fcdd6264aad938f840f49e128054b225749f69f 100644 >--- a/Source/JavaScriptCore/API/tests/testapi.cpp >+++ b/Source/JavaScriptCore/API/tests/testapi.cpp >@@ -137,6 +137,7 @@ public: > void symbolsDeletePropertyForKey(); > void promiseResolveTrue(); > void promiseRejectTrue(); >+ void promiseRejectionCallbacks(); > > int failed() const { return m_failed; } > >@@ -454,7 +455,7 @@ void TestAPI::promiseResolveTrue() > > 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 +480,7 @@ void TestAPI::promiseRejectTrue() > > 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,8 +488,41 @@ void TestAPI::promiseRejectTrue() > > 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::promiseRejectionCallbacks() >+{ >+ JSObjectRef reject; >+ auto promise = JSObjectMakeDeferredPromise(context, nullptr, &reject, nullptr); >+ >+ static TestAPI* tester = this; >+ static auto handlerCallCount = 0; >+ >+ auto handler = [](JSContextRef ctx, JSObjectRef, JSObjectRef, size_t argumentCount, const JSValueRef arguments[], JSValueRef*) -> JSValueRef { >+ // This lambda isn't allowed to capture, so just check that we have a thenable object... >+ tester->check(argumentCount && JSObjectGetProperty(ctx, const_cast<JSObjectRef>(arguments[0]), APIString("then"), nullptr), "callback should get promise as first parameter"); >+ tester->check(argumentCount == 2 && JSValueIsStrictEqual(ctx, arguments[1], JSValueMakeBoolean(ctx, true)), "callback should get result as second parameter"); >+ handlerCallCount++; >+ return JSValueMakeUndefined(ctx); >+ }; >+ auto handlerFunction = JSObjectMakeFunctionWithCallback(context, APIString("handler"), handler); >+ >+ JSGlobalContextSetUnhandledRejectionCallback(context, handlerFunction); >+ >+ auto trueValue = JSValueMakeBoolean(context, true); >+ JSObjectCallAsFunction(context, reject, reject, 1, &trueValue, nullptr); >+ check(handlerCallCount == 1, "unhandled rejection callback should have been called"); >+ >+ auto noopFunction = JSObjectMakeFunction(context, APIString("noop"), 0, nullptr, APIString(""), nullptr, 1, nullptr); >+ >+ JSGlobalContextSetUnhandledRejectionCallback(context, noopFunction); >+ JSGlobalContextSetRejectionHandledCallback(context, handlerFunction); >+ >+ auto catchFunction = JSObjectGetProperty(context, promise, APIString("catch"), nullptr); >+ JSObjectCallAsFunction(context, const_cast<JSObjectRef>(catchFunction), promise, 1, &noopFunction, nullptr); >+ check(handlerCallCount == 2, "rejection handled callback should have been called"); > } > > #define RUN(test) do { \ >@@ -521,6 +555,7 @@ int testCAPIViaCpp(const char* filter) > RUN(symbolsDeletePropertyForKey()); > RUN(promiseResolveTrue()); > RUN(promiseRejectTrue()); >+ RUN(promiseRejectionCallbacks()); > > if (tasks.isEmpty()) { > dataLogLn("Filtered all tests: ERROR"); >diff --git a/Source/JavaScriptCore/jsc.cpp b/Source/JavaScriptCore/jsc.cpp >index d4fa222c721cf4a7e71ad4786f984111241e1852..0ac85413536335686e99c8f383e9fd15ed7fead0 100644 >--- a/Source/JavaScriptCore/jsc.cpp >+++ b/Source/JavaScriptCore/jsc.cpp >@@ -377,6 +377,9 @@ static EncodedJSValue JSC_HOST_CALL functionDisableRichSourceInfo(ExecState*); > static EncodedJSValue JSC_HOST_CALL functionMallocInALoop(ExecState*); > static EncodedJSValue JSC_HOST_CALL functionTotalCompileTime(ExecState*); > >+static EncodedJSValue JSC_HOST_CALL functionSetUnhandledRejectionCallback(ExecState*); >+static EncodedJSValue JSC_HOST_CALL functionSetRejectionHandledCallback(ExecState*); >+ > struct Script { > enum class StrictMode { > Strict, >@@ -631,6 +634,9 @@ protected: > addFunction(vm, "disableRichSourceInfo", functionDisableRichSourceInfo, 0); > addFunction(vm, "mallocInALoop", functionMallocInALoop, 0); > addFunction(vm, "totalCompileTime", functionTotalCompileTime, 0); >+ >+ addFunction(vm, "setUnhandledRejectionCallback", functionSetUnhandledRejectionCallback, 1); >+ addFunction(vm, "setRejectionHandledCallback", functionSetRejectionHandledCallback, 1); > } > > void addFunction(VM& vm, JSObject* object, const char* name, NativeFunction function, unsigned arguments) >@@ -2383,6 +2389,32 @@ static EncodedJSValue JSC_HOST_CALL functionWebAssemblyMemoryMode(ExecState* exe > > #endif // ENABLE(WEBASSEMBLY) > >+EncodedJSValue JSC_HOST_CALL functionSetUnhandledRejectionCallback(ExecState* exec) >+{ >+ VM& vm = exec->vm(); >+ JSValue value = exec->argument(0); >+ auto scope = DECLARE_THROW_SCOPE(vm); >+ >+ if (!value.isFunction(vm)) >+ return JSValue::encode(throwTypeError(exec, scope)); >+ >+ exec->lexicalGlobalObject()->setUnhandledRejectionCallback(vm, jsDynamicCast<JSFunction*>(vm, value)); >+ return JSValue::encode(jsUndefined()); >+} >+ >+EncodedJSValue JSC_HOST_CALL functionSetRejectionHandledCallback(ExecState* exec) >+{ >+ VM& vm = exec->vm(); >+ JSValue value = exec->argument(0); >+ auto scope = DECLARE_THROW_SCOPE(vm); >+ >+ if (!value.isFunction(vm)) >+ return JSValue::encode(throwTypeError(exec, scope)); >+ >+ exec->lexicalGlobalObject()->setRejectionHandledCallback(vm, jsDynamicCast<JSFunction*>(vm, value)); >+ 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 >diff --git a/Source/JavaScriptCore/runtime/JSGlobalObject.h b/Source/JavaScriptCore/runtime/JSGlobalObject.h >index 02607c92748096b81399db4ebdec2e0b6bbc7974..7bfffb403cf010549245ae1d1cf06385df5898b7 100644 >--- a/Source/JavaScriptCore/runtime/JSGlobalObject.h >+++ b/Source/JavaScriptCore/runtime/JSGlobalObject.h >@@ -427,6 +427,9 @@ public: > > String m_name; > >+ Strong<JSFunction> m_unhandledRejectionCallback; >+ Strong<JSFunction> m_rejectionHandledCallback; >+ > Debugger* m_debugger; > > VM& m_vm; >@@ -807,6 +810,12 @@ public: > void setName(const String&); > const String& name() const { return m_name; } > >+ void setUnhandledRejectionCallback(VM& vm, JSFunction* function) { m_unhandledRejectionCallback.set(vm, function); } >+ JSFunction* unhandledRejectionCallback() const { return m_unhandledRejectionCallback.get(); } >+ >+ void setRejectionHandledCallback(VM& vm, JSFunction* function) { m_rejectionHandledCallback.set(vm, function); } >+ JSFunction* rejectionHandledCallback() const { return m_rejectionHandledCallback.get(); } >+ > JSObject* arrayBufferConstructor() const { return m_arrayBufferStructure.constructor(this); } > > JSObject* arrayBufferPrototype(ArrayBufferSharingMode sharingMode) const >diff --git a/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp b/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp >index 08114ca69606b0c32639c141ee8f86ff435eaa04..ac950c743b731d20b823f77b42a58c9be0a70850 100644 >--- a/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp >+++ b/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp >@@ -766,10 +766,12 @@ EncodedJSValue JSC_HOST_CALL globalFuncHostPromiseRejectionTracker(ExecState* ex > 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 (promise->inherits<JSInternalPromise>(vm)) > return JSValue::encode(jsUndefined()); > >- JSPromise* promise = jsCast<JSPromise*>(exec->argument(0)); > JSValue operationValue = exec->argument(1); > > ASSERT(operationValue.isNumber()); >@@ -777,8 +779,29 @@ EncodedJSValue JSC_HOST_CALL globalFuncHostPromiseRejectionTracker(ExecState* ex > ASSERT(operation == JSPromiseRejectionOperation::Reject || operation == JSPromiseRejectionOperation::Handle); > scope.assertNoException(); > >- globalObject->globalObjectMethodTable()->promiseRejectionTracker(globalObject, exec, promise, operation); >- RETURN_IF_EXCEPTION(scope, { }); >+ if (globalObject->globalObjectMethodTable()->promiseRejectionTracker) { >+ globalObject->globalObjectMethodTable()->promiseRejectionTracker(globalObject, exec, promise, operation); >+ RETURN_IF_EXCEPTION(scope, { }); >+ } else { >+ switch (operation) { >+ case JSPromiseRejectionOperation::Reject: >+ vm.m_aboutToBeNotifiedRejectedPromises.constructAndAppend(vm, promise); >+ break; >+ case JSPromiseRejectionOperation::Handle: { >+ bool removed = vm.m_aboutToBeNotifiedRejectedPromises.removeFirstMatching([&] (Strong<JSPromise>& unhandledPromise) { >+ return unhandledPromise.get() == promise; >+ }); >+ if (removed) >+ break; >+ >+ if (!vm.m_outstandingRejectedPromises.remove(promise)) >+ break; >+ >+ vm.m_lateHandledRejectedPromises.constructAndAppend(vm, promise); >+ break; >+ } >+ } >+ } > > return JSValue::encode(jsUndefined()); > } >diff --git a/Source/JavaScriptCore/runtime/VM.cpp b/Source/JavaScriptCore/runtime/VM.cpp >index 25ef945cbe5a7445c2ca7ce0626c2f9884a7c210..91357232720bc1e7d7915954e1d33c8792f8675f 100644 >--- a/Source/JavaScriptCore/runtime/VM.cpp >+++ b/Source/JavaScriptCore/runtime/VM.cpp >@@ -305,6 +305,7 @@ VM::VM(VMType vmType, HeapType heapType) > , entryScope(0) > , m_regExpCache(new RegExpCache(this)) > , m_compactVariableMap(adoptRef(*(new CompactVariableMap))) >+ , m_outstandingRejectedPromises(*this) > #if ENABLE(REGEXP_TRACING) > , m_rtTraceList(new RTTraceList()) > #endif >@@ -1089,13 +1090,52 @@ void VM::queueMicrotask(JSGlobalObject& globalObject, Ref<Microtask>&& task) > m_microtaskQueue.append(std::make_unique<QueuedTask>(*this, &globalObject, WTFMove(task))); > } > >-void VM::drainMicrotasks() >+inline void VM::callPromiseRejectionCallback(JSFunction* callback, Strong<JSPromise>& promise) >+{ >+ 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(); >+} >+ >+inline void VM::didExhaustMicrotaskQueue() > { >- while (!m_microtaskQueue.isEmpty()) { >- m_microtaskQueue.takeFirst()->run(); >- if (m_onEachMicrotaskTick) >- m_onEachMicrotaskTick(*this); >+ auto lateHandledRejections = WTFMove(m_lateHandledRejectedPromises); >+ for (auto& promise : lateHandledRejections) >+ callPromiseRejectionCallback(promise->globalObject()->rejectionHandledCallback(), promise); >+ >+ auto unhandledRejections = WTFMove(m_aboutToBeNotifiedRejectedPromises); >+ for (auto& promise : unhandledRejections) { >+ if (promise->isHandled(*this)) >+ continue; >+ >+ callPromiseRejectionCallback(promise->globalObject()->unhandledRejectionCallback(), promise); >+ >+ if (!promise->isHandled(*this)) >+ m_outstandingRejectedPromises.set(promise.get(), promise.get()); > } >+} >+ >+void VM::drainMicrotasks() >+{ >+ do { >+ while (!m_microtaskQueue.isEmpty()) { >+ m_microtaskQueue.takeFirst()->run(); >+ if (m_onEachMicrotaskTick) >+ m_onEachMicrotaskTick(*this); >+ } >+ didExhaustMicrotaskQueue(); >+ } while (!m_microtaskQueue.isEmpty()); > finalizeSynchronousJSExecution(); > } > >diff --git a/Source/JavaScriptCore/runtime/VM.h b/Source/JavaScriptCore/runtime/VM.h >index 901497b2944369eead740e7510e986798f2c677f..74c888353ae04fa9ee7c55082867f7928b80e1da 100644 >--- a/Source/JavaScriptCore/runtime/VM.h >+++ b/Source/JavaScriptCore/runtime/VM.h >@@ -121,8 +121,10 @@ class Identifier; > class Interpreter; > class JSCustomGetterSetterFunction; > class JSDestructibleObjectHeapCellType; >+class JSFunction; > class JSGlobalObject; > class JSObject; >+class JSPromise; > class JSRunLoopTimer; > class JSStringHeapCellType; > class JSWebAssemblyCodeBlockHeapCellType; >@@ -828,6 +830,10 @@ public: > ALWAYS_INLINE HasOwnPropertyCache* hasOwnPropertyCache() { return m_hasOwnPropertyCache.get(); } > HasOwnPropertyCache* ensureHasOwnPropertyCache(); > >+ Vector<Strong<JSPromise>> m_aboutToBeNotifiedRejectedPromises; >+ Vector<Strong<JSPromise>> m_lateHandledRejectedPromises; >+ WeakGCMap<JSPromise*, JSPromise> m_outstandingRejectedPromises; >+ > #if ENABLE(REGEXP_TRACING) > typedef ListHashSet<RegExp*> RTTraceList; > RTTraceList* m_rtTraceList; >@@ -1005,6 +1011,9 @@ private: > static void primitiveGigacageDisabledCallback(void*); > void primitiveGigacageDisabled(); > >+ void callPromiseRejectionCallback(JSFunction*, Strong<JSPromise>&); >+ void didExhaustMicrotaskQueue(); >+ > #if ENABLE(GC_VALIDATION) > const ClassInfo* m_initializingObjectClass; > #endif >diff --git a/Source/WebCore/bindings/js/JSDOMGlobalObject.cpp b/Source/WebCore/bindings/js/JSDOMGlobalObject.cpp >index 788e2e677f7f20cd39d21712cf867460b56f5b4b..68d12ccdac8d67b2d81bfa5da39871d07260e1c5 100644 >--- a/Source/WebCore/bindings/js/JSDOMGlobalObject.cpp >+++ b/Source/WebCore/bindings/js/JSDOMGlobalObject.cpp >@@ -222,10 +222,6 @@ void JSDOMGlobalObject::promiseRejectionTracker(JSGlobalObject* jsGlobalObject, > 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 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 197172
:
369669
|
373561
|
373564
|
373962
|
374097
|
374102
|
375197
|
375965
|
376286
|
376833
|
376931
|
376949
|
377136