diff --git a/js/src/builtin/Promise.cpp b/js/src/builtin/Promise.cpp index 3048965b45a0..ec9b67434d52 100644 --- a/js/src/builtin/Promise.cpp +++ b/js/src/builtin/Promise.cpp @@ -1167,7 +1167,7 @@ RejectMaybeWrappedPromise(JSContext *cx, HandleObject promiseObj, HandleValue re // floor. RootedObject realReason(cx, UncheckedUnwrap(&reason.toObject())); RootedValue realReasonVal(cx, ObjectValue(*realReason)); - RootedObject realGlobal(cx, &realReason->nonCCWGlobal()); + Rooted realGlobal(cx, &realReason->nonCCWGlobal()); ReportErrorToGlobal(cx, realGlobal, realReasonVal); // Async stacks are only properly adopted if there's at least one diff --git a/js/src/ctypes/CTypes.cpp b/js/src/ctypes/CTypes.cpp index 9235afe93a8b..27f5df2055a9 100644 --- a/js/src/ctypes/CTypes.cpp +++ b/js/src/ctypes/CTypes.cpp @@ -7511,9 +7511,13 @@ CClosure::ClosureStub(ffi_cif* cif, void* result, void** args, void* userData) // Retrieve the essentials from our closure object. ArgClosure argClosure(cif, result, args, static_cast(userData)); JSContext* cx = argClosure.cinfo->cx; - RootedObject fun(cx, argClosure.cinfo->jsfnObj); - js::PrepareScriptEnvironmentAndInvoke(cx, fun, argClosure); + js::AssertSameCompartment(cx, argClosure.cinfo->jsfnObj); + + RootedObject global(cx, JS::CurrentGlobalOrNull(cx)); + MOZ_ASSERT(global); + + js::PrepareScriptEnvironmentAndInvoke(cx, global, argClosure); } bool CClosure::ArgClosure::operator()(JSContext* cx) diff --git a/js/src/jsfriendapi.cpp b/js/src/jsfriendapi.cpp index 122da5a4bb1d..ead188c87365 100644 --- a/js/src/jsfriendapi.cpp +++ b/js/src/jsfriendapi.cpp @@ -1405,14 +1405,16 @@ js::detail::IdMatchesAtom(jsid id, JSString* atom) } JS_FRIEND_API(void) -js::PrepareScriptEnvironmentAndInvoke(JSContext* cx, HandleObject scope, ScriptEnvironmentPreparer::Closure& closure) +js::PrepareScriptEnvironmentAndInvoke(JSContext* cx, HandleObject global, + ScriptEnvironmentPreparer::Closure& closure) { MOZ_ASSERT(!cx->isExceptionPending()); + MOZ_ASSERT(global->is()); MOZ_RELEASE_ASSERT(cx->runtime()->scriptEnvironmentPreparer, "Embedding needs to set a scriptEnvironmentPreparer callback"); - cx->runtime()->scriptEnvironmentPreparer->invoke(scope, closure); + cx->runtime()->scriptEnvironmentPreparer->invoke(global, closure); } JS_FRIEND_API(void) diff --git a/js/src/jsfriendapi.h b/js/src/jsfriendapi.h index 9e5b6c785f38..2706cd30fcd8 100644 --- a/js/src/jsfriendapi.h +++ b/js/src/jsfriendapi.h @@ -2734,20 +2734,15 @@ IdToValue(jsid id) } /** - * If the embedder has registered a ScriptEnvironmentPreparer, - * PrepareScriptEnvironmentAndInvoke will call the preparer's 'invoke' method + * PrepareScriptEnvironmentAndInvoke asserts the embedder has registered a + * ScriptEnvironmentPreparer and then it calls the preparer's 'invoke' method * with the given |closure|, with the assumption that the preparer will set up - * any state necessary to run script in |scope|, invoke |closure| with a valid + * any state necessary to run script in |global|, invoke |closure| with a valid * JSContext*, report any exceptions thrown from the closure, and return. * - * If no preparer is registered, PrepareScriptEnvironmentAndInvoke will assert - * that |rt| has exactly one JSContext associated with it, enter the compartment - * of |scope| on that context, and invoke |closure|. - * - * In both cases, PrepareScriptEnvironmentAndInvoke will report any exceptions - * that are thrown by the closure. Consumers who want to propagate back - * whether the closure succeeded should do so via members of the closure - * itself. + * PrepareScriptEnvironmentAndInvoke will report any exceptions that are thrown + * by the closure. Consumers who want to propagate back whether the closure + * succeeded should do so via members of the closure itself. */ struct ScriptEnvironmentPreparer { @@ -2755,11 +2750,11 @@ struct ScriptEnvironmentPreparer { virtual bool operator()(JSContext* cx) = 0; }; - virtual void invoke(JS::HandleObject scope, Closure& closure) = 0; + virtual void invoke(JS::HandleObject global, Closure& closure) = 0; }; extern JS_FRIEND_API(void) -PrepareScriptEnvironmentAndInvoke(JSContext* cx, JS::HandleObject scope, +PrepareScriptEnvironmentAndInvoke(JSContext* cx, JS::HandleObject global, ScriptEnvironmentPreparer::Closure& closure); JS_FRIEND_API(void) diff --git a/js/src/shell/js.cpp b/js/src/shell/js.cpp index 18d071aa1c5a..dec0ea71bbba 100644 --- a/js/src/shell/js.cpp +++ b/js/src/shell/js.cpp @@ -479,7 +479,7 @@ struct MOZ_STACK_CLASS EnvironmentPreparer : public js::ScriptEnvironmentPrepare { js::SetScriptEnvironmentPreparer(cx, this); } - void invoke(JS::HandleObject scope, Closure& closure) override; + void invoke(JS::HandleObject global, Closure& closure) override; }; // Shell state set once at startup. @@ -796,12 +796,14 @@ SkipUTF8BOM(FILE* file) } void -EnvironmentPreparer::invoke(HandleObject scope, Closure& closure) +EnvironmentPreparer::invoke(HandleObject global, Closure& closure) { + MOZ_ASSERT(JS_IsGlobalObject(global)); + JSContext* cx = TlsContext.get(); MOZ_ASSERT(!JS_IsExceptionPending(cx)); - AutoRealm ar(cx, scope); + AutoRealm ar(cx, global); AutoReportException are(cx); if (!closure(cx)) return; diff --git a/js/src/vm/ErrorReporting.cpp b/js/src/vm/ErrorReporting.cpp index 56490b6bf7c9..adb793722199 100644 --- a/js/src/vm/ErrorReporting.cpp +++ b/js/src/vm/ErrorReporting.cpp @@ -147,7 +147,7 @@ class MOZ_STACK_CLASS ReportExceptionClosure } // anonymous namespace void -js::ReportErrorToGlobal(JSContext* cx, HandleObject global, HandleValue error) +js::ReportErrorToGlobal(JSContext* cx, Handle global, HandleValue error) { MOZ_ASSERT(!cx->isExceptionPending()); #ifdef DEBUG diff --git a/js/src/vm/ErrorReporting.h b/js/src/vm/ErrorReporting.h index 836edea641b1..5d792b424f11 100644 --- a/js/src/vm/ErrorReporting.h +++ b/js/src/vm/ErrorReporting.h @@ -92,13 +92,15 @@ extern MOZ_MUST_USE bool ReportCompileWarning(JSContext* cx, ErrorMetadata&& metadata, UniquePtr notes, unsigned flags, unsigned errorNumber, va_list args); +class GlobalObject; + /** * Report the given error Value to the given global. The JSContext is not - * assumed to be in any particular compartment, but the global and error are + * assumed to be in any particular realm, but the global and error are * expected to be same-compartment. */ extern void -ReportErrorToGlobal(JSContext* cx, JS::HandleObject global, JS::HandleValue error); +ReportErrorToGlobal(JSContext* cx, JS::Handle global, JS::HandleValue error); } // namespace js diff --git a/xpcom/base/CycleCollectedJSRuntime.cpp b/xpcom/base/CycleCollectedJSRuntime.cpp index a5916dfe81b3..9a7926a3acc2 100644 --- a/xpcom/base/CycleCollectedJSRuntime.cpp +++ b/xpcom/base/CycleCollectedJSRuntime.cpp @@ -1549,15 +1549,16 @@ CycleCollectedJSRuntime::PrepareWaitingZonesForGC() } void -CycleCollectedJSRuntime::EnvironmentPreparer::invoke(JS::HandleObject scope, +CycleCollectedJSRuntime::EnvironmentPreparer::invoke(JS::HandleObject global, js::ScriptEnvironmentPreparer::Closure& closure) { - nsIGlobalObject* global = xpc::NativeGlobal(scope); + MOZ_ASSERT(JS_IsGlobalObject(global)); + nsIGlobalObject* nativeGlobal = xpc::NativeGlobal(global); // Not much we can do if we simply don't have a usable global here... - NS_ENSURE_TRUE_VOID(global && global->GetGlobalJSObject()); + NS_ENSURE_TRUE_VOID(nativeGlobal && nativeGlobal->GetGlobalJSObject()); - AutoEntryScript aes(global, "JS-engine-initiated execution"); + AutoEntryScript aes(nativeGlobal, "JS-engine-initiated execution"); MOZ_ASSERT(!JS_IsExceptionPending(aes.cx())); diff --git a/xpcom/base/CycleCollectedJSRuntime.h b/xpcom/base/CycleCollectedJSRuntime.h index 06e8749679d6..87512846b6a1 100644 --- a/xpcom/base/CycleCollectedJSRuntime.h +++ b/xpcom/base/CycleCollectedJSRuntime.h @@ -368,7 +368,7 @@ private: nsTHashtable> mZonesWaitingForGC; struct EnvironmentPreparer : public js::ScriptEnvironmentPreparer { - void invoke(JS::HandleObject scope, Closure& closure) override; + void invoke(JS::HandleObject global, Closure& closure) override; }; EnvironmentPreparer mEnvironmentPreparer;