diff --git a/js/rust/build.rs b/js/rust/build.rs index 29e21dbfddef..3223d366534a 100644 --- a/js/rust/build.rs +++ b/js/rust/build.rs @@ -170,7 +170,7 @@ const WHITELIST_TYPES: &'static [&'static str] = &[ "JS::HandleValue", "JS::HandleValueArray", "JS::IsAcceptableThis", - "JSAutoRealmAllowCCW", + "JSAutoRealm", "JSAutoStructuredCloneBuffer", "JSClass", "JSClassOps", diff --git a/js/rust/src/ar.rs b/js/rust/src/ar.rs index b79bb739f345..d65fbe59092b 100644 --- a/js/rust/src/ar.rs +++ b/js/rust/src/ar.rs @@ -3,7 +3,7 @@ use jsapi::root::*; use std::ptr; #[derive(Debug)] -pub struct AutoRealm(JSAutoRealmAllowCCW); +pub struct AutoRealm(JSAutoRealm); impl AutoRealm { #[cfg(feature = "debugmozjs")] @@ -16,7 +16,7 @@ impl AutoRealm { }; AutoRealm( - JSAutoRealmAllowCCW::new( + JSAutoRealm::new( cx, target, &mut notifier as *mut _)) @@ -27,7 +27,7 @@ impl AutoRealm { target: *mut JSObject) -> AutoRealm { - AutoRealm(JSAutoRealmAllowCCW::new(cx, target)) + AutoRealm(JSAutoRealm::new(cx, target)) } #[cfg(feature = "debugmozjs")] @@ -40,7 +40,7 @@ impl AutoRealm { }; AutoRealm( - JSAutoRealmAllowCCW::new1( + JSAutoRealm::new1( cx, target, &mut notifier as *mut _)) @@ -51,6 +51,6 @@ impl AutoRealm { target: *mut JSScript) -> AutoRealm { - AutoRealm(JSAutoRealmAllowCCW::new1(cx, target)) + AutoRealm(JSAutoRealm::new1(cx, target)) } } diff --git a/js/rust/src/rust.rs b/js/rust/src/rust.rs index b8ba11e383a1..c285fcf8a55e 100644 --- a/js/rust/src/rust.rs +++ b/js/rust/src/rust.rs @@ -620,7 +620,7 @@ impl GCMethods for JS::Value { // ___________________________________________________________________________ // Implementations for various things in jsapi.rs -impl Drop for JSAutoRealmAllowCCW { +impl Drop for JSAutoRealm { fn drop(&mut self) { unsafe { JS::LeaveRealm(self.cx_, self.oldRealm_); } } diff --git a/js/src/devtools/rootAnalysis/annotations.js b/js/src/devtools/rootAnalysis/annotations.js index 7f9e82b5bd56..c3c55dc907e5 100644 --- a/js/src/devtools/rootAnalysis/annotations.js +++ b/js/src/devtools/rootAnalysis/annotations.js @@ -198,11 +198,6 @@ var ignoreFunctions = { // FIXME! "NS_DebugBreak": true, - // These are a little overzealous -- these destructors *can* GC if they end - // up wrapping a pending exception. See bug 898815 for the heavyweight fix. - "void js::AutoRealm::~AutoRealm(int32)" : true, - "void JSAutoRealmAllowCCW::~JSAutoRealmAllowCCW(int32)" : true, - // Similar to heap snapshot mock classes, and GTests below. This posts a // synchronous runnable when a GTest fails, and we are pretty sure that the // particular runnable it posts can't even GC, but the analysis isn't diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index 1cea7c605f9e..04e84f7584df 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -691,6 +691,8 @@ JS::EnterRealm(JSContext* cx, JSObject* target) AssertHeapIsIdle(); CHECK_REQUEST(cx); + MOZ_DIAGNOSTIC_ASSERT(!js::IsCrossCompartmentWrapper(target)); + Realm* oldRealm = cx->realm(); cx->enterRealmOf(target); return oldRealm; @@ -704,44 +706,30 @@ JS::LeaveRealm(JSContext* cx, JS::Realm* oldRealm) cx->leaveRealm(oldRealm); } -JSAutoRealmAllowCCW::JSAutoRealmAllowCCW(JSContext* cx, JSObject* target - MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL) - : cx_(cx), - oldRealm_(cx->realm()) -{ - AssertHeapIsIdleOrIterating(); - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - cx_->enterRealmOf(target); -} - -JSAutoRealmAllowCCW::JSAutoRealmAllowCCW(JSContext* cx, JSScript* target - MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL) - : cx_(cx), - oldRealm_(cx->realm()) -{ - AssertHeapIsIdleOrIterating(); - MOZ_GUARD_OBJECT_NOTIFIER_INIT; - cx_->enterRealmOf(target); -} - -JSAutoRealmAllowCCW::~JSAutoRealmAllowCCW() -{ - cx_->leaveRealm(oldRealm_); -} - JSAutoRealm::JSAutoRealm(JSContext* cx, JSObject* target MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL) - : JSAutoRealmAllowCCW(cx, target) + : cx_(cx), + oldRealm_(cx->realm()) { MOZ_GUARD_OBJECT_NOTIFIER_INIT; MOZ_DIAGNOSTIC_ASSERT(!js::IsCrossCompartmentWrapper(target)); + AssertHeapIsIdleOrIterating(); + cx_->enterRealmOf(target); } JSAutoRealm::JSAutoRealm(JSContext* cx, JSScript* target MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL) - : JSAutoRealmAllowCCW(cx, target) + : cx_(cx), + oldRealm_(cx->realm()) { MOZ_GUARD_OBJECT_NOTIFIER_INIT; + AssertHeapIsIdleOrIterating(); + cx_->enterRealmOf(target); +} + +JSAutoRealm::~JSAutoRealm() +{ + cx_->leaveRealm(oldRealm_); } JSAutoNullableRealm::JSAutoNullableRealm(JSContext* cx, @@ -750,12 +738,14 @@ JSAutoNullableRealm::JSAutoNullableRealm(JSContext* cx, : cx_(cx), oldRealm_(cx->realm()) { - AssertHeapIsIdleOrIterating(); MOZ_GUARD_OBJECT_NOTIFIER_INIT; - if (targetOrNull) + AssertHeapIsIdleOrIterating(); + if (targetOrNull) { + MOZ_DIAGNOSTIC_ASSERT(!js::IsCrossCompartmentWrapper(targetOrNull)); cx_->enterRealmOf(targetOrNull); - else + } else { cx_->enterNullRealm(); + } } JSAutoNullableRealm::~JSAutoNullableRealm() diff --git a/js/src/jsapi.h b/js/src/jsapi.h index 3697499308ee..d6052e23701a 100644 --- a/js/src/jsapi.h +++ b/js/src/jsapi.h @@ -858,10 +858,13 @@ JS_RefreshCrossCompartmentWrappers(JSContext* cx, JS::Handle obj); * { * JSAutoRealm ar(cx, obj); // constructor enters * // in the realm of 'obj' - * } // destructor leaves + * } // destructor leaves * // back in realm 'r' * } * + * The object passed to JSAutoRealm must *not* be a cross-compartment wrapper, + * because CCWs are not associated with a single realm. + * * For more complicated uses that don't neatly fit in a C++ stack frame, the * realm can be entered and left using separate function calls: * @@ -882,27 +885,14 @@ JS_RefreshCrossCompartmentWrappers(JSContext* cx, JS::Handle obj); * the JSAutoRealm. */ -// JSAutoRealmAllowCCW is deprecated and will be removed soon, because entering -// the realm of a CCW doesn't make sense when CCWs are shared by all realms in -// the compartment. New code should prefer JSAutoRealm below instead (it asserts -// the object is not a CCW). -class MOZ_RAII JS_PUBLIC_API(JSAutoRealmAllowCCW) +class MOZ_RAII JS_PUBLIC_API(JSAutoRealm) { JSContext* cx_; JS::Realm* oldRealm_; - public: - JSAutoRealmAllowCCW(JSContext* cx, JSObject* target MOZ_GUARD_OBJECT_NOTIFIER_PARAM); - JSAutoRealmAllowCCW(JSContext* cx, JSScript* target MOZ_GUARD_OBJECT_NOTIFIER_PARAM); - ~JSAutoRealmAllowCCW(); - - MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER -}; - -class MOZ_RAII JS_PUBLIC_API(JSAutoRealm) : public JSAutoRealmAllowCCW -{ public: JSAutoRealm(JSContext* cx, JSObject* target MOZ_GUARD_OBJECT_NOTIFIER_PARAM); JSAutoRealm(JSContext* cx, JSScript* target MOZ_GUARD_OBJECT_NOTIFIER_PARAM); + ~JSAutoRealm(); MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER }; @@ -922,6 +912,9 @@ class MOZ_RAII JS_PUBLIC_API(JSAutoNullableRealm) namespace JS { /** NB: This API is infallible; a nullptr return value does not indicate error. + * + * |target| must not be a cross-compartment wrapper because CCWs are not + * associated with a single realm. * * Entering a realm roots the realm and its global object until the matching * JS::LeaveRealm() call.