diff --git a/components/script/dom/bindings/import.rs b/components/script/dom/bindings/import.rs index 39e21f4b349..33511666d17 100644 --- a/components/script/dom/bindings/import.rs +++ b/components/script/dom/bindings/import.rs @@ -44,6 +44,7 @@ pub(crate) mod base { }; pub(crate) use crate::dom::globalscope::{GlobalScope, GlobalScopeHelpers}; pub(crate) use crate::dom::promise::PromiseHelpers; + pub(crate) use crate::realms::{AlreadyInRealm, InRealm}; pub(crate) use crate::script_runtime::{CanGc, JSContext as SafeJSContext}; } diff --git a/components/script/dom/bindings/iterable.rs b/components/script/dom/bindings/iterable.rs index 1a7be20b3da..d97dfeeddbe 100644 --- a/components/script/dom/bindings/iterable.rs +++ b/components/script/dom/bindings/iterable.rs @@ -30,6 +30,7 @@ use crate::dom::bindings::reflector::{ }; use crate::dom::bindings::root::{Dom, DomRoot, Root}; use crate::dom::bindings::trace::{JSTraceable, NoTrace, RootedTraceableBox}; +use crate::realms::InRealm; use crate::script_runtime::{CanGc, JSContext}; /// An iterator over the iterable entries of a given DOM interface. @@ -46,8 +47,8 @@ pub(crate) struct IterableIterator< } impl + JSTraceable + Iterable> IterableIterator { - pub fn global(&self) -> DomRoot { - >::global(self) + pub fn global_(&self, realm: InRealm) -> DomRoot { + >::global_(self, realm) } } @@ -70,7 +71,7 @@ impl + JSTraceable + Iterable + DomGlob IterableIterator { /// Create a new iterator instance for the provided iterable DOM interface. - pub(crate) fn new(iterable: &T, type_: IteratorType) -> DomRoot { + pub(crate) fn new(iterable: &T, type_: IteratorType, realm: InRealm) -> DomRoot { let iterator = Box::new(IterableIterator { reflector: Reflector::new(), type_, @@ -78,7 +79,7 @@ impl + JSTraceable + Iterable + DomGlob index: Cell::new(0), _marker: NoTrace(PhantomData), }); - reflect_dom_object(iterator, &*iterable.global(), CanGc::note()) + reflect_dom_object(iterator, &*iterable.global_(realm), CanGc::note()) } /// Return the next value from the iterable object. diff --git a/components/script/dom/bindings/reflector.rs b/components/script/dom/bindings/reflector.rs index 779a7a5bf81..3593578a66f 100644 --- a/components/script/dom/bindings/reflector.rs +++ b/components/script/dom/bindings/reflector.rs @@ -12,7 +12,7 @@ use crate::dom::bindings::iterable::{Iterable, IterableIterator}; use crate::dom::bindings::root::{Dom, DomRoot, Root}; use crate::dom::bindings::trace::JSTraceable; use crate::dom::globalscope::{GlobalScope, GlobalScopeHelpers}; -use crate::realms::AlreadyInRealm; +use crate::realms::{AlreadyInRealm, InRealm}; use crate::script_runtime::{CanGc, JSContext}; /// Create the reflector for a new DOM object and yield ownership to the @@ -43,6 +43,16 @@ where } pub(crate) trait DomGlobalGeneric: DomObject { + /// Returns the [`GlobalScope`] of the realm that the [`DomObject`] was created in. If this + /// object is a `Node`, this will be different from it's owning `Document` if adopted by. For + /// `Node`s it's almost always better to use `NodeTraits::owning_global`. + fn global_(&self, realm: InRealm) -> DomRoot + where + Self: Sized, + { + D::GlobalScope::from_reflector(self, realm) + } + /// Returns the [`GlobalScope`] of the realm that the [`DomObject`] was created in. If this /// object is a `Node`, this will be different from it's owning `Document` if adopted by. For /// `Node`s it's almost always better to use `NodeTraits::owning_global`. @@ -51,17 +61,21 @@ pub(crate) trait DomGlobalGeneric: DomObject { Self: Sized, { let realm = AlreadyInRealm::assert_for_cx(D::GlobalScope::get_cx()); - D::GlobalScope::from_reflector(self, &realm) + D::GlobalScope::from_reflector(self, InRealm::already(&realm)) } } impl DomGlobalGeneric for T {} pub(crate) trait DomGlobal { + fn global_(&self, realm: InRealm) -> DomRoot; fn global(&self) -> DomRoot; } impl> DomGlobal for T { + fn global_(&self, realm: InRealm) -> DomRoot { + >::global_(self, realm) + } fn global(&self) -> DomRoot { >::global(self) } diff --git a/components/script/dom/globalscope.rs b/components/script/dom/globalscope.rs index 88d56456686..c4625895f3a 100644 --- a/components/script/dom/globalscope.rs +++ b/components/script/dom/globalscope.rs @@ -2021,10 +2021,7 @@ impl GlobalScope { /// Returns the global scope of the realm that the given DOM object's reflector /// was created in. #[allow(unsafe_code)] - pub(crate) fn from_reflector( - reflector: &T, - _realm: &AlreadyInRealm, - ) -> DomRoot { + pub(crate) fn from_reflector(reflector: &T, _realm: InRealm) -> DomRoot { unsafe { GlobalScope::from_object(*reflector.reflector().get_jsobject()) } } @@ -3337,10 +3334,7 @@ pub(crate) trait GlobalScopeHelpers { unsafe fn from_context(cx: *mut JSContext, realm: InRealm) -> DomRoot; fn get_cx() -> SafeJSContext; unsafe fn from_object(obj: *mut JSObject) -> DomRoot; - fn from_reflector( - reflector: &impl DomObject, - realm: &AlreadyInRealm, - ) -> DomRoot; + fn from_reflector(reflector: &impl DomObject, realm: InRealm) -> DomRoot; unsafe fn from_object_maybe_wrapped( obj: *mut JSObject, @@ -3370,7 +3364,7 @@ impl GlobalScopeHelpers for GlobalScope { GlobalScope::from_object(obj) } - fn from_reflector(reflector: &impl DomObject, realm: &AlreadyInRealm) -> DomRoot { + fn from_reflector(reflector: &impl DomObject, realm: InRealm) -> DomRoot { GlobalScope::from_reflector(reflector, realm) } diff --git a/components/script/dom/promise.rs b/components/script/dom/promise.rs index b8d30bd3651..b970e7f3342 100644 --- a/components/script/dom/promise.rs +++ b/components/script/dom/promise.rs @@ -270,10 +270,10 @@ impl Promise { pub(crate) fn append_native_handler( &self, handler: &PromiseNativeHandler, - _comp: InRealm, + realm: InRealm, can_gc: CanGc, ) { - let _ais = AutoEntryScript::new(&handler.global()); + let _ais = AutoEntryScript::new(&handler.global_(realm)); let cx = GlobalScope::get_cx(); rooted!(in(*cx) let resolve_func = create_native_handler_function(*cx, diff --git a/components/script/realms.rs b/components/script/realms.rs index 9180a925382..434aa93a0a2 100644 --- a/components/script/realms.rs +++ b/components/script/realms.rs @@ -33,6 +33,18 @@ pub(crate) enum InRealm<'a> { Entered(&'a JSAutoRealm), } +impl<'a> From<&'a AlreadyInRealm> for InRealm<'a> { + fn from(token: &'a AlreadyInRealm) -> InRealm<'a> { + InRealm::already(token) + } +} + +impl<'a> From<&'a JSAutoRealm> for InRealm<'a> { + fn from(token: &'a JSAutoRealm) -> InRealm<'a> { + InRealm::entered(token) + } +} + impl InRealm<'_> { pub(crate) fn already(token: &AlreadyInRealm) -> InRealm { InRealm::Already(token) diff --git a/components/script_bindings/codegen/CodegenRust.py b/components/script_bindings/codegen/CodegenRust.py index adb9accf892..ba26ff95d2c 100644 --- a/components/script_bindings/codegen/CodegenRust.py +++ b/components/script_bindings/codegen/CodegenRust.py @@ -3960,7 +3960,7 @@ class CGCallGenerator(CGThing): if static: glob = "global.upcast::()" else: - glob = "&this.global()" + glob = "&this.global_(InRealm::already(&AlreadyInRealm::assert_for_cx(cx)))" self.cgRoot.append(CGGeneric( "let result = match result {\n" @@ -8454,7 +8454,8 @@ class CGIterableMethodGenerator(CGGeneric): return CGGeneric.__init__(self, fill( """ - let result = ${iterClass}::new(this, IteratorType::${itrMethod}); + let realm = AlreadyInRealm::assert_for_cx(cx); + let result = ${iterClass}::new(this, IteratorType::${itrMethod}, InRealm::already(&realm)); """, iterClass=iteratorNativeType(descriptor, True), ifaceName=descriptor.interface.identifier.name,