diff --git a/dom/promise/Promise.cpp b/dom/promise/Promise.cpp index 804bb77435a6..2124f8282e2a 100644 --- a/dom/promise/Promise.cpp +++ b/dom/promise/Promise.cpp @@ -865,11 +865,20 @@ Promise::RunTask() mResolveCallbacks.Clear(); mRejectCallbacks.Clear(); - ThreadsafeAutoJSContext cx; // Just for rooting. + ThreadsafeAutoJSContext cx; JS::Rooted value(cx, mResult); + JS::Rooted wrapper(cx, GetOrCreateWrapper(cx)); + if (!wrapper) { + return; + } + + JSAutoCompartment ac(cx, wrapper); + if (!MaybeWrapValue(cx, &value)) { + return; + } for (uint32_t i = 0; i < callbacks.Length(); ++i) { - callbacks[i]->Call(value); + callbacks[i]->Call(cx, value); } } diff --git a/dom/promise/PromiseCallback.cpp b/dom/promise/PromiseCallback.cpp index cb4caac63600..eeecc70ab846 100644 --- a/dom/promise/PromiseCallback.cpp +++ b/dom/promise/PromiseCallback.cpp @@ -82,19 +82,19 @@ ResolvePromiseCallback::~ResolvePromiseCallback() } void -ResolvePromiseCallback::Call(JS::Handle aValue) +ResolvePromiseCallback::Call(JSContext* aCx, + JS::Handle aValue) { // Run resolver's algorithm with value and the synchronous flag set. - ThreadsafeAutoSafeJSContext cx; - JSAutoCompartment ac(cx, mGlobal); - JS::Rooted value(cx, aValue); - if (!JS_WrapValue(cx, &value)) { + JSAutoCompartment ac(aCx, mGlobal); + JS::Rooted value(aCx, aValue); + if (!JS_WrapValue(aCx, &value)) { NS_WARNING("Failed to wrap value into the right compartment."); return; } - mPromise->ResolveInternal(cx, value, Promise::SyncTask); + mPromise->ResolveInternal(aCx, value, Promise::SyncTask); } // RejectPromiseCallback @@ -142,20 +142,20 @@ RejectPromiseCallback::~RejectPromiseCallback() } void -RejectPromiseCallback::Call(JS::Handle aValue) +RejectPromiseCallback::Call(JSContext* aCx, + JS::Handle aValue) { // Run resolver's algorithm with value and the synchronous flag set. - ThreadsafeAutoSafeJSContext cx; - JSAutoCompartment ac(cx, mGlobal); - JS::Rooted value(cx, aValue); - if (!JS_WrapValue(cx, &value)) { + JSAutoCompartment ac(aCx, mGlobal); + JS::Rooted value(aCx, aValue); + if (!JS_WrapValue(aCx, &value)) { NS_WARNING("Failed to wrap value into the right compartment."); return; } - mPromise->RejectInternal(cx, value, Promise::SyncTask); + mPromise->RejectInternal(aCx, value, Promise::SyncTask); } // WrapperPromiseCallback @@ -205,13 +205,12 @@ WrapperPromiseCallback::~WrapperPromiseCallback() } void -WrapperPromiseCallback::Call(JS::Handle aValue) +WrapperPromiseCallback::Call(JSContext* aCx, + JS::Handle aValue) { - ThreadsafeAutoSafeJSContext cx; - - JSAutoCompartment ac(cx, mGlobal); - JS::Rooted value(cx, aValue); - if (!JS_WrapValue(cx, &value)) { + JSAutoCompartment ac(aCx, mGlobal); + JS::Rooted value(aCx, aValue); + if (!JS_WrapValue(aCx, &value)) { NS_WARNING("Failed to wrap value into the right compartment."); return; } @@ -220,27 +219,27 @@ WrapperPromiseCallback::Call(JS::Handle aValue) // If invoking callback threw an exception, run resolver's reject with the // thrown exception as argument and the synchronous flag set. - JS::Rooted retValue(cx, + JS::Rooted retValue(aCx, mCallback->Call(value, rv, CallbackObject::eRethrowExceptions)); rv.WouldReportJSException(); if (rv.Failed() && rv.IsJSException()) { - JS::Rooted value(cx); - rv.StealJSException(cx, &value); + JS::Rooted value(aCx); + rv.StealJSException(aCx, &value); - if (!JS_WrapValue(cx, &value)) { + if (!JS_WrapValue(aCx, &value)) { NS_WARNING("Failed to wrap value into the right compartment."); return; } - mNextPromise->RejectInternal(cx, value, Promise::SyncTask); + mNextPromise->RejectInternal(aCx, value, Promise::SyncTask); return; } // If the return value is the same as the promise itself, throw TypeError. if (retValue.isObject()) { - JS::Rooted valueObj(cx, &retValue.toObject()); + JS::Rooted valueObj(aCx, &retValue.toObject()); Promise* returnedPromise; nsresult r = UNWRAP_OBJECT(Promise, valueObj, returnedPromise); @@ -250,63 +249,63 @@ WrapperPromiseCallback::Call(JS::Handle aValue) // Try to get some information about the callback to report a sane error, // but don't try too hard (only deals with scripted functions). - JS::Rooted unwrapped(cx, + JS::Rooted unwrapped(aCx, js::CheckedUnwrap(mCallback->Callback())); if (unwrapped) { - JSAutoCompartment ac(cx, unwrapped); - if (JS_ObjectIsFunction(cx, unwrapped)) { - JS::Rooted asValue(cx, JS::ObjectValue(*unwrapped)); - JS::Rooted func(cx, JS_ValueToFunction(cx, asValue)); + JSAutoCompartment ac(aCx, unwrapped); + if (JS_ObjectIsFunction(aCx, unwrapped)) { + JS::Rooted asValue(aCx, JS::ObjectValue(*unwrapped)); + JS::Rooted func(aCx, JS_ValueToFunction(aCx, asValue)); MOZ_ASSERT(func); - JSScript* script = JS_GetFunctionScript(cx, func); + JSScript* script = JS_GetFunctionScript(aCx, func); if (script) { fileName = JS_GetScriptFilename(script); - lineNumber = JS_GetScriptBaseLineNumber(cx, script); + lineNumber = JS_GetScriptBaseLineNumber(aCx, script); } } } // We're back in aValue's compartment here. - JS::Rooted stack(cx, JS_GetEmptyString(JS_GetRuntime(cx))); - JS::Rooted fn(cx, JS_NewStringCopyZ(cx, fileName)); + JS::Rooted stack(aCx, JS_GetEmptyString(JS_GetRuntime(aCx))); + JS::Rooted fn(aCx, JS_NewStringCopyZ(aCx, fileName)); if (!fn) { // Out of memory. Promise will stay unresolved. - JS_ClearPendingException(cx); + JS_ClearPendingException(aCx); return; } - JS::Rooted message(cx, - JS_NewStringCopyZ(cx, + JS::Rooted message(aCx, + JS_NewStringCopyZ(aCx, "then() cannot return same Promise that it resolves.")); if (!message) { // Out of memory. Promise will stay unresolved. - JS_ClearPendingException(cx); + JS_ClearPendingException(aCx); return; } - JS::Rooted typeError(cx); - if (!JS::CreateTypeError(cx, stack, fn, lineNumber, 0, + JS::Rooted typeError(aCx); + if (!JS::CreateTypeError(aCx, stack, fn, lineNumber, 0, nullptr, message, &typeError)) { // Out of memory. Promise will stay unresolved. - JS_ClearPendingException(cx); + JS_ClearPendingException(aCx); return; } - mNextPromise->RejectInternal(cx, typeError, Promise::SyncTask); + mNextPromise->RejectInternal(aCx, typeError, Promise::SyncTask); return; } } // Otherwise, run resolver's resolve with value and the synchronous flag // set. - if (!JS_WrapValue(cx, &retValue)) { + if (!JS_WrapValue(aCx, &retValue)) { NS_WARNING("Failed to wrap value into the right compartment."); return; } - mNextPromise->ResolveInternal(cx, retValue, Promise::SyncTask); + mNextPromise->ResolveInternal(aCx, retValue, Promise::SyncTask); } // NativePromiseCallback @@ -335,7 +334,8 @@ NativePromiseCallback::~NativePromiseCallback() } void -NativePromiseCallback::Call(JS::Handle aValue) +NativePromiseCallback::Call(JSContext* aCx, + JS::Handle aValue) { if (mState == Promise::Resolved) { mHandler->ResolvedCallback(aValue); diff --git a/dom/promise/PromiseCallback.h b/dom/promise/PromiseCallback.h index 4ef115b78ce7..1dfe1ca8dbc9 100644 --- a/dom/promise/PromiseCallback.h +++ b/dom/promise/PromiseCallback.h @@ -24,7 +24,8 @@ public: PromiseCallback(); virtual ~PromiseCallback(); - virtual void Call(JS::Handle aValue) = 0; + virtual void Call(JSContext* aCx, + JS::Handle aValue) = 0; enum Task { Resolve, @@ -47,7 +48,8 @@ public: NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(WrapperPromiseCallback, PromiseCallback) - void Call(JS::Handle aValue) MOZ_OVERRIDE; + void Call(JSContext* aCx, + JS::Handle aValue) MOZ_OVERRIDE; WrapperPromiseCallback(Promise* aNextPromise, JS::Handle aGlobal, AnyCallback* aCallback); @@ -68,7 +70,8 @@ public: NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(ResolvePromiseCallback, PromiseCallback) - void Call(JS::Handle aValue) MOZ_OVERRIDE; + void Call(JSContext* aCx, + JS::Handle aValue) MOZ_OVERRIDE; ResolvePromiseCallback(Promise* aPromise, JS::Handle aGlobal); ~ResolvePromiseCallback(); @@ -87,7 +90,8 @@ public: NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(RejectPromiseCallback, PromiseCallback) - void Call(JS::Handle aValue) MOZ_OVERRIDE; + void Call(JSContext* aCx, + JS::Handle aValue) MOZ_OVERRIDE; RejectPromiseCallback(Promise* aPromise, JS::Handle aGlobal); ~RejectPromiseCallback(); @@ -105,7 +109,8 @@ public: NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(NativePromiseCallback, PromiseCallback) - void Call(JS::Handle aValue) MOZ_OVERRIDE; + void Call(JSContext* aCx, + JS::Handle aValue) MOZ_OVERRIDE; NativePromiseCallback(PromiseNativeHandler* aHandler, Promise::PromiseState aState);