diff options
24 files changed, 168 insertions, 119 deletions
diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index 164c2cb564b..e9c268d5555 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -693,7 +693,7 @@ impl Document { self.activity.get() != DocumentActivity::Inactive } - pub fn set_activity(&self, activity: DocumentActivity) { + pub fn set_activity(&self, activity: DocumentActivity, can_gc: CanGc) { // This function should only be called on documents with a browsing context assert!(self.has_browsing_context); if activity == self.activity.get() { @@ -751,6 +751,7 @@ impl Document { false, // bubbles false, // cancelable true, // persisted + can_gc, ); let event = event.upcast::<Event>(); event.set_trusted(true); @@ -2256,7 +2257,7 @@ impl Document { } // https://html.spec.whatwg.org/multipage/#unload-a-document - pub fn unload(&self, recursive_flag: bool) { + pub fn unload(&self, recursive_flag: bool, can_gc: CanGc) { // TODO: Step 1, increase the event loop's termination nesting level by 1. // Step 2 self.incr_ignore_opens_during_unload_counter(); @@ -2272,6 +2273,7 @@ impl Document { false, // bubbles false, // cancelable self.salvageable.get(), // persisted + can_gc, ); let event = event.upcast::<Event>(); event.set_trusted(true); @@ -2286,7 +2288,7 @@ impl Document { atom!("unload"), EventBubbles::Bubbles, EventCancelable::Cancelable, - CanGc::note(), + can_gc, ); event.set_trusted(true); let event_target = self.window.upcast::<EventTarget>(); @@ -2305,7 +2307,7 @@ impl Document { for iframe in self.iter_iframes() { // TODO: handle the case of cross origin iframes. let document = document_from_node(&*iframe); - document.unload(true); + document.unload(true, can_gc); if !document.salvageable() { self.salvageable.set(false); } @@ -2422,6 +2424,7 @@ impl Document { false, // bubbles false, // cancelable false, // persisted + can_gc, ); let event = event.upcast::<Event>(); event.set_trusted(true); diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index 64a6cb755b0..78cf0960b00 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -1896,7 +1896,7 @@ impl Element { // See https://github.com/w3c/DOM-Parsing/issues/61. let context_document = { if let Some(template) = self.downcast::<HTMLTemplateElement>() { - template.Content(CanGc::note()).upcast::<Node>().owner_doc() + template.Content(can_gc).upcast::<Node>().owner_doc() } else { document_from_node(self) } @@ -2674,7 +2674,7 @@ impl ElementMethods for Element { } // Step 1. - let frag = self.parse_fragment(value, CanGc::note())?; + let frag = self.parse_fragment(value, can_gc)?; Node::replace_all(Some(frag.upcast()), &target); Ok(()) @@ -2723,7 +2723,7 @@ impl ElementMethods for Element { }; // Step 5. - let frag = parent.parse_fragment(value, CanGc::note())?; + let frag = parent.parse_fragment(value, can_gc)?; // Step 6. context_parent.ReplaceChild(frag.upcast(), context_node)?; Ok(()) diff --git a/components/script/dom/gamepad.rs b/components/script/dom/gamepad.rs index 87f6a01a8df..75c4c1c8b2a 100644 --- a/components/script/dom/gamepad.rs +++ b/components/script/dom/gamepad.rs @@ -98,6 +98,7 @@ impl Gamepad { button_bounds: (f64, f64), supported_haptic_effects: GamepadSupportedHapticEffects, xr: bool, + can_gc: CanGc, ) -> DomRoot<Gamepad> { Self::new_with_proto( global, @@ -108,6 +109,7 @@ impl Gamepad { button_bounds, supported_haptic_effects, xr, + can_gc, ) } @@ -126,6 +128,7 @@ impl Gamepad { button_bounds: (f64, f64), supported_haptic_effects: GamepadSupportedHapticEffects, xr: bool, + can_gc: CanGc, ) -> DomRoot<Gamepad> { let button_list = GamepadButtonList::init_buttons(global); let vibration_actuator = @@ -148,7 +151,7 @@ impl Gamepad { )), global, None, - CanGc::note(), + can_gc, ); gamepad.init_axes(); gamepad diff --git a/components/script/dom/globalscope.rs b/components/script/dom/globalscope.rs index 4762a10c683..9c79628464c 100644 --- a/components/script/dom/globalscope.rs +++ b/components/script/dom/globalscope.rs @@ -532,7 +532,7 @@ impl TimerListener { }, }; // Step 7, substeps run in a task. - global.fire_timer(id); + global.fire_timer(id, CanGc::note()); }), &self.canceller, ); @@ -2893,8 +2893,8 @@ impl GlobalScope { } } - pub fn fire_timer(&self, handle: TimerEventId) { - self.timers.fire_timer(handle, self); + pub fn fire_timer(&self, handle: TimerEventId, can_gc: CanGc) { + self.timers.fire_timer(handle, self, can_gc); } pub fn resume(&self) { @@ -3208,7 +3208,7 @@ impl GlobalScope { } } - pub fn handle_gamepad_event(&self, gamepad_event: GamepadEvent) { + pub fn handle_gamepad_event(&self, gamepad_event: GamepadEvent, can_gc: CanGc) { match gamepad_event { GamepadEvent::Connected(index, name, bounds, supported_haptic_effects) => { self.handle_gamepad_connect( @@ -3217,6 +3217,7 @@ impl GlobalScope { bounds.axis_bounds, bounds.button_bounds, supported_haptic_effects, + can_gc, ); }, GamepadEvent::Disconnected(index) => { @@ -3239,6 +3240,7 @@ impl GlobalScope { axis_bounds: (f64, f64), button_bounds: (f64, f64), supported_haptic_effects: GamepadSupportedHapticEffects, + can_gc: CanGc, ) { // TODO: 2. If document is not null and is not allowed to use the "gamepad" permission, // then abort these steps. @@ -3259,7 +3261,8 @@ impl GlobalScope { axis_bounds, button_bounds, supported_haptic_effects, - false + false, + can_gc, ); navigator.set_gamepad(selected_index as usize, &gamepad); } diff --git a/components/script/dom/gpu.rs b/components/script/dom/gpu.rs index 5d688478491..02c8179e520 100644 --- a/components/script/dom/gpu.rs +++ b/components/script/dom/gpu.rs @@ -25,6 +25,7 @@ use crate::dom::globalscope::GlobalScope; use crate::dom::gpuadapter::GPUAdapter; use crate::dom::promise::Promise; use crate::realms::InRealm; +use crate::script_runtime::CanGc; use crate::task_source::{TaskSource, TaskSourceName}; #[dom_struct] @@ -46,7 +47,7 @@ impl GPU { } pub trait AsyncWGPUListener { - fn handle_response(&self, response: WebGPUResponse, promise: &Rc<Promise>); + fn handle_response(&self, response: WebGPUResponse, promise: &Rc<Promise>, can_gc: CanGc); } struct WGPUResponse<T: AsyncWGPUListener + DomObject> { @@ -56,9 +57,11 @@ struct WGPUResponse<T: AsyncWGPUListener + DomObject> { impl<T: AsyncWGPUListener + DomObject> WGPUResponse<T> { #[allow(crown::unrooted_must_root)] - fn response(self, response: WebGPUResponse) { + fn response(self, response: WebGPUResponse, can_gc: CanGc) { let promise = self.trusted.root(); - self.receiver.root().handle_response(response, &promise); + self.receiver + .root() + .handle_response(response, &promise, can_gc); } } @@ -89,7 +92,7 @@ pub fn response_async<T: AsyncWGPUListener + DomObject + 'static>( }; let result = task_source.queue_with_canceller( task!(process_webgpu_task: move|| { - context.response(message.to().unwrap()); + context.response(message.to().unwrap(), CanGc::note()); }), &canceller, ); @@ -140,7 +143,7 @@ impl GPUMethods for GPU { } impl AsyncWGPUListener for GPU { - fn handle_response(&self, response: WebGPUResponse, promise: &Rc<Promise>) { + fn handle_response(&self, response: WebGPUResponse, promise: &Rc<Promise>, _can_gc: CanGc) { match response { WebGPUResponse::Adapter(Ok(adapter)) => { let adapter = GPUAdapter::new( diff --git a/components/script/dom/gpuadapter.rs b/components/script/dom/gpuadapter.rs index ff43baab82c..1643820f972 100644 --- a/components/script/dom/gpuadapter.rs +++ b/components/script/dom/gpuadapter.rs @@ -27,6 +27,7 @@ use crate::dom::gpudevice::GPUDevice; use crate::dom::gpusupportedfeatures::gpu_to_wgt_feature; use crate::dom::promise::Promise; use crate::realms::InRealm; +use crate::script_runtime::CanGc; #[dom_struct] pub struct GPUAdapter { @@ -194,7 +195,7 @@ impl GPUAdapterMethods for GPUAdapter { } impl AsyncWGPUListener for GPUAdapter { - fn handle_response(&self, response: WebGPUResponse, promise: &Rc<Promise>) { + fn handle_response(&self, response: WebGPUResponse, promise: &Rc<Promise>, _can_gc: CanGc) { match response { WebGPUResponse::Device((device_id, queue_id, Ok(descriptor))) => { let device = GPUDevice::new( diff --git a/components/script/dom/gpubuffer.rs b/components/script/dom/gpubuffer.rs index 1708f46de3c..3b6f8eb6fe3 100644 --- a/components/script/dom/gpubuffer.rs +++ b/components/script/dom/gpubuffer.rs @@ -29,7 +29,7 @@ use crate::dom::gpu::{response_async, AsyncWGPUListener}; use crate::dom::gpudevice::GPUDevice; use crate::dom::promise::Promise; use crate::realms::InRealm; -use crate::script_runtime::JSContext; +use crate::script_runtime::{CanGc, JSContext}; #[derive(JSTraceable, MallocSizeOf)] pub struct ActiveBufferMapping { @@ -413,7 +413,7 @@ impl GPUBuffer { impl AsyncWGPUListener for GPUBuffer { #[allow(unsafe_code)] - fn handle_response(&self, response: WebGPUResponse, promise: &Rc<Promise>) { + fn handle_response(&self, response: WebGPUResponse, promise: &Rc<Promise>, _can_gc: CanGc) { match response { WebGPUResponse::BufferMapAsync(Ok(mapping)) => self.map_success(promise, mapping), WebGPUResponse::BufferMapAsync(Err(_)) => self.map_failure(promise), diff --git a/components/script/dom/gpucompilationinfo.rs b/components/script/dom/gpucompilationinfo.rs index 186850effea..ee0049260db 100644 --- a/components/script/dom/gpucompilationinfo.rs +++ b/components/script/dom/gpucompilationinfo.rs @@ -31,16 +31,19 @@ impl GPUCompilationInfo { } #[allow(dead_code)] - pub fn new(global: &GlobalScope, msg: Vec<DomRoot<GPUCompilationMessage>>) -> DomRoot<Self> { - reflect_dom_object_with_proto( - Box::new(Self::new_inherited(msg)), - global, - None, - CanGc::note(), - ) + pub fn new( + global: &GlobalScope, + msg: Vec<DomRoot<GPUCompilationMessage>>, + can_gc: CanGc, + ) -> DomRoot<Self> { + reflect_dom_object_with_proto(Box::new(Self::new_inherited(msg)), global, None, can_gc) } - pub fn from(global: &GlobalScope, error: Option<ShaderCompilationInfo>) -> DomRoot<Self> { + pub fn from( + global: &GlobalScope, + error: Option<ShaderCompilationInfo>, + can_gc: CanGc, + ) -> DomRoot<Self> { Self::new( global, if let Some(error) = error { @@ -48,6 +51,7 @@ impl GPUCompilationInfo { } else { Vec::new() }, + can_gc, ) } } diff --git a/components/script/dom/gpudevice.rs b/components/script/dom/gpudevice.rs index f0cc4136027..97110b99af8 100644 --- a/components/script/dom/gpudevice.rs +++ b/components/script/dom/gpudevice.rs @@ -561,13 +561,13 @@ impl GPUDeviceMethods for GPUDevice { } impl AsyncWGPUListener for GPUDevice { - fn handle_response(&self, response: WebGPUResponse, promise: &Rc<Promise>) { + fn handle_response(&self, response: WebGPUResponse, promise: &Rc<Promise>, can_gc: CanGc) { match response { WebGPUResponse::PoppedErrorScope(result) => match result { Ok(None) | Err(PopError::Lost) => promise.resolve_native(&None::<Option<GPUError>>), Err(PopError::Empty) => promise.reject_error(Error::Operation), Ok(Some(error)) => { - let error = GPUError::from_error(&self.global(), error, CanGc::note()); + let error = GPUError::from_error(&self.global(), error, can_gc); promise.resolve_native(&error); }, }, diff --git a/components/script/dom/gpuqueue.rs b/components/script/dom/gpuqueue.rs index 8accfdbdce7..42510ce286b 100644 --- a/components/script/dom/gpuqueue.rs +++ b/components/script/dom/gpuqueue.rs @@ -24,6 +24,7 @@ use crate::dom::gpubuffer::GPUBuffer; use crate::dom::gpucommandbuffer::GPUCommandBuffer; use crate::dom::gpudevice::GPUDevice; use crate::dom::promise::Promise; +use crate::script_runtime::CanGc; #[dom_struct] pub struct GPUQueue { @@ -206,7 +207,12 @@ impl GPUQueueMethods for GPUQueue { } impl AsyncWGPUListener for GPUQueue { - fn handle_response(&self, response: webgpu::WebGPUResponse, promise: &Rc<Promise>) { + fn handle_response( + &self, + response: webgpu::WebGPUResponse, + promise: &Rc<Promise>, + _can_gc: CanGc, + ) { match response { WebGPUResponse::SubmittedWorkDone => { promise.resolve_native(&()); diff --git a/components/script/dom/gpushadermodule.rs b/components/script/dom/gpushadermodule.rs index a8b62fd96ea..eb6aa9deb63 100644 --- a/components/script/dom/gpushadermodule.rs +++ b/components/script/dom/gpushadermodule.rs @@ -22,6 +22,7 @@ use crate::dom::bindings::trace::RootedTraceableBox; use crate::dom::globalscope::GlobalScope; use crate::dom::gpu::response_async; use crate::realms::InRealm; +use crate::script_runtime::CanGc; #[dom_struct] pub struct GPUShaderModule { @@ -125,10 +126,10 @@ impl GPUShaderModuleMethods for GPUShaderModule { } impl AsyncWGPUListener for GPUShaderModule { - fn handle_response(&self, response: WebGPUResponse, promise: &Rc<Promise>) { + fn handle_response(&self, response: WebGPUResponse, promise: &Rc<Promise>, can_gc: CanGc) { match response { WebGPUResponse::CompilationInfo(info) => { - let info = GPUCompilationInfo::from(&self.global(), info); + let info = GPUCompilationInfo::from(&self.global(), info, can_gc); promise.resolve_native(&info); }, _ => unreachable!("Wrong response received on AsyncWGPUListener for GPUShaderModule"), diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs index b5bdd05cbb7..f37ad2a8ba7 100644 --- a/components/script/dom/node.rs +++ b/components/script/dom/node.rs @@ -2298,7 +2298,7 @@ impl Node { None, document.status_code(), Default::default(), - CanGc::note(), + can_gc, ); DomRoot::upcast::<Node>(document) }, @@ -2360,8 +2360,7 @@ impl Node { // Step 6. if clone_children == CloneChildrenFlag::CloneChildren { for child in node.children() { - let child_copy = - Node::clone(&child, Some(&document), clone_children, CanGc::note()); + let child_copy = Node::clone(&child, Some(&document), clone_children, can_gc); let _inserted_node = Node::pre_insert(&child_copy, ©, None); } } diff --git a/components/script/dom/pagetransitionevent.rs b/components/script/dom/pagetransitionevent.rs index cd20481d2ee..99f364e67b3 100644 --- a/components/script/dom/pagetransitionevent.rs +++ b/components/script/dom/pagetransitionevent.rs @@ -54,16 +54,9 @@ impl PageTransitionEvent { bubbles: bool, cancelable: bool, persisted: bool, + can_gc: CanGc, ) -> DomRoot<PageTransitionEvent> { - Self::new_with_proto( - window, - None, - type_, - bubbles, - cancelable, - persisted, - CanGc::note(), - ) + Self::new_with_proto(window, None, type_, bubbles, cancelable, persisted, can_gc) } fn new_with_proto( diff --git a/components/script/dom/rtcdatachannel.rs b/components/script/dom/rtcdatachannel.rs index df473399c4a..214bd3fd359 100644 --- a/components/script/dom/rtcdatachannel.rs +++ b/components/script/dom/rtcdatachannel.rs @@ -111,24 +111,24 @@ impl RTCDataChannel { rtc_data_channel } - pub fn on_open(&self) { + pub fn on_open(&self, can_gc: CanGc) { let event = Event::new( &self.global(), atom!("open"), EventBubbles::DoesNotBubble, EventCancelable::NotCancelable, - CanGc::note(), + can_gc, ); event.upcast::<Event>().fire(self.upcast()); } - pub fn on_close(&self) { + pub fn on_close(&self, can_gc: CanGc) { let event = Event::new( &self.global(), atom!("close"), EventBubbles::DoesNotBubble, EventCancelable::NotCancelable, - CanGc::note(), + can_gc, ); event.upcast::<Event>().fire(self.upcast()); @@ -151,7 +151,7 @@ impl RTCDataChannel { let message = match error { WebRtcError::Backend(message) => DOMString::from(message), }; - let error = RTCError::new(&global, &init, message); + let error = RTCError::new(&global, &init, message, can_gc); let event = RTCErrorEvent::new(&global, atom!("error"), false, false, &error, can_gc); event.upcast::<Event>().fire(self.upcast()); } diff --git a/components/script/dom/rtcerror.rs b/components/script/dom/rtcerror.rs index 29dd49432b9..372a96f6989 100644 --- a/components/script/dom/rtcerror.rs +++ b/components/script/dom/rtcerror.rs @@ -43,8 +43,13 @@ impl RTCError { } } - pub fn new(global: &GlobalScope, init: &RTCErrorInit, message: DOMString) -> DomRoot<RTCError> { - Self::new_with_proto(global, None, init, message, CanGc::note()) + pub fn new( + global: &GlobalScope, + init: &RTCErrorInit, + message: DOMString, + can_gc: CanGc, + ) -> DomRoot<RTCError> { + Self::new_with_proto(global, None, init, message, can_gc) } fn new_with_proto( diff --git a/components/script/dom/rtcpeerconnection.rs b/components/script/dom/rtcpeerconnection.rs index 95e76c4c588..9f2827b8c32 100644 --- a/components/script/dom/rtcpeerconnection.rs +++ b/components/script/dom/rtcpeerconnection.rs @@ -334,8 +334,8 @@ impl RTCPeerConnection { }; match event { - DataChannelEvent::Open => channel.on_open(), - DataChannelEvent::Close => channel.on_close(), + DataChannelEvent::Open => channel.on_open(can_gc), + DataChannelEvent::Close => channel.on_close(can_gc), DataChannelEvent::Error(error) => channel.on_error(error, can_gc), DataChannelEvent::OnMessage(message) => channel.on_message(message, can_gc), DataChannelEvent::StateChange(state) => channel.on_state_change(state, can_gc), diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index 73a63e435db..e1cbbd0256f 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -56,8 +56,8 @@ use script_layout_interface::{ use script_traits::webdriver_msg::{WebDriverJSError, WebDriverJSResult}; use script_traits::{ ConstellationControlMsg, DocumentState, HistoryEntryReplacement, LoadData, ScriptMsg, - ScriptToConstellationChan, ScrollState, StructuredSerializedData, TimerEventId, - TimerSchedulerMsg, WindowSizeData, WindowSizeType, + ScriptToConstellationChan, ScrollState, StructuredSerializedData, TimerSchedulerMsg, + WindowSizeData, WindowSizeType, }; use selectors::attr::CaseSensitivity; use servo_arc::Arc as ServoArc; @@ -783,7 +783,7 @@ impl WindowMethods for Window { // but we pass false here, which suggests we are not doing that. Why? if document.prompt_to_unload(false) { // Step 4, unload. - document.unload(false); + document.unload(false, CanGc::note()); // https://html.spec.whatwg.org/multipage/#a-browsing-context-is-discarded // which calls into https://html.spec.whatwg.org/multipage/#discard-a-document. @@ -2310,10 +2310,6 @@ impl Window { }; } - pub fn handle_fire_timer(&self, timer_id: TimerEventId) { - self.upcast::<GlobalScope>().fire_timer(timer_id); - } - pub fn set_window_size(&self, size: WindowSizeData) { self.window_size.set(size); } diff --git a/components/script/dom/worker.rs b/components/script/dom/worker.rs index 37693dffb28..850276ae2c0 100644 --- a/components/script/dom/worker.rs +++ b/components/script/dom/worker.rs @@ -220,7 +220,7 @@ impl WorkerMethods for Worker { global.wgpu_id_hub(), control_receiver, context_sender, - CanGc::note(), + can_gc, ); let context = context_receiver diff --git a/components/script/dom/xmlhttprequest.rs b/components/script/dom/xmlhttprequest.rs index 786706db9c2..3daf64c51e5 100644 --- a/components/script/dom/xmlhttprequest.rs +++ b/components/script/dom/xmlhttprequest.rs @@ -254,24 +254,27 @@ impl XMLHttpRequest { fn process_response(&mut self, metadata: Result<FetchMetadata, NetworkError>) { let xhr = self.xhr.root(); - let rv = xhr.process_headers_available(self.gen_id, metadata); + let rv = xhr.process_headers_available(self.gen_id, metadata, CanGc::note()); if rv.is_err() { *self.sync_status.borrow_mut() = Some(rv); } } fn process_response_chunk(&mut self, chunk: Vec<u8>) { - self.xhr.root().process_data_available(self.gen_id, chunk); + self.xhr + .root() + .process_data_available(self.gen_id, chunk, CanGc::note()); } fn process_response_eof( &mut self, response: Result<ResourceFetchTiming, NetworkError>, ) { - let rv = self - .xhr - .root() - .process_response_complete(self.gen_id, response.map(|_| ())); + let rv = self.xhr.root().process_response_complete( + self.gen_id, + response.map(|_| ()), + CanGc::note(), + ); *self.sync_status.borrow_mut() = Some(rv); } @@ -445,7 +448,7 @@ impl XMLHttpRequestMethods for XMLHttpRequest { // Step 13 if self.ready_state.get() != XMLHttpRequestState::Opened { - self.change_ready_state(XMLHttpRequestState::Opened); + self.change_ready_state(XMLHttpRequestState::Opened, CanGc::note()); } Ok(()) }, @@ -810,7 +813,10 @@ impl XMLHttpRequestMethods for XMLHttpRequest { state == XMLHttpRequestState::Loading { let gen_id = self.generation_id.get(); - self.process_partial_response(XHRProgress::Errored(gen_id, Error::Abort)); + self.process_partial_response( + XHRProgress::Errored(gen_id, Error::Abort), + CanGc::note(), + ); // If open was called in one of the handlers invoked by the // above call then we should terminate the abort sequence if self.generation_id.get() != gen_id { @@ -819,7 +825,7 @@ impl XMLHttpRequestMethods for XMLHttpRequest { } // Step 3 if self.ready_state.get() == XMLHttpRequestState::Done { - self.change_ready_state(XMLHttpRequestState::Unsent); + self.change_ready_state(XMLHttpRequestState::Unsent, CanGc::note()); self.response_status.set(Err(())); self.response.borrow_mut().clear(); self.response_headers.borrow_mut().clear(); @@ -1021,7 +1027,7 @@ impl XMLHttpRequestMethods for XMLHttpRequest { pub type TrustedXHRAddress = Trusted<XMLHttpRequest>; impl XMLHttpRequest { - fn change_ready_state(&self, rs: XMLHttpRequestState) { + fn change_ready_state(&self, rs: XMLHttpRequestState, can_gc: CanGc) { assert_ne!(self.ready_state.get(), rs); self.ready_state.set(rs); if rs != XMLHttpRequestState::Unsent { @@ -1030,7 +1036,7 @@ impl XMLHttpRequest { atom!("readystatechange"), EventBubbles::DoesNotBubble, EventCancelable::Cancelable, - CanGc::note(), + can_gc, ); event.fire(self.upcast()); } @@ -1040,6 +1046,7 @@ impl XMLHttpRequest { &self, gen_id: GenerationId, metadata: Result<FetchMetadata, NetworkError>, + can_gc: CanGc, ) -> Result<(), Error> { let metadata = match metadata { Ok(meta) => match meta { @@ -1052,7 +1059,7 @@ impl XMLHttpRequest { }, }, Err(_) => { - self.process_partial_response(XHRProgress::Errored(gen_id, Error::Network)); + self.process_partial_response(XHRProgress::Errored(gen_id, Error::Network), can_gc); return Err(Error::Network); }, }; @@ -1060,36 +1067,40 @@ impl XMLHttpRequest { metadata.final_url[..Position::AfterQuery].clone_into(&mut self.response_url.borrow_mut()); // XXXManishearth Clear cache entries in case of a network error - self.process_partial_response(XHRProgress::HeadersReceived( - gen_id, - metadata.headers.map(Serde::into_inner), - metadata.status, - )); + self.process_partial_response( + XHRProgress::HeadersReceived( + gen_id, + metadata.headers.map(Serde::into_inner), + metadata.status, + ), + can_gc, + ); Ok(()) } - fn process_data_available(&self, gen_id: GenerationId, payload: Vec<u8>) { - self.process_partial_response(XHRProgress::Loading(gen_id, payload)); + fn process_data_available(&self, gen_id: GenerationId, payload: Vec<u8>, can_gc: CanGc) { + self.process_partial_response(XHRProgress::Loading(gen_id, payload), can_gc); } fn process_response_complete( &self, gen_id: GenerationId, status: Result<(), NetworkError>, + can_gc: CanGc, ) -> ErrorResult { match status { Ok(()) => { - self.process_partial_response(XHRProgress::Done(gen_id)); + self.process_partial_response(XHRProgress::Done(gen_id), can_gc); Ok(()) }, Err(_) => { - self.process_partial_response(XHRProgress::Errored(gen_id, Error::Network)); + self.process_partial_response(XHRProgress::Errored(gen_id, Error::Network), can_gc); Err(Error::Network) }, } } - fn process_partial_response(&self, progress: XHRProgress) { + fn process_partial_response(&self, progress: XHRProgress, can_gc: CanGc) { let msg_id = progress.generation_id(); // Aborts processing if abort() or open() was called @@ -1156,7 +1167,7 @@ impl XMLHttpRequest { } // Substep 3 if !self.sync.get() { - self.change_ready_state(XMLHttpRequestState::HeadersReceived); + self.change_ready_state(XMLHttpRequestState::HeadersReceived, can_gc); } }, XHRProgress::Loading(_, mut partial_response) => { @@ -1174,7 +1185,7 @@ impl XMLHttpRequest { atom!("readystatechange"), EventBubbles::DoesNotBubble, EventCancelable::Cancelable, - CanGc::note(), + can_gc, ); event.fire(self.upcast()); return_if_fetch_was_terminated!(); @@ -1197,7 +1208,7 @@ impl XMLHttpRequest { // Subsubsteps 6-8 self.send_flag.set(false); - self.change_ready_state(XMLHttpRequestState::Done); + self.change_ready_state(XMLHttpRequestState::Done, can_gc); return_if_fetch_was_terminated!(); // Subsubsteps 11-12 self.dispatch_response_progress_event(atom!("load")); @@ -1211,7 +1222,7 @@ impl XMLHttpRequest { self.discard_subsequent_responses(); self.send_flag.set(false); // XXXManishearth set response to NetworkError - self.change_ready_state(XMLHttpRequestState::Done); + self.change_ready_state(XMLHttpRequestState::Done, can_gc); return_if_fetch_was_terminated!(); let errormsg = match e { @@ -1499,7 +1510,7 @@ impl XMLHttpRequest { &document, Some(DOMString::from(decoded)), wr.get_url(), - CanGc::note(), + can_gc, ); document } @@ -1515,7 +1526,7 @@ impl XMLHttpRequest { &document, Some(DOMString::from(decoded)), wr.get_url(), - CanGc::note(), + can_gc, ); document } @@ -1662,10 +1673,13 @@ pub struct XHRTimeoutCallback { } impl XHRTimeoutCallback { - pub fn invoke(self) { + pub fn invoke(self, can_gc: CanGc) { let xhr = self.xhr.root(); if xhr.ready_state.get() != XMLHttpRequestState::Done { - xhr.process_partial_response(XHRProgress::Errored(self.generation_id, Error::Timeout)); + xhr.process_partial_response( + XHRProgress::Errored(self.generation_id, Error::Timeout), + can_gc, + ); } } } diff --git a/components/script/dom/xrinputsource.rs b/components/script/dom/xrinputsource.rs index 1f4509e37d8..a260e2e6780 100644 --- a/components/script/dom/xrinputsource.rs +++ b/components/script/dom/xrinputsource.rs @@ -20,7 +20,7 @@ use crate::dom::xrhand::XRHand; use crate::dom::xrsession::XRSession; use crate::dom::xrspace::XRSpace; use crate::realms::enter_realm; -use crate::script_runtime::JSContext; +use crate::script_runtime::{CanGc, JSContext}; #[dom_struct] pub struct XRInputSource { @@ -42,6 +42,7 @@ impl XRInputSource { global: &GlobalScope, session: &XRSession, info: InputSource, + can_gc: CanGc, ) -> XRInputSource { // <https://www.w3.org/TR/webxr-gamepads-module-1/#gamepad-differences> let gamepad = Gamepad::new( @@ -56,6 +57,7 @@ impl XRInputSource { supports_trigger_rumble: false, }, true, + can_gc, ); XRInputSource { reflector: Reflector::new(), @@ -74,9 +76,10 @@ impl XRInputSource { global: &GlobalScope, session: &XRSession, info: InputSource, + can_gc: CanGc, ) -> DomRoot<XRInputSource> { let source = reflect_dom_object( - Box::new(XRInputSource::new_inherited(global, session, info)), + Box::new(XRInputSource::new_inherited(global, session, info, can_gc)), global, ); diff --git a/components/script/dom/xrinputsourcearray.rs b/components/script/dom/xrinputsourcearray.rs index 0dd800336f5..e47ddefb24a 100644 --- a/components/script/dom/xrinputsourcearray.rs +++ b/components/script/dom/xrinputsourcearray.rs @@ -15,6 +15,7 @@ use crate::dom::globalscope::GlobalScope; use crate::dom::xrinputsource::XRInputSource; use crate::dom::xrinputsourceschangeevent::XRInputSourcesChangeEvent; use crate::dom::xrsession::XRSession; +use crate::script_runtime::CanGc; #[dom_struct] pub struct XRInputSourceArray { @@ -34,7 +35,7 @@ impl XRInputSourceArray { reflect_dom_object(Box::new(XRInputSourceArray::new_inherited()), global) } - pub fn add_input_sources(&self, session: &XRSession, inputs: &[InputSource]) { + pub fn add_input_sources(&self, session: &XRSession, inputs: &[InputSource], can_gc: CanGc) { let mut input_sources = self.input_sources.borrow_mut(); let global = self.global(); @@ -46,7 +47,7 @@ impl XRInputSourceArray { !input_sources.iter().any(|i| i.id() == info.id), "Should never add a duplicate input id!" ); - let input = XRInputSource::new(&global, session, info.clone()); + let input = XRInputSource::new(&global, session, info.clone(), can_gc); input_sources.push(Dom::from_ref(&input)); added.push(input); } @@ -90,7 +91,13 @@ impl XRInputSourceArray { event.upcast::<Event>().fire(session.upcast()); } - pub fn add_remove_input_source(&self, session: &XRSession, id: InputId, info: InputSource) { + pub fn add_remove_input_source( + &self, + session: &XRSession, + id: InputId, + info: InputSource, + can_gc: CanGc, + ) { let mut input_sources = self.input_sources.borrow_mut(); let global = self.global(); let root; @@ -103,7 +110,7 @@ impl XRInputSourceArray { &[] }; input_sources.retain(|i| i.id() != id); - let input = XRInputSource::new(&global, session, info); + let input = XRInputSource::new(&global, session, info, can_gc); input_sources.push(Dom::from_ref(&input)); let added = [input]; diff --git a/components/script/dom/xrsession.rs b/components/script/dom/xrsession.rs index 43ed08df3d8..c146cef6da2 100644 --- a/components/script/dom/xrsession.rs +++ b/components/script/dom/xrsession.rs @@ -68,6 +68,7 @@ use crate::dom::xrspace::XRSpace; use crate::realms::InRealm; use crate::script_runtime::JSContext; use crate::task_source::TaskSource; +use crate::script_runtime::CanGc; #[dom_struct] pub struct XRSession { @@ -240,7 +241,7 @@ impl XRSession { let this = this.clone(); let _ = task_source.queue_with_canceller( task!(xr_event_callback: move || { - this.root().event_callback(message.to().unwrap()); + this.root().event_callback(message.to().unwrap(), CanGc::note()); }), &canceller, ); @@ -275,13 +276,13 @@ impl XRSession { let _ = task_source.queue_with_canceller( task!(session_initial_inputs: move || { let this = this.root(); - this.input_sources.add_input_sources(&this, &initial_inputs); + this.input_sources.add_input_sources(&this, &initial_inputs, CanGc::note()); }), &canceller, ); } - fn event_callback(&self, event: XREvent) { + fn event_callback(&self, event: XREvent, can_gc: CanGc) { match event { XREvent::SessionEnd => { // https://immersive-web.github.io/webxr/#shut-down-the-session @@ -366,13 +367,14 @@ impl XRSession { self.dirty_layers(); }, XREvent::AddInput(info) => { - self.input_sources.add_input_sources(self, &[info]); + self.input_sources.add_input_sources(self, &[info], can_gc); }, XREvent::RemoveInput(id) => { self.input_sources.remove_input_source(self, id); }, XREvent::UpdateInput(id, source) => { - self.input_sources.add_remove_input_source(self, id, source); + self.input_sources + .add_remove_input_source(self, id, source, can_gc); }, XREvent::InputChanged(id, frame) => { self.input_frames.borrow_mut().insert(id, frame); diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs index de9160b0850..4514257c894 100644 --- a/components/script/script_thread.rs +++ b/components/script/script_thread.rs @@ -1538,7 +1538,7 @@ impl ScriptThread { } /// Process compositor events as part of a "update the rendering task". - fn process_pending_compositor_events(&self, pipeline_id: PipelineId) { + fn process_pending_compositor_events(&self, pipeline_id: PipelineId, can_gc: CanGc) { let Some(document) = self.documents.borrow().find_document(pipeline_id) else { warn!("Processing pending compositor events for closed pipeline {pipeline_id}."); return; @@ -1630,7 +1630,7 @@ impl ScriptThread { CompositorEvent::GamepadEvent(gamepad_event) => { let global = window.upcast::<GlobalScope>(); - global.handle_gamepad_event(gamepad_event); + global.handle_gamepad_event(gamepad_event, can_gc); }, } } @@ -1638,7 +1638,7 @@ impl ScriptThread { } /// <https://html.spec.whatwg.org/multipage/#update-the-rendering> - fn update_the_rendering(&self) { + fn update_the_rendering(&self, can_gc: CanGc) { self.update_the_rendering_task_queued_for_pipeline .borrow_mut() .clear(); @@ -1687,7 +1687,7 @@ impl ScriptThread { // TODO: Should this be broken and to match the specification more closely? For instance see // https://html.spec.whatwg.org/multipage/#flush-autofocus-candidates. - self.process_pending_compositor_events(pipeline_id); + self.process_pending_compositor_events(pipeline_id, can_gc); // TODO(#31665): Implement the "run the scroll steps" from // https://drafts.csswg.org/cssom-view/#document-run-the-scroll-steps. @@ -1781,7 +1781,7 @@ impl ScriptThread { SCRIPT_THREAD_ROOT.with(|root| { if let Some(script_thread) = root.get() { let script_thread = unsafe {&*script_thread}; - script_thread.update_the_rendering(); + script_thread.update_the_rendering(CanGc::note()); } }) }), @@ -2311,7 +2311,7 @@ impl ScriptThread { can_gc, ), ConstellationControlMsg::UnloadDocument(pipeline_id) => { - self.handle_unload_document(pipeline_id) + self.handle_unload_document(pipeline_id, can_gc) }, ConstellationControlMsg::ResizeInactive(id, new_size) => { self.handle_resize_inactive_msg(id, new_size) @@ -2320,7 +2320,7 @@ impl ScriptThread { self.handle_get_title_msg(pipeline_id) }, ConstellationControlMsg::SetDocumentActivity(pipeline_id, activity) => { - self.handle_set_document_activity_msg(pipeline_id, activity) + self.handle_set_document_activity_msg(pipeline_id, activity, can_gc) }, ConstellationControlMsg::SetThrottled(pipeline_id, throttled) => { self.handle_set_throttled_msg(pipeline_id, throttled) @@ -2988,7 +2988,12 @@ impl ScriptThread { } /// Handles activity change message - fn handle_set_document_activity_msg(&self, id: PipelineId, activity: DocumentActivity) { + fn handle_set_document_activity_msg( + &self, + id: PipelineId, + activity: DocumentActivity, + can_gc: CanGc, + ) { debug!( "Setting activity of {} to be {:?} in {:?}.", id, @@ -2997,7 +3002,7 @@ impl ScriptThread { ); let document = self.documents.borrow().find_document(id); if let Some(document) = document { - document.set_activity(activity); + document.set_activity(activity, can_gc); return; } let mut loads = self.incomplete_loads.borrow_mut(); @@ -3073,10 +3078,10 @@ impl ScriptThread { } } - fn handle_unload_document(&self, pipeline_id: PipelineId) { + fn handle_unload_document(&self, pipeline_id: PipelineId, can_gc: CanGc) { let document = self.documents.borrow().find_document(pipeline_id); if let Some(document) = document { - document.unload(false); + document.unload(false, can_gc); } } diff --git a/components/script/timers.rs b/components/script/timers.rs index 9022ea4bc2d..3b70a344f8c 100644 --- a/components/script/timers.rs +++ b/components/script/timers.rs @@ -29,6 +29,7 @@ use crate::dom::htmlmetaelement::RefreshRedirectDue; use crate::dom::testbinding::TestBindingCallback; use crate::dom::xmlhttprequest::XHRTimeoutCallback; use crate::script_module::ScriptFetchOptions; +use crate::script_runtime::CanGc; use crate::script_thread::ScriptThread; #[derive(Clone, Copy, Debug, Eq, Hash, JSTraceable, MallocSizeOf, Ord, PartialEq, PartialOrd)] @@ -88,9 +89,9 @@ pub enum OneshotTimerCallback { } impl OneshotTimerCallback { - fn invoke<T: DomObject>(self, this: &T, js_timers: &JsTimers) { + fn invoke<T: DomObject>(self, this: &T, js_timers: &JsTimers, can_gc: CanGc) { match self { - OneshotTimerCallback::XhrTimeout(callback) => callback.invoke(), + OneshotTimerCallback::XhrTimeout(callback) => callback.invoke(can_gc), OneshotTimerCallback::EventSourceTimeout(callback) => callback.invoke(), OneshotTimerCallback::JsTimer(task) => task.invoke(this, js_timers), OneshotTimerCallback::TestBindingCallback(callback) => callback.invoke(), @@ -190,7 +191,7 @@ impl OneshotTimers { } } - pub fn fire_timer(&self, id: TimerEventId, global: &GlobalScope) { + pub fn fire_timer(&self, id: TimerEventId, global: &GlobalScope, can_gc: CanGc) { let expected_id = self.expected_event_id.get(); if expected_id != id { debug!( @@ -233,7 +234,7 @@ impl OneshotTimers { return; } let callback = timer.callback; - callback.invoke(global, &self.js_timers); + callback.invoke(global, &self.js_timers, can_gc); } self.schedule_timer_call(); |