diff --git a/components/script/body.rs b/components/script/body.rs index b7436c3e5e0..8ac94d09a1e 100644 --- a/components/script/body.rs +++ b/components/script/body.rs @@ -718,10 +718,8 @@ impl Callback for ConsumeBodyPromiseHandler { // https://fetch.spec.whatwg.org/#concept-body-consume-body #[allow(unrooted_must_root)] pub fn consume_body(object: &T, body_type: BodyType) -> Rc { - let global = object.global(); - let in_realm_proof = AlreadyInRealm::assert(&global); - let promise = - Promise::new_in_current_realm(&object.global(), InRealm::Already(&in_realm_proof)); + let in_realm_proof = AlreadyInRealm::assert(); + let promise = Promise::new_in_current_realm(InRealm::Already(&in_realm_proof)); // Step 1 if object.is_disturbed() || object.is_locked() { diff --git a/components/script/devtools.rs b/components/script/devtools.rs index fbc3ca58e58..8ff911a6b78 100644 --- a/components/script/devtools.rs +++ b/components/script/devtools.rs @@ -33,7 +33,7 @@ use uuid::Uuid; pub fn handle_evaluate_js(global: &GlobalScope, eval: String, reply: IpcSender) { // global.get_cx() returns a valid `JSContext` pointer, so this is safe. let result = unsafe { - let cx = global.get_cx(); + let cx = GlobalScope::get_cx(); let _ac = enter_realm(global); rooted!(in(*cx) let mut rval = UndefinedValue()); let source_code = SourceCode::Text(Rc::new(DOMString::from_string(eval))); diff --git a/components/script/dom/abstractworkerglobalscope.rs b/components/script/dom/abstractworkerglobalscope.rs index ca994c1c694..a1cab9aca2d 100644 --- a/components/script/dom/abstractworkerglobalscope.rs +++ b/components/script/dom/abstractworkerglobalscope.rs @@ -9,6 +9,7 @@ use crate::dom::dedicatedworkerglobalscope::{AutoWorkerReset, DedicatedWorkerScr use crate::dom::globalscope::GlobalScope; use crate::dom::worker::TrustedWorkerAddress; use crate::dom::workerglobalscope::WorkerGlobalScope; +use crate::realms::enter_realm; use crate::script_runtime::{CommonScriptMsg, ScriptChan, ScriptPort}; use crate::task_queue::{QueuedTaskConversion, TaskQueue}; use crossbeam_channel::{Receiver, Sender}; @@ -140,6 +141,7 @@ pub fn run_worker_event_loop( } // Step 3 for event in sequential { + let _realm = enter_realm(&*worker_scope); if !worker_scope.handle_event(event) { // Shutdown return; diff --git a/components/script/dom/audiobuffer.rs b/components/script/dom/audiobuffer.rs index ade645827a6..268424d1c4b 100644 --- a/components/script/dom/audiobuffer.rs +++ b/components/script/dom/audiobuffer.rs @@ -9,8 +9,9 @@ use crate::dom::bindings::codegen::Bindings::AudioBufferBinding::{ }; use crate::dom::bindings::error::{Error, Fallible}; use crate::dom::bindings::num::Finite; -use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector}; +use crate::dom::bindings::reflector::{reflect_dom_object, Reflector}; use crate::dom::bindings::root::DomRoot; +use crate::dom::globalscope::GlobalScope; use crate::dom::window::Window; use crate::realms::enter_realm; use crate::script_runtime::JSContext; @@ -172,7 +173,7 @@ impl AudioBuffer { self.length as usize, self.sample_rate, ); - let cx = self.global().get_cx(); + let cx = GlobalScope::get_cx(); for (i, channel) in self.js_channels.borrow_mut().iter().enumerate() { // Step 1. if channel.get().is_null() { @@ -271,7 +272,7 @@ impl AudioBufferMethods for AudioBuffer { } let bytes_to_copy = min(self.length - start_in_channel, destination.len() as u32) as usize; - let cx = self.global().get_cx(); + let cx = GlobalScope::get_cx(); let channel_number = channel_number as usize; let offset = start_in_channel as usize; let mut dest = Vec::with_capacity(destination.len()); @@ -313,7 +314,7 @@ impl AudioBufferMethods for AudioBuffer { return Err(Error::IndexSize); } - let cx = self.global().get_cx(); + let cx = GlobalScope::get_cx(); if !self.restore_js_channel_data(cx) { return Err(Error::JSFailed); } diff --git a/components/script/dom/audiocontext.rs b/components/script/dom/audiocontext.rs index 9a5160773f9..4f0d10285fa 100644 --- a/components/script/dom/audiocontext.rs +++ b/components/script/dom/audiocontext.rs @@ -132,7 +132,7 @@ impl AudioContextMethods for AudioContext { // https://webaudio.github.io/web-audio-api/#dom-audiocontext-suspend fn Suspend(&self, comp: InRealm) -> Rc { // Step 1. - let promise = Promise::new_in_current_realm(&self.global(), comp); + let promise = Promise::new_in_current_realm(comp); // Step 2. if self.context.control_thread_state() == ProcessingState::Closed { @@ -193,7 +193,7 @@ impl AudioContextMethods for AudioContext { // https://webaudio.github.io/web-audio-api/#dom-audiocontext-close fn Close(&self, comp: InRealm) -> Rc { // Step 1. - let promise = Promise::new_in_current_realm(&self.global(), comp); + let promise = Promise::new_in_current_realm(comp); // Step 2. if self.context.control_thread_state() == ProcessingState::Closed { diff --git a/components/script/dom/baseaudiocontext.rs b/components/script/dom/baseaudiocontext.rs index 42836dd61f0..ec7fcfc328e 100644 --- a/components/script/dom/baseaudiocontext.rs +++ b/components/script/dom/baseaudiocontext.rs @@ -284,7 +284,7 @@ impl BaseAudioContextMethods for BaseAudioContext { /// https://webaudio.github.io/web-audio-api/#dom-baseaudiocontext-resume fn Resume(&self, comp: InRealm) -> Rc { // Step 1. - let promise = Promise::new_in_current_realm(&self.global(), comp); + let promise = Promise::new_in_current_realm(comp); // Step 2. if self.audio_context_impl.lock().unwrap().state() == ProcessingState::Closed { @@ -440,7 +440,7 @@ impl BaseAudioContextMethods for BaseAudioContext { comp: InRealm, ) -> Rc { // Step 1. - let promise = Promise::new_in_current_realm(&self.global(), comp); + let promise = Promise::new_in_current_realm(comp); let global = self.global(); let window = global.as_window(); diff --git a/components/script/dom/bindings/callback.rs b/components/script/dom/bindings/callback.rs index c9130cfd50a..9b14f3ced60 100644 --- a/components/script/dom/bindings/callback.rs +++ b/components/script/dom/bindings/callback.rs @@ -245,7 +245,7 @@ impl CallSetup { if let Some(window) = global.downcast::() { window.Document().ensure_safe_to_run_script_or_layout(); } - let cx = global.get_cx(); + let cx = GlobalScope::get_cx(); let aes = AutoEntryScript::new(&global); let ais = callback.incumbent().map(AutoIncumbentScript::new); diff --git a/components/script/dom/bindings/reflector.rs b/components/script/dom/bindings/reflector.rs index 04bf9fdbbed..8176989ed36 100644 --- a/components/script/dom/bindings/reflector.rs +++ b/components/script/dom/bindings/reflector.rs @@ -9,6 +9,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; +use crate::realms::AlreadyInRealm; use crate::script_runtime::JSContext; use js::jsapi::{Heap, JSObject}; use js::rust::HandleObject; @@ -22,7 +23,7 @@ where U: DerivedFrom, { let global_scope = global.upcast(); - unsafe { T::WRAP(global_scope.get_cx(), global_scope, obj) } + unsafe { T::WRAP(GlobalScope::get_cx(), global_scope, obj) } } /// A struct to store a reference to the reflector of a DOM object. @@ -82,7 +83,8 @@ pub trait DomObject: JSTraceable + 'static { where Self: Sized, { - GlobalScope::from_reflector(self) + let realm = AlreadyInRealm::assert_for_cx(GlobalScope::get_cx()); + GlobalScope::from_reflector(self, &realm) } } diff --git a/components/script/dom/bindings/structuredclone.rs b/components/script/dom/bindings/structuredclone.rs index 19dcf78ccd4..85cb758e600 100644 --- a/components/script/dom/bindings/structuredclone.rs +++ b/components/script/dom/bindings/structuredclone.rs @@ -352,7 +352,7 @@ pub fn read( mut data: StructuredSerializedData, rval: MutableHandleValue, ) -> Result>, ()> { - let cx = global.get_cx(); + let cx = GlobalScope::get_cx(); let _ac = enter_realm(&*global); let mut sc_holder = StructuredDataHolder::Read { blobs: None, diff --git a/components/script/dom/blob.rs b/components/script/dom/blob.rs index 44011df9494..4cc0149d008 100644 --- a/components/script/dom/blob.rs +++ b/components/script/dom/blob.rs @@ -238,8 +238,8 @@ impl BlobMethods for Blob { // https://w3c.github.io/FileAPI/#text-method-algo fn Text(&self) -> Rc { let global = self.global(); - let in_realm_proof = AlreadyInRealm::assert(&global); - let p = Promise::new_in_current_realm(&global, InRealm::Already(&in_realm_proof)); + let in_realm_proof = AlreadyInRealm::assert(); + let p = Promise::new_in_current_realm(InRealm::Already(&in_realm_proof)); let id = self.get_blob_url_id(); global.read_file_async( id, @@ -261,8 +261,8 @@ impl BlobMethods for Blob { // https://w3c.github.io/FileAPI/#arraybuffer-method-algo fn ArrayBuffer(&self) -> Rc { let global = self.global(); - let in_realm_proof = AlreadyInRealm::assert(&global); - let p = Promise::new_in_current_realm(&global, InRealm::Already(&in_realm_proof)); + let in_realm_proof = AlreadyInRealm::assert(); + let p = Promise::new_in_current_realm(InRealm::Already(&in_realm_proof)); let id = self.get_blob_url_id(); @@ -272,7 +272,7 @@ impl BlobMethods for Blob { Box::new(|promise, bytes| { match bytes { Ok(b) => { - let cx = promise.global().get_cx(); + let cx = GlobalScope::get_cx(); let result = run_array_buffer_data_algorithm(cx, b); match result { diff --git a/components/script/dom/bluetooth.rs b/components/script/dom/bluetooth.rs index 2bdc636dc7a..e2754af4043 100644 --- a/components/script/dom/bluetooth.rs +++ b/components/script/dom/bluetooth.rs @@ -287,8 +287,8 @@ where T: AsyncBluetoothListener + DomObject + 'static, F: FnOnce(StringOrUnsignedLong) -> Fallible, { - let in_realm_proof = AlreadyInRealm::assert(&attribute.global()); - let p = Promise::new_in_current_realm(&attribute.global(), InRealm::Already(&in_realm_proof)); + let in_realm_proof = AlreadyInRealm::assert(); + let p = Promise::new_in_current_realm(InRealm::Already(&in_realm_proof)); let result_uuid = if let Some(u) = uuid { // Step 1. @@ -528,7 +528,7 @@ impl From for Error { impl BluetoothMethods for Bluetooth { // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetooth-requestdevice fn RequestDevice(&self, option: &RequestDeviceOptions, comp: InRealm) -> Rc { - let p = Promise::new_in_current_realm(&self.global(), comp); + let p = Promise::new_in_current_realm(comp); // Step 1. if (option.filters.is_some() && option.acceptAllDevices) || (option.filters.is_none() && !option.acceptAllDevices) @@ -546,7 +546,7 @@ impl BluetoothMethods for Bluetooth { // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetooth-getavailability fn GetAvailability(&self, comp: InRealm) -> Rc { - let p = Promise::new_in_current_realm(&self.global(), comp); + let p = Promise::new_in_current_realm(comp); // Step 1. We did not override the method // Step 2 - 3. in handle_response let sender = response_async(&p, self); diff --git a/components/script/dom/bluetoothdevice.rs b/components/script/dom/bluetoothdevice.rs index bff2e0871ff..2d96efb3e05 100644 --- a/components/script/dom/bluetoothdevice.rs +++ b/components/script/dom/bluetoothdevice.rs @@ -277,7 +277,7 @@ impl BluetoothDeviceMethods for BluetoothDevice { // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothdevice-watchadvertisements fn WatchAdvertisements(&self, comp: InRealm) -> Rc { - let p = Promise::new_in_current_realm(&self.global(), comp); + let p = Promise::new_in_current_realm(comp); let sender = response_async(&p, self); // TODO: Step 1. // Note: Steps 2 - 3 are implemented in components/bluetooth/lib.rs in watch_advertisements function diff --git a/components/script/dom/bluetoothremotegattcharacteristic.rs b/components/script/dom/bluetoothremotegattcharacteristic.rs index fd01653c84d..a3c4b826bd7 100644 --- a/components/script/dom/bluetoothremotegattcharacteristic.rs +++ b/components/script/dom/bluetoothremotegattcharacteristic.rs @@ -137,7 +137,7 @@ impl BluetoothRemoteGATTCharacteristicMethods for BluetoothRemoteGATTCharacteris // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-readvalue fn ReadValue(&self, comp: InRealm) -> Rc { - let p = Promise::new_in_current_realm(&self.global(), comp); + let p = Promise::new_in_current_realm(comp); // Step 1. if uuid_is_blocklisted(self.uuid.as_ref(), Blocklist::Reads) { @@ -170,7 +170,7 @@ impl BluetoothRemoteGATTCharacteristicMethods for BluetoothRemoteGATTCharacteris // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-writevalue fn WriteValue(&self, value: ArrayBufferViewOrArrayBuffer, comp: InRealm) -> Rc { - let p = Promise::new_in_current_realm(&self.global(), comp); + let p = Promise::new_in_current_realm(comp); // Step 1. if uuid_is_blocklisted(self.uuid.as_ref(), Blocklist::Writes) { @@ -221,7 +221,7 @@ impl BluetoothRemoteGATTCharacteristicMethods for BluetoothRemoteGATTCharacteris // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-startnotifications fn StartNotifications(&self, comp: InRealm) -> Rc { - let p = Promise::new_in_current_realm(&self.global(), comp); + let p = Promise::new_in_current_realm(comp); // Step 1. if uuid_is_blocklisted(self.uuid.as_ref(), Blocklist::Reads) { @@ -258,7 +258,7 @@ impl BluetoothRemoteGATTCharacteristicMethods for BluetoothRemoteGATTCharacteris // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-stopnotifications fn StopNotifications(&self, comp: InRealm) -> Rc { - let p = Promise::new_in_current_realm(&self.global(), comp); + let p = Promise::new_in_current_realm(comp); let sender = response_async(&p, self); // TODO: Step 3 - 4: Implement `active notification context set` for BluetoothRemoteGATTCharacteristic, diff --git a/components/script/dom/bluetoothremotegattdescriptor.rs b/components/script/dom/bluetoothremotegattdescriptor.rs index 39e298f923c..0e60170857e 100644 --- a/components/script/dom/bluetoothremotegattdescriptor.rs +++ b/components/script/dom/bluetoothremotegattdescriptor.rs @@ -93,7 +93,7 @@ impl BluetoothRemoteGATTDescriptorMethods for BluetoothRemoteGATTDescriptor { // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattdescriptor-readvalue fn ReadValue(&self, comp: InRealm) -> Rc { - let p = Promise::new_in_current_realm(&self.global(), comp); + let p = Promise::new_in_current_realm(comp); // Step 1. if uuid_is_blocklisted(self.uuid.as_ref(), Blocklist::Reads) { @@ -125,7 +125,7 @@ impl BluetoothRemoteGATTDescriptorMethods for BluetoothRemoteGATTDescriptor { // https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattdescriptor-writevalue fn WriteValue(&self, value: ArrayBufferViewOrArrayBuffer, comp: InRealm) -> Rc { - let p = Promise::new_in_current_realm(&self.global(), comp); + let p = Promise::new_in_current_realm(comp); // Step 1. if uuid_is_blocklisted(self.uuid.as_ref(), Blocklist::Writes) { diff --git a/components/script/dom/bluetoothremotegattserver.rs b/components/script/dom/bluetoothremotegattserver.rs index 8a4f94fe35c..c5ffecb100b 100644 --- a/components/script/dom/bluetoothremotegattserver.rs +++ b/components/script/dom/bluetoothremotegattserver.rs @@ -71,7 +71,7 @@ impl BluetoothRemoteGATTServerMethods for BluetoothRemoteGATTServer { #[allow(unsafe_code)] fn Connect(&self, comp: InRealm) -> Rc { // Step 1. - let p = Promise::new_in_current_realm(&self.global(), comp); + let p = Promise::new_in_current_realm(comp); let sender = response_async(&p, self); // TODO: Step 3: Check if the UA is currently using the Bluetooth system. diff --git a/components/script/dom/console.rs b/components/script/dom/console.rs index 93171beb547..329e4c93c50 100644 --- a/components/script/dom/console.rs +++ b/components/script/dom/console.rs @@ -17,7 +17,8 @@ impl Console { #[allow(unsafe_code)] fn send_to_devtools(global: &GlobalScope, level: LogLevel, message: DOMString) { if let Some(chan) = global.devtools_chan() { - let caller = unsafe { describe_scripted_caller(*global.get_cx()) }.unwrap_or_default(); + let caller = + unsafe { describe_scripted_caller(*GlobalScope::get_cx()) }.unwrap_or_default(); let console_message = ConsoleMessage { message: String::from(message), logLevel: level, diff --git a/components/script/dom/create.rs b/components/script/dom/create.rs index 37aaf07286f..1a4815d1179 100644 --- a/components/script/dom/create.rs +++ b/components/script/dom/create.rs @@ -154,7 +154,7 @@ fn create_html_element( // Step 6. Recovering from exception. let global = GlobalScope::current().unwrap_or_else(|| document.global()); - let cx = global.get_cx(); + let cx = GlobalScope::get_cx(); // Step 6.1.1 unsafe { diff --git a/components/script/dom/customelementregistry.rs b/components/script/dom/customelementregistry.rs index dfba75a2028..153b1d206fc 100644 --- a/components/script/dom/customelementregistry.rs +++ b/components/script/dom/customelementregistry.rs @@ -140,11 +140,10 @@ impl CustomElementRegistry { constructor: HandleObject, prototype: MutableHandleValue, ) -> ErrorResult { - let global_scope = self.window.upcast::(); unsafe { // Step 10.1 if !JS_GetProperty( - *global_scope.get_cx(), + *GlobalScope::get_cx(), constructor, b"prototype\0".as_ptr() as *const _, prototype, @@ -166,7 +165,7 @@ impl CustomElementRegistry { /// Steps 10.3, 10.4 #[allow(unsafe_code)] unsafe fn get_callbacks(&self, prototype: HandleObject) -> Fallible { - let cx = self.window.get_cx(); + let cx = GlobalScope::get_cx(); // Step 4 Ok(LifecycleCallbacks { @@ -181,7 +180,7 @@ impl CustomElementRegistry { /// Step 10.6 #[allow(unsafe_code)] fn get_observed_attributes(&self, constructor: HandleObject) -> Fallible> { - let cx = self.window.get_cx(); + let cx = GlobalScope::get_cx(); rooted!(in(*cx) let mut observed_attributes = UndefinedValue()); if unsafe { !JS_GetProperty( @@ -254,7 +253,7 @@ impl CustomElementRegistryMethods for CustomElementRegistry { constructor_: Rc, options: &ElementDefinitionOptions, ) -> ErrorResult { - let cx = self.window.get_cx(); + let cx = GlobalScope::get_cx(); rooted!(in(*cx) let constructor = constructor_.callback()); let name = LocalName::from(&*name); @@ -429,7 +428,7 @@ impl CustomElementRegistryMethods for CustomElementRegistry { // Step 1 if !is_valid_custom_element_name(&name) { - let promise = Promise::new_in_current_realm(&global_scope, comp); + let promise = Promise::new_in_current_realm(comp); promise.reject_native(&DOMException::new(&global_scope, DOMErrorName::SyntaxError)); return promise; } @@ -437,12 +436,12 @@ impl CustomElementRegistryMethods for CustomElementRegistry { // Step 2 if let Some(definition) = self.definitions.borrow().get(&LocalName::from(&*name)) { unsafe { - let cx = global_scope.get_cx(); + let cx = GlobalScope::get_cx(); rooted!(in(*cx) let mut constructor = UndefinedValue()); definition .constructor .to_jsval(*cx, constructor.handle_mut()); - let promise = Promise::new_in_current_realm(&global_scope, comp); + let promise = Promise::new_in_current_realm(comp); promise.resolve_native(&constructor.get()); return promise; } @@ -453,7 +452,7 @@ impl CustomElementRegistryMethods for CustomElementRegistry { // Steps 4, 5 let promise = map.get(&name).cloned().unwrap_or_else(|| { - let promise = Promise::new_in_current_realm(&global_scope, comp); + let promise = Promise::new_in_current_realm(comp); map.insert(name, promise.clone()); promise }); @@ -543,7 +542,7 @@ impl CustomElementDefinition { prefix: Option, ) -> Fallible> { let window = document.window(); - let cx = window.get_cx(); + let cx = GlobalScope::get_cx(); // Step 2 rooted!(in(*cx) let constructor = ObjectValue(self.constructor.callback())); rooted!(in(*cx) let mut element = ptr::null_mut::()); @@ -662,7 +661,7 @@ pub fn upgrade_element(definition: Rc, element: &Elemen // Step 8.exception.3 let global = GlobalScope::current().expect("No current global"); - let cx = global.get_cx(); + let cx = GlobalScope::get_cx(); unsafe { let ar = enter_realm(&*global); throw_dom_exception(cx, &global, error); @@ -686,7 +685,7 @@ fn run_upgrade_constructor( element: &Element, ) -> ErrorResult { let window = window_from_node(element); - let cx = window.get_cx(); + let cx = GlobalScope::get_cx(); rooted!(in(*cx) let constructor_val = ObjectValue(constructor.callback())); rooted!(in(*cx) let mut element_val = UndefinedValue()); unsafe { @@ -909,7 +908,7 @@ impl CustomElementReactionStack { return; } - let cx = element.global().get_cx(); + let cx = GlobalScope::get_cx(); // We might be here during HTML parsing, rather than // during Javscript execution, and so we typically aren't // already in a realm here. diff --git a/components/script/dom/dissimilaroriginwindow.rs b/components/script/dom/dissimilaroriginwindow.rs index 989aec3ff3d..13d836114c6 100644 --- a/components/script/dom/dissimilaroriginwindow.rs +++ b/components/script/dom/dissimilaroriginwindow.rs @@ -46,7 +46,7 @@ pub struct DissimilarOriginWindow { impl DissimilarOriginWindow { #[allow(unsafe_code)] pub fn new(global_to_clone_from: &GlobalScope, window_proxy: &WindowProxy) -> DomRoot { - let cx = global_to_clone_from.get_cx(); + let cx = GlobalScope::get_cx(); let win = Box::new(Self { globalscope: GlobalScope::new_inherited( PipelineId::new(), diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index f636e11fc51..cb2d43dd62c 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -3573,9 +3573,8 @@ impl Document { // https://fullscreen.spec.whatwg.org/#dom-element-requestfullscreen pub fn enter_fullscreen(&self, pending: &Element) -> Rc { // Step 1 - let in_realm_proof = AlreadyInRealm::assert(&self.global()); - let promise = - Promise::new_in_current_realm(&self.global(), InRealm::Already(&in_realm_proof)); + let in_realm_proof = AlreadyInRealm::assert(); + let promise = Promise::new_in_current_realm(InRealm::Already(&in_realm_proof)); let mut error = false; // Step 4 @@ -3642,8 +3641,8 @@ impl Document { pub fn exit_fullscreen(&self) -> Rc { let global = self.global(); // Step 1 - let in_realm_proof = AlreadyInRealm::assert(&global); - let promise = Promise::new_in_current_realm(&global, InRealm::Already(&in_realm_proof)); + let in_realm_proof = AlreadyInRealm::assert(); + let promise = Promise::new_in_current_realm(InRealm::Already(&in_realm_proof)); // Step 2 if self.fullscreen_element.get().is_none() { promise.reject_error(Error::Type(String::from("fullscreen is null"))); diff --git a/components/script/dom/eventsource.rs b/components/script/dom/eventsource.rs index 49e612cd6eb..9be9962378e 100644 --- a/components/script/dom/eventsource.rs +++ b/components/script/dom/eventsource.rs @@ -222,10 +222,10 @@ impl EventSourceContext { // Steps 4-5 let event = { let _ac = enter_realm(&*event_source); - rooted!(in(*event_source.global().get_cx()) let mut data = UndefinedValue()); + rooted!(in(*GlobalScope::get_cx()) let mut data = UndefinedValue()); unsafe { self.data - .to_jsval(*event_source.global().get_cx(), data.handle_mut()) + .to_jsval(*GlobalScope::get_cx(), data.handle_mut()) }; MessageEvent::new( &*event_source.global(), diff --git a/components/script/dom/eventtarget.rs b/components/script/dom/eventtarget.rs index 0d57b38c16b..9e9bf816c72 100644 --- a/components/script/dom/eventtarget.rs +++ b/components/script/dom/eventtarget.rs @@ -184,7 +184,7 @@ impl CompiledEventListener { CommonEventHandler::ErrorEventHandler(ref handler) => { if let Some(event) = event.downcast::() { if object.is::() || object.is::() { - let cx = object.global().get_cx(); + let cx = GlobalScope::get_cx(); rooted!(in(*cx) let error = event.Error(cx)); let return_value = handler.Call_( object, @@ -242,7 +242,7 @@ impl CompiledEventListener { CommonEventHandler::EventHandler(ref handler) => { if let Ok(value) = handler.Call_(object, event, exception_handle) { - let cx = object.global().get_cx(); + let cx = GlobalScope::get_cx(); rooted!(in(*cx) let value = value); let value = value.handle(); @@ -525,7 +525,7 @@ impl EventTarget { let is_error = ty == &atom!("error") && self.is::(); let args = if is_error { ERROR_ARG_NAMES } else { ARG_NAMES }; - let cx = window.get_cx(); + let cx = GlobalScope::get_cx(); let options = unsafe { CompileOptionsWrapper::new(*cx, &handler.url.to_string(), handler.line as u32) }; @@ -592,7 +592,7 @@ impl EventTarget { where T: CallbackContainer, { - let cx = self.global().get_cx(); + let cx = GlobalScope::get_cx(); let event_listener = listener.map(|listener| { InlineEventListener::Compiled(CommonEventHandler::EventHandler(unsafe { @@ -607,7 +607,7 @@ impl EventTarget { where T: CallbackContainer, { - let cx = self.global().get_cx(); + let cx = GlobalScope::get_cx(); let event_listener = listener.map(|listener| { InlineEventListener::Compiled(CommonEventHandler::ErrorEventHandler(unsafe { @@ -625,7 +625,7 @@ impl EventTarget { ) where T: CallbackContainer, { - let cx = self.global().get_cx(); + let cx = GlobalScope::get_cx(); let event_listener = listener.map(|listener| { InlineEventListener::Compiled(CommonEventHandler::BeforeUnloadEventHandler(unsafe { @@ -637,7 +637,7 @@ impl EventTarget { #[allow(unsafe_code)] pub fn get_event_handler_common(&self, ty: &str) -> Option> { - let cx = self.global().get_cx(); + let cx = GlobalScope::get_cx(); let listener = self.get_inline_event_listener(&Atom::from(ty)); unsafe { listener.map(|listener| { diff --git a/components/script/dom/filereader.rs b/components/script/dom/filereader.rs index 084cecc9577..2e56f48079c 100644 --- a/components/script/dom/filereader.rs +++ b/components/script/dom/filereader.rs @@ -258,7 +258,7 @@ impl FileReader { let _ac = enter_realm(&*fr); FileReader::perform_readasarraybuffer( &fr.result, - fr.global().get_cx(), + GlobalScope::get_cx(), data, &blob_contents, ) diff --git a/components/script/dom/globalscope.rs b/components/script/dom/globalscope.rs index 9a3829f4d0e..b03915997e5 100644 --- a/components/script/dom/globalscope.rs +++ b/components/script/dom/globalscope.rs @@ -1215,7 +1215,7 @@ impl GlobalScope { return; } - rooted!(in(*global.get_cx()) let mut message = UndefinedValue()); + rooted!(in(*GlobalScope::get_cx()) let mut message = UndefinedValue()); // Step 10.3 StructuredDeserialize(serialized, targetRealm). if let Ok(ports) = structuredclone::read(&global, data, message.handle_mut()) { @@ -1269,7 +1269,7 @@ impl GlobalScope { }; if let Some((dom_port, PortMessageTask { origin, data })) = should_dispatch { // Substep 3-4 - rooted!(in(*self.get_cx()) let mut message_clone = UndefinedValue()); + rooted!(in(*GlobalScope::get_cx()) let mut message_clone = UndefinedValue()); if let Ok(ports) = structuredclone::read(self, data, message_clone.handle_mut()) { // Substep 6 // Dispatch the event, using the dom message-port. @@ -2120,7 +2120,7 @@ impl GlobalScope { /// Returns the global scope of the realm that the given DOM object's reflector /// was created in. #[allow(unsafe_code)] - pub fn from_reflector(reflector: &T) -> DomRoot { + pub fn from_reflector(reflector: &T, _realm: &AlreadyInRealm) -> DomRoot { unsafe { GlobalScope::from_object(*reflector.reflector().get_jsobject()) } } @@ -2221,7 +2221,7 @@ impl GlobalScope { } #[allow(unsafe_code)] - pub fn get_cx(&self) -> SafeJSContext { + pub fn get_cx() -> SafeJSContext { unsafe { SafeJSContext::from_ptr(Runtime::get()) } } @@ -2603,7 +2603,7 @@ impl GlobalScope { Some(metadata), self.time_profiler_chan().clone(), || { - let cx = self.get_cx(); + let cx = GlobalScope::get_cx(); let ar = enter_realm(&*self); @@ -2733,8 +2733,8 @@ impl GlobalScope { image: ImageBitmapSource, options: &ImageBitmapOptions, ) -> Rc { - let in_realm_proof = AlreadyInRealm::assert(&self); - let p = Promise::new_in_current_realm(&self, InRealm::Already(&in_realm_proof)); + let in_realm_proof = AlreadyInRealm::assert(); + let p = Promise::new_in_current_realm(InRealm::Already(&in_realm_proof)); if options.resizeWidth.map_or(false, |w| w == 0) { p.reject_error(Error::InvalidState); return p; @@ -2857,7 +2857,7 @@ impl GlobalScope { // Only perform the checkpoint if we're not shutting down. if self.can_continue_running() { self.microtask_queue.checkpoint( - self.get_cx(), + GlobalScope::get_cx(), |_| Some(DomRoot::from_ref(self)), vec![DomRoot::from_ref(self)], ); @@ -2866,7 +2866,7 @@ impl GlobalScope { /// Enqueue a microtask for subsequent execution. pub fn enqueue_microtask(&self, job: Microtask) { - self.microtask_queue.enqueue(job, self.get_cx()); + self.microtask_queue.enqueue(job, GlobalScope::get_cx()); } /// Create a new sender/receiver pair that can be used to implement an on-demand diff --git a/components/script/dom/gpu.rs b/components/script/dom/gpu.rs index eea21c1b988..8fe003f2fcd 100644 --- a/components/script/dom/gpu.rs +++ b/components/script/dom/gpu.rs @@ -100,7 +100,7 @@ impl GPUMethods for GPU { // https://gpuweb.github.io/gpuweb/#dom-gpu-requestadapter fn RequestAdapter(&self, options: &GPURequestAdapterOptions, comp: InRealm) -> Rc { let global = &self.global(); - let promise = Promise::new_in_current_realm(global, comp); + let promise = Promise::new_in_current_realm(comp); let sender = response_async(&promise, self); let power_preference = match options.powerPreference { Some(GPUPowerPreference::Low_power) => PowerPreference::LowPower, diff --git a/components/script/dom/gpuadapter.rs b/components/script/dom/gpuadapter.rs index e4876416952..ce82e4ec4a3 100644 --- a/components/script/dom/gpuadapter.rs +++ b/components/script/dom/gpuadapter.rs @@ -78,7 +78,7 @@ impl GPUAdapterMethods for GPUAdapter { /// https://gpuweb.github.io/gpuweb/#dom-gpuadapter-requestdevice fn RequestDevice(&self, descriptor: &GPUDeviceDescriptor, comp: InRealm) -> Rc { - let promise = Promise::new_in_current_realm(&self.global(), comp); + let promise = Promise::new_in_current_realm(comp); let sender = response_async(&promise, self); let mut features = wgt::Features::empty(); for &ext in descriptor.extensions.iter() { diff --git a/components/script/dom/gpubuffer.rs b/components/script/dom/gpubuffer.rs index 60a6075cb7f..83dd27b47d9 100644 --- a/components/script/dom/gpubuffer.rs +++ b/components/script/dom/gpubuffer.rs @@ -6,7 +6,6 @@ use crate::dom::bindings::cell::DomRefCell; use crate::dom::bindings::codegen::Bindings::GPUBufferBinding::{GPUBufferMethods, GPUSize64}; use crate::dom::bindings::codegen::Bindings::GPUMapModeBinding::GPUMapModeConstants; use crate::dom::bindings::error::{Error, Fallible}; -use crate::dom::bindings::reflector::DomObject; use crate::dom::bindings::reflector::{reflect_dom_object, Reflector}; use crate::dom::bindings::root::{Dom, DomRoot}; use crate::dom::bindings::str::USVString; @@ -134,7 +133,7 @@ impl GPUBufferMethods for GPUBuffer { #[allow(unsafe_code)] /// https://gpuweb.github.io/gpuweb/#dom-gpubuffer-unmap fn Unmap(&self) { - let cx = self.global().get_cx(); + let cx = GlobalScope::get_cx(); // Step 1 match self.state.get() { GPUBufferState::Unmapped | GPUBufferState::Destroyed => { @@ -209,7 +208,7 @@ impl GPUBufferMethods for GPUBuffer { size: Option, comp: InRealm, ) -> Rc { - let promise = Promise::new_in_current_realm(&self.global(), comp); + let promise = Promise::new_in_current_realm(comp); let range_size = if let Some(s) = size { s } else if offset >= self.size { diff --git a/components/script/dom/gpudevice.rs b/components/script/dom/gpudevice.rs index fb6fad7efb4..5ea21eac5de 100644 --- a/components/script/dom/gpudevice.rs +++ b/components/script/dom/gpudevice.rs @@ -357,7 +357,7 @@ impl GPUDeviceMethods for GPUDevice { /// https://gpuweb.github.io/gpuweb/#dom-gpudevice-lost fn Lost(&self, comp: InRealm) -> Rc { - let promise = Promise::new_in_current_realm(&self.global(), comp); + let promise = Promise::new_in_current_realm(comp); *self.lost_promise.borrow_mut() = Some(promise.clone()); promise } @@ -1117,7 +1117,7 @@ impl GPUDeviceMethods for GPUDevice { /// https://gpuweb.github.io/gpuweb/#dom-gpudevice-poperrorscope fn PopErrorScope(&self, comp: InRealm) -> Rc { let mut context = self.scope_context.borrow_mut(); - let promise = Promise::new_in_current_realm(&self.global(), comp); + let promise = Promise::new_in_current_realm(comp); let scope_id = if let Some(meta) = context.scope_stack.iter().rev().find(|m| !m.popped.get()) { meta.popped.set(true); diff --git a/components/script/dom/history.rs b/components/script/dom/history.rs index 9023a397c66..663499da38f 100644 --- a/components/script/dom/history.rs +++ b/components/script/dom/history.rs @@ -117,7 +117,7 @@ impl History { blobs: None, }; let global_scope = self.window.upcast::(); - rooted!(in(*global_scope.get_cx()) let mut state = UndefinedValue()); + rooted!(in(*GlobalScope::get_cx()) let mut state = UndefinedValue()); if let Err(_) = structuredclone::read(&global_scope, data, state.handle_mut()) { warn!("Error reading structuredclone data"); } diff --git a/components/script/dom/htmlimageelement.rs b/components/script/dom/htmlimageelement.rs index 893080edd07..1c898d1dc98 100644 --- a/components/script/dom/htmlimageelement.rs +++ b/components/script/dom/htmlimageelement.rs @@ -46,6 +46,7 @@ use crate::fetch::create_a_potential_cors_request; use crate::image_listener::{generate_cache_listener_for_element, ImageCacheListener}; use crate::microtask::{Microtask, MicrotaskRunnable}; use crate::network_listener::{self, NetworkListener, PreInvoke, ResourceTimingListener}; +use crate::realms::enter_realm; use crate::script_thread::ScriptThread; use crate::task_source::TaskSource; use app_units::{Au, AU_PER_PX}; @@ -56,6 +57,7 @@ use html5ever::{LocalName, Prefix, QualName}; use ipc_channel::ipc; use ipc_channel::ipc::IpcSender; use ipc_channel::router::ROUTER; +use js::jsapi::JSAutoRealm; use mime::{self, Mime}; use msg::constellation_msg::PipelineId; use net_traits::image::base::{Image, ImageMetadata}; @@ -1353,6 +1355,13 @@ impl MicrotaskRunnable for ImageElementMicrotask { }, } } + + fn enter_realm(&self) -> JSAutoRealm { + match self { + &ImageElementMicrotask::StableStateUpdateImageDataTask { ref elem, .. } | + &ImageElementMicrotask::EnvironmentChangesTask { ref elem, .. } => enter_realm(&**elem), + } + } } pub trait LayoutHTMLImageElementHelpers { diff --git a/components/script/dom/htmlinputelement.rs b/components/script/dom/htmlinputelement.rs index 696e4566b63..e81e07e9643 100755 --- a/components/script/dom/htmlinputelement.rs +++ b/components/script/dom/htmlinputelement.rs @@ -833,7 +833,7 @@ impl HTMLInputElement { } // Rust's regex is not compatible, we need to use mozjs RegExp. - let cx = self.global().get_cx(); + let cx = GlobalScope::get_cx(); let _ac = enter_realm(self); rooted!(in(*cx) let mut pattern = ptr::null_mut::()); diff --git a/components/script/dom/htmlmediaelement.rs b/components/script/dom/htmlmediaelement.rs index f5043cac0ea..5eb9f709838 100644 --- a/components/script/dom/htmlmediaelement.rs +++ b/components/script/dom/htmlmediaelement.rs @@ -62,7 +62,7 @@ use crate::dom::virtualmethods::VirtualMethods; use crate::fetch::{create_a_potential_cors_request, FetchCanceller}; use crate::microtask::{Microtask, MicrotaskRunnable}; use crate::network_listener::{self, NetworkListener, PreInvoke, ResourceTimingListener}; -use crate::realms::InRealm; +use crate::realms::{enter_realm, InRealm}; use crate::script_thread::ScriptThread; use crate::task_source::TaskSource; use dom_struct::dom_struct; @@ -74,6 +74,7 @@ use html5ever::{LocalName, Prefix}; use http::header::{self, HeaderMap, HeaderValue}; use ipc_channel::ipc; use ipc_channel::router::ROUTER; +use js::jsapi::JSAutoRealm; use media::{glplayer_channel, GLPlayerMsg, GLPlayerMsgForward, WindowGLContext}; use net_traits::image::base::Image; use net_traits::request::Destination; @@ -2112,7 +2113,7 @@ impl HTMLMediaElementMethods for HTMLMediaElement { // https://html.spec.whatwg.org/multipage/#dom-media-play fn Play(&self, comp: InRealm) -> Rc { - let promise = Promise::new_in_current_realm(&self.global(), comp); + let promise = Promise::new_in_current_realm(comp); // Step 1. // FIXME(nox): Reject promise if not allowed to play. @@ -2506,6 +2507,14 @@ impl MicrotaskRunnable for MediaElementMicrotask { }, } } + + fn enter_realm(&self) -> JSAutoRealm { + match self { + &MediaElementMicrotask::ResourceSelectionTask { ref elem, .. } | + &MediaElementMicrotask::PauseIfNotInDocumentTask { ref elem } | + &MediaElementMicrotask::SeekedTask { ref elem, .. } => enter_realm(&**elem), + } + } } enum Resource { diff --git a/components/script/dom/htmlscriptelement.rs b/components/script/dom/htmlscriptelement.rs index dc7490f232c..1a0afeb1c84 100644 --- a/components/script/dom/htmlscriptelement.rs +++ b/components/script/dom/htmlscriptelement.rs @@ -110,7 +110,7 @@ unsafe extern "C" fn off_thread_compilation_callback( task!(off_thread_compile_continue: move || { let elem = script_element.root(); let global = elem.global(); - let cx = global.get_cx(); + let cx = GlobalScope::get_cx(); let _ar = enter_realm(&*global); let compiled_script = FinishOffThreadStencil(*cx, token.0, ptr::null_mut()); @@ -418,7 +418,7 @@ impl FetchResponseListener for ClassicContext { let elem = self.elem.root(); let global = elem.global(); - let cx = global.get_cx(); + let cx = GlobalScope::get_cx(); let _ar = enter_realm(&*global); let options = unsafe { CompileOptionsWrapper::new(*cx, final_url.as_str(), 1) }; @@ -1053,7 +1053,7 @@ impl HTMLScriptElement { } else { self.line_number as u32 }; - rooted!(in(*window.get_cx()) let mut rval = UndefinedValue()); + rooted!(in(*GlobalScope::get_cx()) let mut rval = UndefinedValue()); let global = window.upcast::(); global.evaluate_script_on_global_with_result( &script.code, @@ -1108,7 +1108,7 @@ impl HTMLScriptElement { .map(|record| record.handle()); if let Some(record) = record { - rooted!(in(*global.get_cx()) let mut rval = UndefinedValue()); + rooted!(in(*GlobalScope::get_cx()) let mut rval = UndefinedValue()); let evaluated = module_tree.execute_module(global, record, rval.handle_mut().into()); diff --git a/components/script/dom/imagedata.rs b/components/script/dom/imagedata.rs index d8574a9b666..43df0951492 100644 --- a/components/script/dom/imagedata.rs +++ b/components/script/dom/imagedata.rs @@ -39,7 +39,7 @@ impl ImageData { ) -> Fallible> { let len = width * height * 4; unsafe { - let cx = global.get_cx(); + let cx = GlobalScope::get_cx(); rooted!(in (*cx) let mut js_object = ptr::null_mut::()); if let Some(ref mut d) = data { d.resize(len as usize, 0); @@ -60,7 +60,7 @@ impl ImageData { jsobject: *mut JSObject, ) -> Fallible> { // checking jsobject type - let cx = global.get_cx(); + let cx = GlobalScope::get_cx(); typedarray!(in(*cx) let array_res: Uint8ClampedArray = jsobject); let array = array_res.map_err(|_| { Error::Type("Argument to Image data is not an Uint8ClampedArray".to_owned()) @@ -111,7 +111,7 @@ impl ImageData { }); let len = width * height * 4; - let cx = global.get_cx(); + let cx = GlobalScope::get_cx(); rooted!(in (*cx) let mut array = ptr::null_mut::()); Uint8ClampedArray::create(*cx, CreateWith::Length(len as usize), array.handle_mut()) .unwrap(); diff --git a/components/script/dom/mediadevices.rs b/components/script/dom/mediadevices.rs index b1f00a154be..9a88ed2e3a2 100644 --- a/components/script/dom/mediadevices.rs +++ b/components/script/dom/mediadevices.rs @@ -44,7 +44,7 @@ impl MediaDevicesMethods for MediaDevices { /// https://w3c.github.io/mediacapture-main/#dom-mediadevices-getusermedia #[allow(unsafe_code)] fn GetUserMedia(&self, constraints: &MediaStreamConstraints, comp: InRealm) -> Rc { - let p = Promise::new_in_current_realm(&self.global(), comp); + let p = Promise::new_in_current_realm(comp); let media = ServoMedia::get().unwrap(); let stream = MediaStream::new(&self.global()); if let Some(constraints) = convert_constraints(&constraints.audio) { @@ -67,9 +67,8 @@ impl MediaDevicesMethods for MediaDevices { /// https://w3c.github.io/mediacapture-main/#dom-mediadevices-enumeratedevices fn EnumerateDevices(&self) -> Rc { // Step 1. - let global = self.global(); - let in_realm_proof = AlreadyInRealm::assert(&global); - let p = Promise::new_in_current_realm(&global, InRealm::Already(&in_realm_proof)); + let in_realm_proof = AlreadyInRealm::assert(); + let p = Promise::new_in_current_realm(InRealm::Already(&in_realm_proof)); // Step 2. // XXX These steps should be run in parallel. diff --git a/components/script/dom/navigationpreloadmanager.rs b/components/script/dom/navigationpreloadmanager.rs index d45fa9ac5f8..c8d74403fcd 100644 --- a/components/script/dom/navigationpreloadmanager.rs +++ b/components/script/dom/navigationpreloadmanager.rs @@ -43,7 +43,7 @@ impl NavigationPreloadManager { impl NavigationPreloadManagerMethods for NavigationPreloadManager { // https://w3c.github.io/ServiceWorker/#navigation-preload-manager-enable fn Enable(&self, comp: InRealm) -> Rc { - let promise = Promise::new_in_current_realm(&*self.global(), comp); + let promise = Promise::new_in_current_realm(comp); // 2. if self.serviceworker_registration.is_active() { @@ -65,7 +65,7 @@ impl NavigationPreloadManagerMethods for NavigationPreloadManager { // https://w3c.github.io/ServiceWorker/#navigation-preload-manager-disable fn Disable(&self, comp: InRealm) -> Rc { - let promise = Promise::new_in_current_realm(&*self.global(), comp); + let promise = Promise::new_in_current_realm(comp); // 2. if self.serviceworker_registration.is_active() { @@ -87,7 +87,7 @@ impl NavigationPreloadManagerMethods for NavigationPreloadManager { // https://w3c.github.io/ServiceWorker/#navigation-preload-manager-setheadervalue fn SetHeaderValue(&self, value: ByteString, comp: InRealm) -> Rc { - let promise = Promise::new_in_current_realm(&*self.global(), comp); + let promise = Promise::new_in_current_realm(comp); // 2. if self.serviceworker_registration.is_active() { @@ -109,7 +109,7 @@ impl NavigationPreloadManagerMethods for NavigationPreloadManager { // https://w3c.github.io/ServiceWorker/#navigation-preload-manager-getstate fn GetState(&self, comp: InRealm) -> Rc { - let promise = Promise::new_in_current_realm(&*self.global(), comp); + let promise = Promise::new_in_current_realm(comp); // 2. let mut state = NavigationPreloadState::empty(); diff --git a/components/script/dom/offlineaudiocontext.rs b/components/script/dom/offlineaudiocontext.rs index 878bdedd314..798abe76f7d 100644 --- a/components/script/dom/offlineaudiocontext.rs +++ b/components/script/dom/offlineaudiocontext.rs @@ -121,7 +121,7 @@ impl OfflineAudioContextMethods for OfflineAudioContext { // https://webaudio.github.io/web-audio-api/#dom-offlineaudiocontext-startrendering fn StartRendering(&self, comp: InRealm) -> Rc { - let promise = Promise::new_in_current_realm(&self.global(), comp); + let promise = Promise::new_in_current_realm(comp); if self.rendering_started.get() { promise.reject_error(Error::InvalidState); return promise; diff --git a/components/script/dom/paintworkletglobalscope.rs b/components/script/dom/paintworkletglobalscope.rs index 5a3b9af24df..25bdeeb5ca3 100644 --- a/components/script/dom/paintworkletglobalscope.rs +++ b/components/script/dom/paintworkletglobalscope.rs @@ -252,7 +252,7 @@ impl PaintWorkletGlobalScope { name, size_in_px.width, size_in_px.height, device_pixel_ratio ); - let cx = self.worklet_global.get_cx(); + let cx = WorkletGlobalScope::get_cx(); let _ac = JSAutoRealm::new(*cx, self.worklet_global.reflector().get_jsobject().get()); // TODO: Steps 1-2.1. @@ -517,7 +517,7 @@ impl PaintWorkletGlobalScopeMethods for PaintWorkletGlobalScope { /// fn RegisterPaint(&self, name: DOMString, paint_ctor: Rc) -> Fallible<()> { let name = Atom::from(name); - let cx = self.worklet_global.get_cx(); + let cx = WorkletGlobalScope::get_cx(); rooted!(in(*cx) let paint_obj = paint_ctor.callback_holder().get()); rooted!(in(*cx) let paint_val = ObjectValue(paint_obj.get())); diff --git a/components/script/dom/permissions.rs b/components/script/dom/permissions.rs index b4e6bf8f5de..2d7cd549cc2 100644 --- a/components/script/dom/permissions.rs +++ b/components/script/dom/permissions.rs @@ -87,8 +87,8 @@ impl Permissions { let p = match promise { Some(promise) => promise, None => { - let in_realm_proof = AlreadyInRealm::assert(&self.global()); - Promise::new_in_current_realm(&self.global(), InRealm::Already(&in_realm_proof)) + let in_realm_proof = AlreadyInRealm::assert(); + Promise::new_in_current_realm(InRealm::Already(&in_realm_proof)) }, }; diff --git a/components/script/dom/promise.rs b/components/script/dom/promise.rs index 18be293c625..2ba29d20db6 100644 --- a/components/script/dom/promise.rs +++ b/components/script/dom/promise.rs @@ -88,11 +88,11 @@ impl Promise { pub fn new(global: &GlobalScope) -> Rc { let realm = enter_realm(&*global); let comp = InRealm::Entered(&realm); - Promise::new_in_current_realm(global, comp) + Promise::new_in_current_realm(comp) } - pub fn new_in_current_realm(global: &GlobalScope, _comp: InRealm) -> Rc { - let cx = global.get_cx(); + pub fn new_in_current_realm(_comp: InRealm) -> Rc { + let cx = GlobalScope::get_cx(); rooted!(in(*cx) let mut obj = ptr::null_mut::()); Promise::create_js_promise(cx, obj.handle_mut()); Promise::new_with_js_promise(obj.handle(), cx) @@ -100,7 +100,7 @@ impl Promise { #[allow(unsafe_code)] pub fn duplicate(&self) -> Rc { - let cx = self.global().get_cx(); + let cx = GlobalScope::get_cx(); Promise::new_with_js_promise(self.reflector().get_jsobject(), cx) } @@ -172,7 +172,7 @@ impl Promise { where T: ToJSValConvertible, { - let cx = self.global().get_cx(); + let cx = GlobalScope::get_cx(); let _ac = enter_realm(&*self); rooted!(in(*cx) let mut v = UndefinedValue()); unsafe { @@ -195,7 +195,7 @@ impl Promise { where T: ToJSValConvertible, { - let cx = self.global().get_cx(); + let cx = GlobalScope::get_cx(); let _ac = enter_realm(&*self); rooted!(in(*cx) let mut v = UndefinedValue()); unsafe { @@ -206,7 +206,7 @@ impl Promise { #[allow(unsafe_code)] pub fn reject_error(&self, error: Error) { - let cx = self.global().get_cx(); + let cx = GlobalScope::get_cx(); let _ac = enter_realm(&*self); rooted!(in(*cx) let mut v = UndefinedValue()); unsafe { @@ -245,7 +245,7 @@ impl Promise { #[allow(unsafe_code)] pub fn append_native_handler(&self, handler: &PromiseNativeHandler, _comp: InRealm) { let _ais = AutoEntryScript::new(&*handler.global()); - let cx = self.global().get_cx(); + let cx = GlobalScope::get_cx(); rooted!(in(*cx) let resolve_func = create_native_handler_function(*cx, handler.reflector().get_jsobject(), diff --git a/components/script/dom/readablestream.rs b/components/script/dom/readablestream.rs index 723e229916a..746f094045c 100644 --- a/components/script/dom/readablestream.rs +++ b/components/script/dom/readablestream.rs @@ -120,7 +120,7 @@ impl ReadableStream { ) -> DomRoot { let _ar = enter_realm(global); let _ais = AutoIncumbentScript::new(global); - let cx = global.get_cx(); + let cx = GlobalScope::get_cx(); let source = Rc::new(ExternalUnderlyingSourceController::new(source)); @@ -157,7 +157,7 @@ impl ReadableStream { pub fn enqueue_native(&self, bytes: Vec) { let global = self.global(); let _ar = enter_realm(&*global); - let cx = global.get_cx(); + let cx = GlobalScope::get_cx(); let handle = unsafe { self.js_stream.handle() }; @@ -171,7 +171,7 @@ impl ReadableStream { pub fn error_native(&self, error: Error) { let global = self.global(); let _ar = enter_realm(&*global); - let cx = global.get_cx(); + let cx = GlobalScope::get_cx(); unsafe { rooted!(in(*cx) let mut js_error = UndefinedValue()); @@ -188,7 +188,7 @@ impl ReadableStream { pub fn close_native(&self) { let global = self.global(); let _ar = enter_realm(&*global); - let cx = global.get_cx(); + let cx = GlobalScope::get_cx(); let handle = unsafe { self.js_stream.handle() }; @@ -223,7 +223,7 @@ impl ReadableStream { let global = self.global(); let _ar = enter_realm(&*global); - let cx = global.get_cx(); + let cx = GlobalScope::get_cx(); unsafe { rooted!(in(*cx) let reader = ReadableStreamGetReader( @@ -253,7 +253,7 @@ impl ReadableStream { let _ar = enter_realm(&*global); let _aes = AutoEntryScript::new(&*global); - let cx = global.get_cx(); + let cx = GlobalScope::get_cx(); unsafe { rooted!(in(*cx) let promise_obj = ReadableStreamDefaultReaderRead( @@ -276,7 +276,7 @@ impl ReadableStream { let global = self.global(); let _ar = enter_realm(&*global); - let cx = global.get_cx(); + let cx = GlobalScope::get_cx(); unsafe { ReadableStreamReaderReleaseLock(*cx, self.js_reader.handle()); @@ -293,7 +293,7 @@ impl ReadableStream { } // Otherwise, still double-check that script didn't lock the stream. - let cx = self.global().get_cx(); + let cx = GlobalScope::get_cx(); let mut locked_or_disturbed = false; unsafe { @@ -306,7 +306,7 @@ impl ReadableStream { #[allow(unsafe_code)] pub fn is_disturbed(&self) -> bool { // Check that script didn't disturb the stream. - let cx = self.global().get_cx(); + let cx = GlobalScope::get_cx(); let mut locked_or_disturbed = false; unsafe { diff --git a/components/script/dom/rtcdatachannel.rs b/components/script/dom/rtcdatachannel.rs index 052f3f13131..6fefea60812 100644 --- a/components/script/dom/rtcdatachannel.rs +++ b/components/script/dom/rtcdatachannel.rs @@ -135,7 +135,7 @@ impl RTCDataChannel { pub fn on_error(&self, error: WebRtcError) { let global = self.global(); - let cx = global.get_cx(); + let cx = GlobalScope::get_cx(); let _ac = JSAutoRealm::new(*cx, self.reflector().get_jsobject().get()); let init = RTCErrorInit { errorDetail: RTCErrorDetailType::Data_channel_failure, @@ -157,7 +157,7 @@ impl RTCDataChannel { pub fn on_message(&self, channel_message: DataChannelMessage) { unsafe { let global = self.global(); - let cx = global.get_cx(); + let cx = GlobalScope::get_cx(); let _ac = JSAutoRealm::new(*cx, self.reflector().get_jsobject().get()); rooted!(in(*cx) let mut message = UndefinedValue()); diff --git a/components/script/dom/rtcpeerconnection.rs b/components/script/dom/rtcpeerconnection.rs index 9fd651e5a16..2342dd6730e 100644 --- a/components/script/dom/rtcpeerconnection.rs +++ b/components/script/dom/rtcpeerconnection.rs @@ -548,7 +548,7 @@ impl RTCPeerConnectionMethods for RTCPeerConnection { /// https://w3c.github.io/webrtc-pc/#dom-rtcpeerconnection-addicecandidate fn AddIceCandidate(&self, candidate: &RTCIceCandidateInit, comp: InRealm) -> Rc { - let p = Promise::new_in_current_realm(&self.global(), comp); + let p = Promise::new_in_current_realm(comp); if candidate.sdpMid.is_none() && candidate.sdpMLineIndex.is_none() { p.reject_error(Error::Type(format!( "one of sdpMid and sdpMLineIndex must be set" @@ -583,7 +583,7 @@ impl RTCPeerConnectionMethods for RTCPeerConnection { /// https://w3c.github.io/webrtc-pc/#dom-rtcpeerconnection-createoffer fn CreateOffer(&self, _options: &RTCOfferOptions, comp: InRealm) -> Rc { - let p = Promise::new_in_current_realm(&self.global(), comp); + let p = Promise::new_in_current_realm(comp); if self.closed.get() { p.reject_error(Error::InvalidState); return p; @@ -595,7 +595,7 @@ impl RTCPeerConnectionMethods for RTCPeerConnection { /// https://w3c.github.io/webrtc-pc/#dom-rtcpeerconnection-createoffer fn CreateAnswer(&self, _options: &RTCAnswerOptions, comp: InRealm) -> Rc { - let p = Promise::new_in_current_realm(&self.global(), comp); + let p = Promise::new_in_current_realm(comp); if self.closed.get() { p.reject_error(Error::InvalidState); return p; @@ -618,7 +618,7 @@ impl RTCPeerConnectionMethods for RTCPeerConnection { /// https://w3c.github.io/webrtc-pc/#dom-rtcpeerconnection-setlocaldescription fn SetLocalDescription(&self, desc: &RTCSessionDescriptionInit, comp: InRealm) -> Rc { // XXXManishearth validate the current state - let p = Promise::new_in_current_realm(&self.global(), comp); + let p = Promise::new_in_current_realm(comp); let this = Trusted::new(self); let desc: SessionDescription = desc.into(); let trusted_promise = TrustedPromise::new(p.clone()); @@ -651,7 +651,7 @@ impl RTCPeerConnectionMethods for RTCPeerConnection { /// https://w3c.github.io/webrtc-pc/#dom-rtcpeerconnection-setremotedescription fn SetRemoteDescription(&self, desc: &RTCSessionDescriptionInit, comp: InRealm) -> Rc { // XXXManishearth validate the current state - let p = Promise::new_in_current_realm(&self.global(), comp); + let p = Promise::new_in_current_realm(comp); let this = Trusted::new(self); let desc: SessionDescription = desc.into(); let trusted_promise = TrustedPromise::new(p.clone()); diff --git a/components/script/dom/serviceworkercontainer.rs b/components/script/dom/serviceworkercontainer.rs index b65dcd59b7d..b02b72e2c5b 100644 --- a/components/script/dom/serviceworkercontainer.rs +++ b/components/script/dom/serviceworkercontainer.rs @@ -70,7 +70,7 @@ impl ServiceWorkerContainerMethods for ServiceWorkerContainer { let global = self.client.global(); // A: Step 1 - let promise = Promise::new_in_current_realm(&*global, comp); + let promise = Promise::new_in_current_realm(comp); let USVString(ref script_url) = script_url; // A: Step 3 diff --git a/components/script/dom/servoparser/mod.rs b/components/script/dom/servoparser/mod.rs index 9967da64556..c4b52a038ea 100644 --- a/components/script/dom/servoparser/mod.rs +++ b/components/script/dom/servoparser/mod.rs @@ -34,6 +34,7 @@ use crate::dom::processinginstruction::ProcessingInstruction; use crate::dom::text::Text; use crate::dom::virtualmethods::vtable_for; use crate::network_listener::PreInvoke; +use crate::realms::enter_realm; use crate::script_thread::ScriptThread; use content_security_policy::{self as csp, CspList}; use dom_struct::dom_struct; @@ -828,6 +829,8 @@ impl FetchResponseListener for ParserContext { return; } + let _realm = enter_realm(&*parser.document); + parser.document.set_csp_list(csp_list); self.parser = Some(Trusted::new(&*parser)); self.submit_resource_timing(); @@ -916,6 +919,7 @@ impl FetchResponseListener for ParserContext { if parser.aborted.get() { return; } + let _realm = enter_realm(&*parser); parser.parse_bytes_chunk(payload); } @@ -931,6 +935,8 @@ impl FetchResponseListener for ParserContext { return; } + let _realm = enter_realm(&*parser); + match status { // are we throwing this away or can we use it? Ok(_) => (), diff --git a/components/script/dom/testbinding.rs b/components/script/dom/testbinding.rs index 34c25c40449..b8d2fefc951 100644 --- a/components/script/dom/testbinding.rs +++ b/components/script/dom/testbinding.rs @@ -1005,7 +1005,7 @@ impl TestBindingMethods for TestBinding { resolve.map(SimpleHandler::new), reject.map(SimpleHandler::new), ); - let p = Promise::new_in_current_realm(&global, comp.clone()); + let p = Promise::new_in_current_realm(comp.clone()); p.append_native_handler(&handler, comp); return p; @@ -1028,7 +1028,7 @@ impl TestBindingMethods for TestBinding { } fn PromiseAttribute(&self, comp: InRealm) -> Rc { - Promise::new_in_current_realm(&self.global(), comp) + Promise::new_in_current_realm(comp) } fn AcceptPromise(&self, _promise: &Promise) {} diff --git a/components/script/dom/websocket.rs b/components/script/dom/websocket.rs index a3c9848ed9b..59b87d08987 100644 --- a/components/script/dom/websocket.rs +++ b/components/script/dom/websocket.rs @@ -554,9 +554,9 @@ impl TaskOnce for MessageReceivedTask { // Step 2-5. let global = ws.global(); - // global.get_cx() returns a valid `JSContext` pointer, so this is safe. + // GlobalScope::get_cx() returns a valid `JSContext` pointer, so this is safe. unsafe { - let cx = global.get_cx(); + let cx = GlobalScope::get_cx(); let _ac = JSAutoRealm::new(*cx, ws.reflector().get_jsobject().get()); rooted!(in(*cx) let mut message = UndefinedValue()); match self.message { diff --git a/components/script/dom/windowproxy.rs b/components/script/dom/windowproxy.rs index 35850f76092..9ae85a30fc6 100644 --- a/components/script/dom/windowproxy.rs +++ b/components/script/dom/windowproxy.rs @@ -165,7 +165,7 @@ impl WindowProxy { let WindowProxyHandler(handler) = window.windowproxy_handler(); assert!(!handler.is_null()); - let cx = window.get_cx(); + let cx = GlobalScope::get_cx(); let window_jsobject = window.reflector().get_jsobject(); assert!(!window_jsobject.get().is_null()); assert_ne!( @@ -225,7 +225,7 @@ impl WindowProxy { let handler = CreateWrapperProxyHandler(&XORIGIN_PROXY_HANDLER); assert!(!handler.is_null()); - let cx = global_to_clone_from.get_cx(); + let cx = GlobalScope::get_cx(); // Create a new browsing context. let window_proxy = Box::new(WindowProxy::new_inherited( @@ -624,7 +624,7 @@ impl WindowProxy { let handler = CreateWrapperProxyHandler(traps); assert!(!handler.is_null()); - let cx = window.get_cx(); + let cx = GlobalScope::get_cx(); let window_jsobject = window.reflector().get_jsobject(); let old_js_proxy = self.reflector.get_jsobject(); assert!(!window_jsobject.get().is_null()); diff --git a/components/script/dom/worker.rs b/components/script/dom/worker.rs index 563a04679ea..b9370f02914 100644 --- a/components/script/dom/worker.rs +++ b/components/script/dom/worker.rs @@ -169,7 +169,7 @@ impl Worker { let global = worker.global(); let target = worker.upcast(); let _ac = enter_realm(target); - rooted!(in(*global.get_cx()) let mut message = UndefinedValue()); + rooted!(in(*GlobalScope::get_cx()) let mut message = UndefinedValue()); if let Ok(ports) = structuredclone::read(&global, data, message.handle_mut()) { MessageEvent::dispatch_jsval(target, &global, message.handle(), None, None, ports); } else { @@ -247,7 +247,7 @@ impl WorkerMethods for Worker { self.terminated.set(true); // Step 3 - let cx = self.global().get_cx(); + let cx = GlobalScope::get_cx(); unsafe { JS_RequestInterruptCallback(*cx) }; } diff --git a/components/script/dom/worklet.rs b/components/script/dom/worklet.rs index d472696325a..7455e2a5775 100644 --- a/components/script/dom/worklet.rs +++ b/components/script/dom/worklet.rs @@ -130,8 +130,7 @@ impl WorkletMethods for Worklet { comp: InRealm, ) -> Rc { // Step 1. - let global = self.window.upcast(); - let promise = Promise::new_in_current_realm(&global, comp); + let promise = Promise::new_in_current_realm(comp); // Step 3. let module_url_record = match self.window.Document().base_url().join(&module_url.0) { diff --git a/components/script/dom/workletglobalscope.rs b/components/script/dom/workletglobalscope.rs index 29d5b9b7f99..96270b8fab8 100644 --- a/components/script/dom/workletglobalscope.rs +++ b/components/script/dom/workletglobalscope.rs @@ -85,14 +85,14 @@ impl WorkletGlobalScope { } /// Get the JS context. - pub fn get_cx(&self) -> JSContext { - self.globalscope.get_cx() + pub fn get_cx() -> JSContext { + GlobalScope::get_cx() } /// Evaluate a JS script in this global. pub fn evaluate_js(&self, script: &str) -> bool { debug!("Evaluating Dom in a worklet."); - rooted!(in (*self.globalscope.get_cx()) let mut rval = UndefinedValue()); + rooted!(in (*GlobalScope::get_cx()) let mut rval = UndefinedValue()); self.globalscope.evaluate_js_on_global_with_result( &*script, rval.handle_mut(), diff --git a/components/script/dom/xrinputsource.rs b/components/script/dom/xrinputsource.rs index 248fb6d737a..592ced2f10d 100644 --- a/components/script/dom/xrinputsource.rs +++ b/components/script/dom/xrinputsource.rs @@ -57,7 +57,7 @@ impl XRInputSource { ); let _ac = enter_realm(&*global); - let cx = global.get_cx(); + let cx = GlobalScope::get_cx(); unsafe { rooted!(in(*cx) let mut profiles = UndefinedValue()); source.info.profiles.to_jsval(*cx, profiles.handle_mut()); diff --git a/components/script/dom/xrinputsourceschangeevent.rs b/components/script/dom/xrinputsourceschangeevent.rs index d23c5ea4157..99e5da7ead7 100644 --- a/components/script/dom/xrinputsourceschangeevent.rs +++ b/components/script/dom/xrinputsourceschangeevent.rs @@ -63,7 +63,7 @@ impl XRInputSourcesChangeEvent { event.init_event(type_, bubbles, cancelable); } let _ac = enter_realm(&*global); - let cx = global.get_cx(); + let cx = GlobalScope::get_cx(); unsafe { rooted!(in(*cx) let mut added_val = UndefinedValue()); added.to_jsval(*cx, added_val.handle_mut()); diff --git a/components/script/dom/xrray.rs b/components/script/dom/xrray.rs index cb5e29d9c62..781ff6a396b 100644 --- a/components/script/dom/xrray.rs +++ b/components/script/dom/xrray.rs @@ -116,7 +116,7 @@ impl XRRayMethods for XRRay { // https://immersive-web.github.io/hit-test/#xrray-obtain-the-matrix // Step 1 if self.matrix.get().is_null() { - let cx = self.global().get_cx(); + let cx = GlobalScope::get_cx(); // Step 2 let z = Vector3D::new(0., 0., -1.); // Step 3 diff --git a/components/script/dom/xrrigidtransform.rs b/components/script/dom/xrrigidtransform.rs index 0488d4584eb..00909e1fe1c 100644 --- a/components/script/dom/xrrigidtransform.rs +++ b/components/script/dom/xrrigidtransform.rs @@ -117,7 +117,7 @@ impl XRRigidTransformMethods for XRRigidTransform { // https://immersive-web.github.io/webxr/#dom-xrrigidtransform-matrix fn Matrix(&self, _cx: JSContext) -> NonNull { if self.matrix.get().is_null() { - let cx = self.global().get_cx(); + let cx = GlobalScope::get_cx(); // According to the spec all matrices are column-major, // however euclid uses row vectors so we use .to_array() let arr = self.transform.to_transform().to_array(); diff --git a/components/script/dom/xrsession.rs b/components/script/dom/xrsession.rs index 01b21379ce3..73f2bc4ce88 100644 --- a/components/script/dom/xrsession.rs +++ b/components/script/dom/xrsession.rs @@ -757,7 +757,7 @@ impl XRSessionMethods for XRSession { /// https://immersive-web.github.io/webxr/#dom-xrsession-requestreferencespace fn RequestReferenceSpace(&self, ty: XRReferenceSpaceType, comp: InRealm) -> Rc { - let p = Promise::new_in_current_realm(&self.global(), comp); + let p = Promise::new_in_current_realm(comp); // https://immersive-web.github.io/webxr/#create-a-reference-space diff --git a/components/script/dom/xrsystem.rs b/components/script/dom/xrsystem.rs index 23235c1d95a..15e4f9e65f4 100644 --- a/components/script/dom/xrsystem.rs +++ b/components/script/dom/xrsystem.rs @@ -14,6 +14,7 @@ use crate::dom::bindings::root::{Dom, DomRoot, MutNullableDom}; use crate::dom::bindings::trace::RootedTraceableBox; use crate::dom::eventtarget::EventTarget; use crate::dom::gamepad::Gamepad; +use crate::dom::globalscope::GlobalScope; use crate::dom::promise::Promise; use crate::dom::window::Window; use crate::dom::xrsession::XRSession; @@ -158,7 +159,7 @@ impl XRSystemMethods for XRSystem { ) -> Rc { let global = self.global(); let window = global.as_window(); - let promise = Promise::new_in_current_realm(&global, comp); + let promise = Promise::new_in_current_realm(comp); if mode != XRSessionMode::Inline { if !ScriptThread::is_user_interacting() { @@ -180,7 +181,7 @@ impl XRSystemMethods for XRSystem { let mut required_features = vec![]; let mut optional_features = vec![]; - let cx = global.get_cx(); + let cx = GlobalScope::get_cx(); // We are supposed to include "viewer" and on immersive devices "local" // by default here, but this is handled directly in requestReferenceSpace() diff --git a/components/script/dom/xrview.rs b/components/script/dom/xrview.rs index a5972e26955..b849b1d03ba 100644 --- a/components/script/dom/xrview.rs +++ b/components/script/dom/xrview.rs @@ -3,7 +3,6 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ use crate::dom::bindings::codegen::Bindings::XRViewBinding::{XREye, XRViewMethods}; -use crate::dom::bindings::reflector::DomObject; use crate::dom::bindings::reflector::{reflect_dom_object, Reflector}; use crate::dom::bindings::root::{Dom, DomRoot}; use crate::dom::bindings::utils::create_typed_array; @@ -90,7 +89,7 @@ impl XRViewMethods for XRView { /// https://immersive-web.github.io/webxr/#dom-xrview-projectionmatrix fn ProjectionMatrix(&self, _cx: JSContext) -> NonNull { if self.proj.get().is_null() { - let cx = self.global().get_cx(); + let cx = GlobalScope::get_cx(); // row_major since euclid uses row vectors let proj = self.view.projection.to_array(); create_typed_array(cx, &proj, &self.proj); diff --git a/components/script/dom/xrviewerpose.rs b/components/script/dom/xrviewerpose.rs index 7a2f4a6b441..e9b072e5e5d 100644 --- a/components/script/dom/xrviewerpose.rs +++ b/components/script/dom/xrviewerpose.rs @@ -154,7 +154,7 @@ impl XRViewerPose { let transform = XRRigidTransform::new(global, cast_transform(transform)); let pose = reflect_dom_object(Box::new(XRViewerPose::new_inherited(&transform)), global); - let cx = global.get_cx(); + let cx = GlobalScope::get_cx(); unsafe { rooted!(in(*cx) let mut jsval = UndefinedValue()); views.to_jsval(*cx, jsval.handle_mut()); diff --git a/components/script/fetch.rs b/components/script/fetch.rs index 4889d6f138c..9487e7c8717 100644 --- a/components/script/fetch.rs +++ b/components/script/fetch.rs @@ -142,7 +142,7 @@ pub fn Fetch( let core_resource_thread = global.core_resource_thread(); // Step 1 - let promise = Promise::new_in_current_realm(global, comp); + let promise = Promise::new_in_current_realm(comp); let response = Response::new(global); // Step 2 diff --git a/components/script/microtask.rs b/components/script/microtask.rs index b97368fcad5..10322bb2fef 100644 --- a/components/script/microtask.rs +++ b/components/script/microtask.rs @@ -15,9 +15,10 @@ use crate::dom::globalscope::GlobalScope; use crate::dom::htmlimageelement::ImageElementMicrotask; use crate::dom::htmlmediaelement::MediaElementMicrotask; use crate::dom::mutationobserver::MutationObserver; +use crate::realms::enter_realm; use crate::script_runtime::{notify_about_rejected_promises, JSContext}; use crate::script_thread::ScriptThread; -use js::jsapi::{JobQueueIsEmpty, JobQueueMayNotBeEmpty}; +use js::jsapi::{JSAutoRealm, JobQueueIsEmpty, JobQueueMayNotBeEmpty}; use msg::constellation_msg::PipelineId; use std::cell::Cell; use std::mem; @@ -44,6 +45,7 @@ pub enum Microtask { pub trait MicrotaskRunnable { fn handler(&self) {} + fn enter_realm(&self) -> JSAutoRealm; } /// A promise callback scheduled to run during the next microtask checkpoint (#4283). @@ -108,19 +110,23 @@ impl MicrotaskQueue { if let Some(target) = target_provider(job.pipeline) { let was_interacting = ScriptThread::is_user_interacting(); ScriptThread::set_user_interacting(job.is_user_interacting); + let _realm = enter_realm(&*target); let _ = job.callback.Call_(&*target, ExceptionHandling::Report); ScriptThread::set_user_interacting(was_interacting); } }, Microtask::User(ref job) => { if let Some(target) = target_provider(job.pipeline) { + let _realm = enter_realm(&*target); let _ = job.callback.Call_(&*target, ExceptionHandling::Report); } }, Microtask::MediaElement(ref task) => { + let _realm = task.enter_realm(); task.handler(); }, Microtask::ImageElement(ref task) => { + let _realm = task.enter_realm(); task.handler(); }, Microtask::CustomElementReaction => { diff --git a/components/script/realms.rs b/components/script/realms.rs index 280e615e412..48b141aae56 100644 --- a/components/script/realms.rs +++ b/components/script/realms.rs @@ -11,9 +11,9 @@ pub struct AlreadyInRealm(()); impl AlreadyInRealm { #![allow(unsafe_code)] - pub fn assert(global: &GlobalScope) -> AlreadyInRealm { + pub fn assert() -> AlreadyInRealm { unsafe { - assert!(!GetCurrentRealmOrNull(*global.get_cx()).is_null()); + assert!(!GetCurrentRealmOrNull(*GlobalScope::get_cx()).is_null()); } AlreadyInRealm(()) } @@ -44,7 +44,7 @@ impl<'a> InRealm<'a> { pub fn enter_realm(object: &impl DomObject) -> JSAutoRealm { JSAutoRealm::new( - *object.global().get_cx(), + *GlobalScope::get_cx(), object.reflector().get_jsobject().get(), ) } diff --git a/components/script/script_module.rs b/components/script/script_module.rs index c13fbc3aeb8..9ba8dd523a0 100644 --- a/components/script/script_module.rs +++ b/components/script/script_module.rs @@ -81,8 +81,8 @@ use uuid::Uuid; #[allow(unsafe_code)] unsafe fn gen_type_error(global: &GlobalScope, string: String) -> RethrowError { - rooted!(in(*global.get_cx()) let mut thrown = UndefinedValue()); - Error::Type(string).to_jsval(*global.get_cx(), &global, thrown.handle_mut()); + rooted!(in(*GlobalScope::get_cx()) let mut thrown = UndefinedValue()); + Error::Type(string).to_jsval(*GlobalScope::get_cx(), &global, thrown.handle_mut()); return RethrowError(RootedTraceableBox::from_box(Heap::boxed(thrown.get()))); } @@ -357,7 +357,7 @@ impl ModuleTree { match promise.as_ref() { Some(promise) => promise.append_native_handler(&handler, comp), None => { - let new_promise = Promise::new_in_current_realm(&owner.global(), comp); + let new_promise = Promise::new_in_current_realm(comp); new_promise.append_native_handler(&handler, comp); *promise = Some(new_promise); }, @@ -393,7 +393,7 @@ impl ModuleTree { match promise.as_ref() { Some(promise) => promise.append_native_handler(&handler, comp), None => { - let new_promise = Promise::new_in_current_realm(&owner.global(), comp); + let new_promise = Promise::new_in_current_realm(comp); new_promise.append_native_handler(&handler, comp); *promise = Some(new_promise); }, @@ -421,14 +421,14 @@ impl ModuleTree { url: ServoUrl, options: ScriptFetchOptions, ) -> Result { - let _ac = JSAutoRealm::new(*global.get_cx(), *global.reflector().get_jsobject()); + let cx = GlobalScope::get_cx(); + let _ac = JSAutoRealm::new(*cx, *global.reflector().get_jsobject()); - let compile_options = - unsafe { CompileOptionsWrapper::new(*global.get_cx(), url.as_str(), 1) }; + let compile_options = unsafe { CompileOptionsWrapper::new(*cx, url.as_str(), 1) }; unsafe { - rooted!(in(*global.get_cx()) let mut module_script = CompileModule1( - *global.get_cx(), + rooted!(in(*cx) let mut module_script = CompileModule1( + *cx, compile_options.ptr, &mut transform_str_to_source_text(&module_script_text), )); @@ -436,12 +436,9 @@ impl ModuleTree { if module_script.is_null() { warn!("fail to compile module script of {}", url); - rooted!(in(*global.get_cx()) let mut exception = UndefinedValue()); - assert!(JS_GetPendingException( - *global.get_cx(), - &mut exception.handle_mut() - )); - JS_ClearPendingException(*global.get_cx()); + rooted!(in(*cx) let mut exception = UndefinedValue()); + assert!(JS_GetPendingException(*cx, &mut exception.handle_mut())); + JS_ClearPendingException(*cx); return Err(RethrowError(RootedTraceableBox::from_box(Heap::boxed( exception.get(), @@ -474,18 +471,16 @@ impl ModuleTree { global: &GlobalScope, module_record: HandleObject, ) -> Result<(), RethrowError> { - let _ac = JSAutoRealm::new(*global.get_cx(), *global.reflector().get_jsobject()); + let cx = GlobalScope::get_cx(); + let _ac = JSAutoRealm::new(*cx, *global.reflector().get_jsobject()); unsafe { - if !ModuleLink(*global.get_cx(), module_record) { + if !ModuleLink(*cx, module_record) { warn!("fail to link & instantiate module"); - rooted!(in(*global.get_cx()) let mut exception = UndefinedValue()); - assert!(JS_GetPendingException( - *global.get_cx(), - &mut exception.handle_mut() - )); - JS_ClearPendingException(*global.get_cx()); + rooted!(in(*cx) let mut exception = UndefinedValue()); + assert!(JS_GetPendingException(*cx, &mut exception.handle_mut())); + JS_ClearPendingException(*cx); Err(RethrowError(RootedTraceableBox::from_box(Heap::boxed( exception.get(), @@ -505,7 +500,7 @@ impl ModuleTree { module_record: HandleObject, eval_result: MutableHandleValue, ) -> Result<(), RethrowError> { - let cx = global.get_cx(); + let cx = GlobalScope::get_cx(); let _ac = JSAutoRealm::new(*cx, *global.reflector().get_jsobject()); unsafe { @@ -547,11 +542,11 @@ impl ModuleTree { unsafe { let ar = enter_realm(&*global); JS_SetPendingException( - *global.get_cx(), + *GlobalScope::get_cx(), exception.handle(), ExceptionStackBehavior::Capture, ); - report_pending_exception(*global.get_cx(), true, InRealm::Entered(&ar)); + report_pending_exception(*GlobalScope::get_cx(), true, InRealm::Entered(&ar)); } } } @@ -563,16 +558,17 @@ impl ModuleTree { module_object: HandleObject, base_url: ServoUrl, ) -> Result, RethrowError> { - let _ac = JSAutoRealm::new(*global.get_cx(), *global.reflector().get_jsobject()); + let cx = GlobalScope::get_cx(); + let _ac = JSAutoRealm::new(*cx, *global.reflector().get_jsobject()); let mut specifier_urls = IndexSet::new(); unsafe { - rooted!(in(*global.get_cx()) let requested_modules = GetRequestedModules(*global.get_cx(), module_object)); + rooted!(in(*cx) let requested_modules = GetRequestedModules(*cx, module_object)); let mut length = 0; - if !GetArrayLength(*global.get_cx(), requested_modules.handle(), &mut length) { + if !GetArrayLength(*cx, requested_modules.handle(), &mut length) { let module_length_error = gen_type_error(&global, "Wrong length of requested modules".to_owned()); @@ -580,10 +576,10 @@ impl ModuleTree { } for index in 0..length { - rooted!(in(*global.get_cx()) let mut element = UndefinedValue()); + rooted!(in(*cx) let mut element = UndefinedValue()); if !JS_GetElement( - *global.get_cx(), + *cx, requested_modules.handle(), index, &mut element.handle_mut(), @@ -594,12 +590,12 @@ impl ModuleTree { return Err(get_element_error); } - rooted!(in(*global.get_cx()) let specifier = GetRequestedModuleSpecifier( - *global.get_cx(), element.handle() + rooted!(in(*cx) let specifier = GetRequestedModuleSpecifier( + *cx, element.handle() )); let url = ModuleTree::resolve_module_specifier( - *global.get_cx(), + *cx, &base_url, specifier.handle().into_handle(), ); @@ -976,7 +972,7 @@ impl ModuleOwner { let module = global.dynamic_module_list().remove(dynamic_module_id); - let cx = global.get_cx(); + let cx = GlobalScope::get_cx(); let module_tree = module_identity.get_module_tree(&global); // In the timing of executing this `finish_dynamic_module` function, @@ -986,7 +982,7 @@ impl ModuleOwner { let network_error = module_tree.get_network_error().borrow().as_ref().cloned(); let existing_rethrow_error = module_tree.get_rethrow_error().borrow().as_ref().cloned(); - rooted!(in(*global.get_cx()) let mut rval = UndefinedValue()); + rooted!(in(*cx) let mut rval = UndefinedValue()); if network_error.is_none() && existing_rethrow_error.is_none() { let record = module_tree .get_record() @@ -1355,7 +1351,7 @@ fn fetch_an_import_module_script_graph( promise: Rc, ) -> Result<(), RethrowError> { // Step 1. - let cx = global.get_cx(); + let cx = GlobalScope::get_cx(); rooted!(in(*cx) let specifier = unsafe { GetModuleRequestSpecifier(*cx, module_request) }); let url = ModuleTree::resolve_module_specifier(*cx, &base_url, specifier.handle().into()); @@ -1428,9 +1424,9 @@ unsafe extern "C" fn HostResolveImportedModule( } // Step 5. - rooted!(in(*global_scope.get_cx()) let specifier = GetModuleRequestSpecifier(cx, specifier)); + rooted!(in(*GlobalScope::get_cx()) let specifier = GetModuleRequestSpecifier(cx, specifier)); let url = ModuleTree::resolve_module_specifier( - *global_scope.get_cx(), + *GlobalScope::get_cx(), &base_url, specifier.handle().into(), ); diff --git a/components/script/script_runtime.rs b/components/script/script_runtime.rs index d9566f6b204..59cbdc77ba3 100644 --- a/components/script/script_runtime.rs +++ b/components/script/script_runtime.rs @@ -297,7 +297,7 @@ unsafe extern "C" fn promise_rejection_tracker( global.dom_manipulation_task_source().queue( task!(rejection_handled_event: move || { let target = target.root(); - let cx = target.global().get_cx(); + let cx = GlobalScope::get_cx(); let root_promise = trusted_promise.root(); rooted!(in(*cx) let mut reason = UndefinedValue()); @@ -324,7 +324,7 @@ unsafe extern "C" fn promise_rejection_tracker( #[allow(unsafe_code, unrooted_must_root)] /// https://html.spec.whatwg.org/multipage/#notify-about-rejected-promises pub fn notify_about_rejected_promises(global: &GlobalScope) { - let cx = global.get_cx(); + let cx = GlobalScope::get_cx(); unsafe { // Step 2. if global.get_uncaught_rejections().borrow().len() > 0 { @@ -350,7 +350,7 @@ pub fn notify_about_rejected_promises(global: &GlobalScope) { global.dom_manipulation_task_source().queue( task!(unhandled_rejection_event: move || { let target = target.root(); - let cx = target.global().get_cx(); + let cx = GlobalScope::get_cx(); for promise in uncaught_rejections { let promise = promise.root(); diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs index 89b4ceab185..96ea03881d4 100644 --- a/components/script/script_thread.rs +++ b/components/script/script_thread.rs @@ -1473,6 +1473,12 @@ impl ScriptThread { let mut mouse_move_event_index = None; let mut animation_ticks = HashSet::new(); loop { + let pipeline_id = self.message_to_pipeline(&event); + let _realm = pipeline_id.map(|id| { + let global = self.documents.borrow().find_global(id); + global.map(|global| enter_realm(&*global)) + }); + // https://html.spec.whatwg.org/multipage/#event-loop-processing-model step 7 match event { // This has to be handled before the ResizeMsg below, @@ -1592,6 +1598,11 @@ impl ScriptThread { let category = self.categorize_msg(&msg); let pipeline_id = self.message_to_pipeline(&msg); + let _realm = pipeline_id.and_then(|id| { + let global = self.documents.borrow().find_global(id); + global.map(|global| enter_realm(&*global)) + }); + if self.closing.load(Ordering::SeqCst) { // If we've received the closed signal from the BHM, only handle exit messages. match msg { @@ -1638,6 +1649,7 @@ impl ScriptThread { // https://html.spec.whatwg.org/multipage/#the-end step 6 let mut docs = self.docs_with_no_blocking_loads.borrow_mut(); for document in docs.iter() { + let _realm = enter_realm(&**document); document.maybe_queue_document_completion(); } docs.clear(); @@ -1656,6 +1668,8 @@ impl ScriptThread { } let window = document.window(); + let _realm = enter_realm(&*document); + window .upcast::() .perform_a_dom_garbage_collection_checkpoint(); @@ -1684,6 +1698,7 @@ impl ScriptThread { } for (_, document) in self.documents.borrow().iter() { + let _realm = enter_realm(&*document); document.animations().send_pending_events(document.window()); } } @@ -1756,7 +1771,9 @@ impl ScriptThread { MixedMessage::FromConstellation(ref inner_msg) => match *inner_msg { StopDelayingLoadEventsMode(id) => Some(id), NavigationResponse(id, _) => Some(id), - AttachLayout(ref new_layout_info) => Some(new_layout_info.new_pipeline_id), + AttachLayout(ref new_layout_info) => new_layout_info + .parent_info + .or(Some(new_layout_info.new_pipeline_id)), Resize(id, ..) => Some(id), ResizeInactive(id, ..) => Some(id), UnloadDocument(id) => Some(id), @@ -1786,7 +1803,7 @@ impl ScriptThread { DispatchStorageEvent(id, ..) => Some(id), ReportCSSError(id, ..) => Some(id), Reload(id, ..) => Some(id), - PaintMetric(..) => None, + PaintMetric(id, ..) => Some(id), ExitFullScreen(id, ..) => Some(id), MediaSessionAction(..) => None, SetWebGPUPort(..) => None, @@ -2070,7 +2087,13 @@ impl ScriptThread { fn handle_msg_from_script(&self, msg: MainThreadScriptMsg) { match msg { - MainThreadScriptMsg::Common(CommonScriptMsg::Task(_, task, _, _)) => task.run_box(), + MainThreadScriptMsg::Common(CommonScriptMsg::Task(_, task, pipeline_id, _)) => { + let _realm = pipeline_id.and_then(|id| { + let global = self.documents.borrow().find_global(id); + global.map(|global| enter_realm(&*global)) + }); + task.run_box() + }, MainThreadScriptMsg::Common(CommonScriptMsg::CollectReports(chan)) => { self.collect_reports(chan) }, @@ -3277,6 +3300,8 @@ impl ScriptThread { incomplete.inherited_secure_context, ); + let _realm = enter_realm(&*window); + // Initialize the browsing context for the window. let window_proxy = self.local_window_proxy( &window, @@ -3460,6 +3485,8 @@ impl ScriptThread { ); } + let _realm = enter_realm(&*window); + // Assuming all CompositionEvent are generated by user interactions. ScriptThread::set_user_interacting(true); match event { @@ -3697,7 +3724,7 @@ impl ScriptThread { // Script source is ready to be evaluated (11.) let _ac = enter_realm(global_scope); - rooted!(in(*global_scope.get_cx()) let mut jsval = UndefinedValue()); + rooted!(in(*GlobalScope::get_cx()) let mut jsval = UndefinedValue()); global_scope.evaluate_js_on_global_with_result( &script_source, jsval.handle_mut(), @@ -3708,7 +3735,7 @@ impl ScriptThread { load_data.js_eval_result = if jsval.get().is_string() { unsafe { let strval = DOMString::from_jsval( - *global_scope.get_cx(), + *GlobalScope::get_cx(), jsval.handle(), StringificationBehavior::Empty, ); @@ -3978,7 +4005,7 @@ impl ScriptThread { .documents .borrow() .iter() - .map(|(_id, document)| document.global()) + .map(|(_id, document)| DomRoot::from_ref(document.window().upcast())) .collect(); self.microtask_queue.checkpoint( diff --git a/components/script/timers.rs b/components/script/timers.rs index ebc0bd8874c..5078bc1e788 100644 --- a/components/script/timers.rs +++ b/components/script/timers.rs @@ -540,7 +540,7 @@ impl JsTimerTask { match self.callback { InternalTimerCallback::StringTimerCallback(ref code_str) => { let global = this.global(); - let cx = global.get_cx(); + let cx = GlobalScope::get_cx(); rooted!(in(*cx) let mut rval = UndefinedValue()); // FIXME(cybai): Use base url properly by saving private reference for timers (#27260) global.evaluate_js_on_global_with_result(