diff --git a/components/script/dom/baseaudiocontext.rs b/components/script/dom/baseaudiocontext.rs index bbaafbb48e6..41633683824 100644 --- a/components/script/dom/baseaudiocontext.rs +++ b/components/script/dom/baseaudiocontext.rs @@ -547,7 +547,7 @@ impl BaseAudioContextMethods for BaseAudioContext { assert!(resolvers.contains_key(&uuid_)); let resolver = resolvers.remove(&uuid_).unwrap(); if let Some(callback) = resolver.success_callback { - let _ = callback.Call__(&buffer, ExceptionHandling::Report); + let _ = callback.Call__(&buffer, ExceptionHandling::Report, CanGc::note()); } resolver.promise.resolve_native(&buffer, CanGc::note()); })); @@ -561,7 +561,7 @@ impl BaseAudioContextMethods for BaseAudioContext { if let Some(callback) = resolver.error_callback { let _ = callback.Call__( &DOMException::new(&this.global(), DOMErrorName::DataCloneError, CanGc::note()), - ExceptionHandling::Report); + ExceptionHandling::Report, CanGc::note()); } let error = format!("Audio decode error {:?}", error); resolver.promise.reject_error(Error::Type(error), CanGc::note()); diff --git a/components/script/dom/bindings/import.rs b/components/script/dom/bindings/import.rs index b67268437ae..313ad17a3d8 100644 --- a/components/script/dom/bindings/import.rs +++ b/components/script/dom/bindings/import.rs @@ -44,7 +44,7 @@ pub(crate) mod base { }; pub(crate) use crate::dom::globalscope::{GlobalScope, GlobalScopeHelpers}; pub(crate) use crate::dom::promise::PromiseHelpers; - pub(crate) use crate::script_runtime::JSContext as SafeJSContext; + pub(crate) use crate::script_runtime::{CanGc, JSContext as SafeJSContext}; } #[allow(unused_imports)] diff --git a/components/script/dom/customelementregistry.rs b/components/script/dom/customelementregistry.rs index a307eae2294..5e570743325 100644 --- a/components/script/dom/customelementregistry.rs +++ b/components/script/dom/customelementregistry.rs @@ -1020,6 +1020,7 @@ impl CustomElementReaction { arguments, value.handle_mut(), ExceptionHandling::Report, + can_gc, ); }, } diff --git a/components/script/dom/datatransferitem.rs b/components/script/dom/datatransferitem.rs index 777f590ee3a..41385f31ce9 100644 --- a/components/script/dom/datatransferitem.rs +++ b/components/script/dom/datatransferitem.rs @@ -126,7 +126,7 @@ impl DataTransferItemMethods for DataTransferItem { let maybe_index = this.root().pending_callbacks.borrow().iter().position(|val| val.id == id); if let Some(index) = maybe_index { let callback = this.root().pending_callbacks.borrow_mut().swap_remove(index).callback; - let _ = callback.Call__(DOMString::from(string), ExceptionHandling::Report); + let _ = callback.Call__(DOMString::from(string), ExceptionHandling::Report, CanGc::note()); } })); } diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index 6458b11e481..63e465ccae8 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -2380,7 +2380,7 @@ impl Document { } /// - pub(crate) fn run_the_animation_frame_callbacks(&self) { + pub(crate) fn run_the_animation_frame_callbacks(&self, can_gc: CanGc) { let _realm = enter_realm(self); rooted_vec!(let mut animation_frame_list); mem::swap( @@ -2398,7 +2398,7 @@ impl Document { for (_, callback) in animation_frame_list.drain(..) { if let Some(callback) = callback { - callback.call(self, *timing); + callback.call(self, *timing, can_gc); } } @@ -6106,7 +6106,7 @@ pub(crate) enum AnimationFrameCallback { } impl AnimationFrameCallback { - fn call(&self, document: &Document, now: f64) { + fn call(&self, document: &Document, now: f64, can_gc: CanGc) { match *self { AnimationFrameCallback::DevtoolsFramerateTick { ref actor_name } => { let msg = ScriptToDevtoolsControlMsg::FramerateTick(actor_name.clone(), now); @@ -6116,7 +6116,7 @@ impl AnimationFrameCallback { AnimationFrameCallback::FrameRequestCallback { ref callback } => { // TODO(jdm): The spec says that any exceptions should be suppressed: // https://github.com/servo/servo/issues/6928 - let _ = callback.Call__(Finite::wrap(now), ExceptionHandling::Report); + let _ = callback.Call__(Finite::wrap(now), ExceptionHandling::Report, can_gc); }, } } diff --git a/components/script/dom/event.rs b/components/script/dom/event.rs index a39325b86c2..896970fec54 100644 --- a/components/script/dom/event.rs +++ b/components/script/dom/event.rs @@ -1154,6 +1154,7 @@ fn invoke( phase, invocation_target_in_shadow_tree, timeline_window, + can_gc, ); // Step 9. If found is false and event’s isTrusted attribute is true: @@ -1182,6 +1183,7 @@ fn invoke( phase, invocation_target_in_shadow_tree, timeline_window, + can_gc, ); // Step 9.4 Set event’s type attribute value to originalEventType. @@ -1196,6 +1198,7 @@ fn inner_invoke( _phase: ListenerPhase, invocation_target_in_shadow_tree: bool, timeline_window: Option<&Window>, + can_gc: CanGc, ) -> bool { // Step 1. Let found be false. let mut found = false; @@ -1261,6 +1264,7 @@ fn inner_invoke( .expect("event target was initialized as part of \"invoke\""), event, ExceptionHandling::Report, + can_gc, ); if let Some(window) = timeline_window { window.emit_timeline_marker(marker.end()); diff --git a/components/script/dom/eventtarget.rs b/components/script/dom/eventtarget.rs index 96b18558774..f8d01f95553 100644 --- a/components/script/dom/eventtarget.rs +++ b/components/script/dom/eventtarget.rs @@ -190,11 +190,12 @@ impl CompiledEventListener { object: &EventTarget, event: &Event, exception_handle: ExceptionHandling, + can_gc: CanGc, ) { // Step 3 match *self { CompiledEventListener::Listener(ref listener) => { - let _ = listener.HandleEvent_(object, event, exception_handle); + let _ = listener.HandleEvent_(object, event, exception_handle, can_gc); }, CompiledEventListener::Handler(ref handler) => { match *handler { @@ -214,6 +215,7 @@ impl CompiledEventListener { Some(error.handle()), rooted_return_value.handle_mut(), exception_handle, + can_gc, ); // Step 4 if let Ok(()) = return_value { @@ -237,15 +239,19 @@ impl CompiledEventListener { None, rooted_return_value.handle_mut(), exception_handle, + can_gc, ); }, CommonEventHandler::BeforeUnloadEventHandler(ref handler) => { if let Some(event) = event.downcast::() { // Step 5 - if let Ok(value) = - handler.Call_(object, event.upcast::(), exception_handle) - { + if let Ok(value) = handler.Call_( + object, + event.upcast::(), + exception_handle, + can_gc, + ) { let rv = event.ReturnValue(); if let Some(v) = value { if rv.is_empty() { @@ -256,8 +262,12 @@ impl CompiledEventListener { } } else { // Step 5, "Otherwise" clause - let _ = - handler.Call_(object, event.upcast::(), exception_handle); + let _ = handler.Call_( + object, + event.upcast::(), + exception_handle, + can_gc, + ); } }, @@ -269,6 +279,7 @@ impl CompiledEventListener { event, rooted_return_value.handle_mut(), exception_handle, + can_gc, ) { let value = rooted_return_value.handle(); diff --git a/components/script/dom/htmlcanvaselement.rs b/components/script/dom/htmlcanvaselement.rs index 04324e5fd3d..fa3a48f6a6a 100644 --- a/components/script/dom/htmlcanvaselement.rs +++ b/components/script/dom/htmlcanvaselement.rs @@ -640,9 +640,9 @@ impl HTMLCanvasElementMethods for HTMLCanvasElement { // Set result to a new Blob object, created in the relevant realm of this canvas element // Invoke callback with « result » and "report". let blob = Blob::new(&this.global(), blob_impl, CanGc::note()); - let _ = callback.Call__(Some(&blob), ExceptionHandling::Report); + let _ = callback.Call__(Some(&blob), ExceptionHandling::Report, CanGc::note()); } else { - let _ = callback.Call__(None, ExceptionHandling::Report); + let _ = callback.Call__(None, ExceptionHandling::Report, CanGc::note()); } })); diff --git a/components/script/dom/mediasession.rs b/components/script/dom/mediasession.rs index 1db8c4dc25d..fe5604daf85 100644 --- a/components/script/dom/mediasession.rs +++ b/components/script/dom/mediasession.rs @@ -75,7 +75,7 @@ impl MediaSession { debug!("Handle media session action {:?}", action); if let Some(handler) = self.action_handlers.borrow().get(&action) { - if handler.Call__(ExceptionHandling::Report).is_err() { + if handler.Call__(ExceptionHandling::Report, can_gc).is_err() { warn!("Error calling MediaSessionActionHandler callback"); } return; diff --git a/components/script/dom/mutationobserver.rs b/components/script/dom/mutationobserver.rs index 2df554c80ff..558453f9235 100644 --- a/components/script/dom/mutationobserver.rs +++ b/components/script/dom/mutationobserver.rs @@ -134,7 +134,7 @@ impl MutationObserver { if !queue.is_empty() { let _ = mo .callback - .Call_(&**mo, queue, mo, ExceptionHandling::Report); + .Call_(&**mo, queue, mo, ExceptionHandling::Report, can_gc); } } diff --git a/components/script/dom/nodeiterator.rs b/components/script/dom/nodeiterator.rs index 175a3a89467..94e2564d049 100644 --- a/components/script/dom/nodeiterator.rs +++ b/components/script/dom/nodeiterator.rs @@ -103,7 +103,7 @@ impl NodeIteratorMethods for NodeIterator { } // https://dom.spec.whatwg.org/#dom-nodeiterator-nextnode - fn NextNode(&self) -> Fallible>> { + fn NextNode(&self, can_gc: CanGc) -> Fallible>> { // https://dom.spec.whatwg.org/#concept-NodeIterator-traverse // Step 1. let node = self.reference_node.get(); @@ -116,7 +116,7 @@ impl NodeIteratorMethods for NodeIterator { before_node = false; // Step 3-2. - let result = self.accept_node(&node)?; + let result = self.accept_node(&node, can_gc)?; // Step 3-3. if result == NodeFilterConstants::FILTER_ACCEPT { @@ -131,7 +131,7 @@ impl NodeIteratorMethods for NodeIterator { // Step 3-1. for following_node in node.following_nodes(&self.root_node) { // Step 3-2. - let result = self.accept_node(&following_node)?; + let result = self.accept_node(&following_node, can_gc)?; // Step 3-3. if result == NodeFilterConstants::FILTER_ACCEPT { @@ -147,7 +147,7 @@ impl NodeIteratorMethods for NodeIterator { } // https://dom.spec.whatwg.org/#dom-nodeiterator-previousnode - fn PreviousNode(&self) -> Fallible>> { + fn PreviousNode(&self, can_gc: CanGc) -> Fallible>> { // https://dom.spec.whatwg.org/#concept-NodeIterator-traverse // Step 1. let node = self.reference_node.get(); @@ -160,7 +160,7 @@ impl NodeIteratorMethods for NodeIterator { before_node = true; // Step 3-2. - let result = self.accept_node(&node)?; + let result = self.accept_node(&node, can_gc)?; // Step 3-3. if result == NodeFilterConstants::FILTER_ACCEPT { @@ -175,7 +175,7 @@ impl NodeIteratorMethods for NodeIterator { // Step 3-1. for preceding_node in node.preceding_nodes(&self.root_node) { // Step 3-2. - let result = self.accept_node(&preceding_node)?; + let result = self.accept_node(&preceding_node, can_gc)?; // Step 3-3. if result == NodeFilterConstants::FILTER_ACCEPT { @@ -198,7 +198,7 @@ impl NodeIteratorMethods for NodeIterator { impl NodeIterator { // https://dom.spec.whatwg.org/#concept-node-filter - fn accept_node(&self, node: &Node) -> Fallible { + fn accept_node(&self, node: &Node, can_gc: CanGc) -> Fallible { // Step 1. if self.active.get() { return Err(Error::InvalidState); @@ -217,7 +217,7 @@ impl NodeIterator { // Step 5. self.active.set(true); // Step 6. - let result = callback.AcceptNode_(self, node, Rethrow); + let result = callback.AcceptNode_(self, node, Rethrow, can_gc); // Step 7. self.active.set(false); // Step 8. diff --git a/components/script/dom/notification.rs b/components/script/dom/notification.rs index 471c5a82e84..8661e5f9add 100644 --- a/components/script/dom/notification.rs +++ b/components/script/dom/notification.rs @@ -291,7 +291,7 @@ impl NotificationMethods for Notification { // Step 3.2.1: If deprecatedCallback is given, // then invoke deprecatedCallback with « permissionState » and "report". if let Some(callback) = global.remove_notification_permission_request_callback(uuid_) { - let _ = callback.Call__(notification_permission, ExceptionHandling::Report); + let _ = callback.Call__(notification_permission, ExceptionHandling::Report, CanGc::note()); } // Step 3.2.2: Resolve promise with permissionState. diff --git a/components/script/dom/performanceobserver.rs b/components/script/dom/performanceobserver.rs index 379474d03e9..25c3f0139fc 100644 --- a/components/script/dom/performanceobserver.rs +++ b/components/script/dom/performanceobserver.rs @@ -101,9 +101,13 @@ impl PerformanceObserver { let observer_entry_list = PerformanceObserverEntryList::new(&self.global(), entry_list, can_gc); // using self both as thisArg and as the second formal argument - let _ = self - .callback - .Call_(self, &observer_entry_list, self, ExceptionHandling::Report); + let _ = self.callback.Call_( + self, + &observer_entry_list, + self, + ExceptionHandling::Report, + can_gc, + ); } pub(crate) fn callback(&self) -> Rc { diff --git a/components/script/dom/readablestreamdefaultcontroller.rs b/components/script/dom/readablestreamdefaultcontroller.rs index da61d5e02ca..b564aa1f171 100644 --- a/components/script/dom/readablestreamdefaultcontroller.rs +++ b/components/script/dom/readablestreamdefaultcontroller.rs @@ -679,7 +679,7 @@ impl ReadableStreamDefaultController { let size = if let Some(strategy_size) = strategy_size { // Note: the Rethrow exception handling is necessary, // otherwise returning JSFailed will panic because no exception is pending. - let result = strategy_size.Call__(chunk, ExceptionHandling::Rethrow); + let result = strategy_size.Call__(chunk, ExceptionHandling::Rethrow, can_gc); match result { // Let chunkSize be result.[[Value]]. Ok(size) => size, diff --git a/components/script/dom/resizeobserver.rs b/components/script/dom/resizeobserver.rs index 55178f01b1d..ae883524fd3 100644 --- a/components/script/dom/resizeobserver.rs +++ b/components/script/dom/resizeobserver.rs @@ -148,7 +148,7 @@ impl ResizeObserver { } let _ = self .callback - .Call_(self, entries, self, ExceptionHandling::Report); + .Call_(self, entries, self, ExceptionHandling::Report, can_gc); } /// diff --git a/components/script/dom/testbinding.rs b/components/script/dom/testbinding.rs index 31e62b9f92f..7dd61b98ed6 100644 --- a/components/script/dom/testbinding.rs +++ b/components/script/dom/testbinding.rs @@ -1034,9 +1034,11 @@ impl TestBindingMethods for TestBinding { } } impl Callback for SimpleHandler { - fn callback(&self, cx: SafeJSContext, v: HandleValue, realm: InRealm, _can_gc: CanGc) { + fn callback(&self, cx: SafeJSContext, v: HandleValue, realm: InRealm, can_gc: CanGc) { let global = GlobalScope::from_safe_context(cx, realm); - let _ = self.handler.Call_(&*global, v, ExceptionHandling::Report); + let _ = self + .handler + .Call_(&*global, v, ExceptionHandling::Report, can_gc); } } } diff --git a/components/script/dom/treewalker.rs b/components/script/dom/treewalker.rs index b3ec0e86501..9b01f14f5cd 100644 --- a/components/script/dom/treewalker.rs +++ b/components/script/dom/treewalker.rs @@ -100,7 +100,7 @@ impl TreeWalkerMethods for TreeWalker { } // https://dom.spec.whatwg.org/#dom-treewalker-parentnode - fn ParentNode(&self) -> Fallible>> { + fn ParentNode(&self, can_gc: CanGc) -> Fallible>> { // "1. Let node be the value of the currentNode attribute." let mut node = self.current_node.get(); // "2. While node is not null and is not root, run these substeps:" @@ -111,7 +111,7 @@ impl TreeWalkerMethods for TreeWalker { node = n; // "2. If node is not null and filtering node returns FILTER_ACCEPT, // then set the currentNode attribute to node, return node." - if NodeFilterConstants::FILTER_ACCEPT == self.accept_node(&node)? { + if NodeFilterConstants::FILTER_ACCEPT == self.accept_node(&node, can_gc)? { self.current_node.set(&node); return Ok(Some(node)); } @@ -124,31 +124,47 @@ impl TreeWalkerMethods for TreeWalker { } // https://dom.spec.whatwg.org/#dom-treewalker-firstchild - fn FirstChild(&self) -> Fallible>> { + fn FirstChild(&self, can_gc: CanGc) -> Fallible>> { // "The firstChild() method must traverse children of type first." - self.traverse_children(|node| node.GetFirstChild(), |node| node.GetNextSibling()) + self.traverse_children( + |node| node.GetFirstChild(), + |node| node.GetNextSibling(), + can_gc, + ) } // https://dom.spec.whatwg.org/#dom-treewalker-lastchild - fn LastChild(&self) -> Fallible>> { + fn LastChild(&self, can_gc: CanGc) -> Fallible>> { // "The lastChild() method must traverse children of type last." - self.traverse_children(|node| node.GetLastChild(), |node| node.GetPreviousSibling()) + self.traverse_children( + |node| node.GetLastChild(), + |node| node.GetPreviousSibling(), + can_gc, + ) } // https://dom.spec.whatwg.org/#dom-treewalker-previoussibling - fn PreviousSibling(&self) -> Fallible>> { + fn PreviousSibling(&self, can_gc: CanGc) -> Fallible>> { // "The nextSibling() method must traverse siblings of type next." - self.traverse_siblings(|node| node.GetLastChild(), |node| node.GetPreviousSibling()) + self.traverse_siblings( + |node| node.GetLastChild(), + |node| node.GetPreviousSibling(), + can_gc, + ) } // https://dom.spec.whatwg.org/#dom-treewalker-nextsibling - fn NextSibling(&self) -> Fallible>> { + fn NextSibling(&self, can_gc: CanGc) -> Fallible>> { // "The previousSibling() method must traverse siblings of type previous." - self.traverse_siblings(|node| node.GetFirstChild(), |node| node.GetNextSibling()) + self.traverse_siblings( + |node| node.GetFirstChild(), + |node| node.GetNextSibling(), + can_gc, + ) } // https://dom.spec.whatwg.org/#dom-treewalker-previousnode - fn PreviousNode(&self) -> Fallible>> { + fn PreviousNode(&self, can_gc: CanGc) -> Fallible>> { // "1. Let node be the value of the currentNode attribute." let mut node = self.current_node.get(); // "2. While node is not root, run these substeps:" @@ -166,7 +182,7 @@ impl TreeWalkerMethods for TreeWalker { // "4. If result is FILTER_ACCEPT, then // set the currentNode attribute to node and return node." loop { - let result = self.accept_node(&node)?; + let result = self.accept_node(&node, can_gc)?; match result { NodeFilterConstants::FILTER_REJECT => break, _ if node.GetFirstChild().is_some() => node = node.GetLastChild().unwrap(), @@ -196,7 +212,7 @@ impl TreeWalkerMethods for TreeWalker { } // "5. Filter node and if the return value is FILTER_ACCEPT, then // set the currentNode attribute to node and return node." - if NodeFilterConstants::FILTER_ACCEPT == self.accept_node(&node)? { + if NodeFilterConstants::FILTER_ACCEPT == self.accept_node(&node, can_gc)? { self.current_node.set(&node); return Ok(Some(node)); } @@ -206,7 +222,7 @@ impl TreeWalkerMethods for TreeWalker { } // https://dom.spec.whatwg.org/#dom-treewalker-nextnode - fn NextNode(&self) -> Fallible>> { + fn NextNode(&self, can_gc: CanGc) -> Fallible>> { // "1. Let node be the value of the currentNode attribute." let mut node = self.current_node.get(); // "2. Let result be FILTER_ACCEPT." @@ -224,7 +240,7 @@ impl TreeWalkerMethods for TreeWalker { // "1. Set node to its first child." node = child; // "2. Filter node and set result to the return value." - result = self.accept_node(&node)?; + result = self.accept_node(&node, can_gc)?; // "3. If result is FILTER_ACCEPT, then // set the currentNode attribute to node and return node." if NodeFilterConstants::FILTER_ACCEPT == result { @@ -242,7 +258,7 @@ impl TreeWalkerMethods for TreeWalker { Some(n) => { node = n; // "3. Filter node and set result to the return value." - result = self.accept_node(&node)?; + result = self.accept_node(&node, can_gc)?; // "4. If result is FILTER_ACCEPT, then // set the currentNode attribute to node and return node." if NodeFilterConstants::FILTER_ACCEPT == result { @@ -262,6 +278,7 @@ impl TreeWalker { &self, next_child: F, next_sibling: G, + can_gc: CanGc, ) -> Fallible>> where F: Fn(&Node) -> Option>, @@ -281,7 +298,7 @@ impl TreeWalker { // 4. Main: Repeat these substeps: 'main: loop { // "1. Filter node and let result be the return value." - let result = self.accept_node(&node)?; + let result = self.accept_node(&node, can_gc)?; match result { // "2. If result is FILTER_ACCEPT, then set the currentNode // attribute to node and return node." @@ -338,6 +355,7 @@ impl TreeWalker { &self, next_child: F, next_sibling: G, + can_gc: CanGc, ) -> Fallible>> where F: Fn(&Node) -> Option>, @@ -360,7 +378,7 @@ impl TreeWalker { // "1. Set node to sibling." node = sibling_op.unwrap(); // "2. Filter node and let result be the return value." - let result = self.accept_node(&node)?; + let result = self.accept_node(&node, can_gc)?; // "3. If result is FILTER_ACCEPT, then set the currentNode // attribute to node and return node." if NodeFilterConstants::FILTER_ACCEPT == result { @@ -389,7 +407,7 @@ impl TreeWalker { // "5. Filter node and if the return value is FILTER_ACCEPT, then return null." Some(n) => { node = n; - if NodeFilterConstants::FILTER_ACCEPT == self.accept_node(&node)? { + if NodeFilterConstants::FILTER_ACCEPT == self.accept_node(&node, can_gc)? { return Ok(None); } }, @@ -421,7 +439,7 @@ impl TreeWalker { } // https://dom.spec.whatwg.org/#concept-node-filter - fn accept_node(&self, node: &Node) -> Fallible { + fn accept_node(&self, node: &Node, can_gc: CanGc) -> Fallible { // Step 1. if self.active.get() { return Err(Error::InvalidState); @@ -439,7 +457,7 @@ impl TreeWalker { // Step 5. self.active.set(true); // Step 6. - let result = callback.AcceptNode_(self, node, Rethrow); + let result = callback.AcceptNode_(self, node, Rethrow, can_gc); // Step 7. self.active.set(false); // Step 8. @@ -461,7 +479,7 @@ impl Iterator for &TreeWalker { type Item = DomRoot; fn next(&mut self) -> Option> { - match self.NextNode() { + match self.NextNode(CanGc::note()) { Ok(node) => node, Err(_) => // The Err path happens only when a JavaScript diff --git a/components/script/dom/underlyingsourcecontainer.rs b/components/script/dom/underlyingsourcecontainer.rs index e04e6a0fd6a..949510856ee 100644 --- a/components/script/dom/underlyingsourcecontainer.rs +++ b/components/script/dom/underlyingsourcecontainer.rs @@ -117,6 +117,7 @@ impl UnderlyingSourceContainer { &SafeHandle::from_raw(this_obj.handle()), Some(reason), ExceptionHandling::Rethrow, + can_gc, ) }; return Some(result); @@ -146,6 +147,7 @@ impl UnderlyingSourceContainer { &SafeHandle::from_raw(this_obj.handle()), controller, ExceptionHandling::Rethrow, + can_gc, ) }; return Some(result); @@ -186,6 +188,7 @@ impl UnderlyingSourceContainer { controller, result.handle_mut(), ExceptionHandling::Rethrow, + can_gc, ) { return Some(Err(error)); } diff --git a/components/script/dom/webxr/xrsession.rs b/components/script/dom/webxr/xrsession.rs index 8205bc63798..f5fd065619e 100644 --- a/components/script/dom/webxr/xrsession.rs +++ b/components/script/dom/webxr/xrsession.rs @@ -480,7 +480,7 @@ impl XRSession { for i in 0..len { let callback = self.current_raf_callback_list.borrow()[i].1.clone(); if let Some(callback) = callback { - let _ = callback.Call__(time, &frame, ExceptionHandling::Report); + let _ = callback.Call__(time, &frame, ExceptionHandling::Report, can_gc); } } self.outside_raf.set(true); diff --git a/components/script/dom/webxr/xrtest.rs b/components/script/dom/webxr/xrtest.rs index 4ababf97849..8d80c5df69e 100644 --- a/components/script/dom/webxr/xrtest.rs +++ b/components/script/dom/webxr/xrtest.rs @@ -180,10 +180,15 @@ impl XRTestMethods for XRTest { } /// - fn SimulateUserActivation(&self, f: Rc) { + fn SimulateUserActivation(&self, f: Rc, can_gc: CanGc) { ScriptThread::set_user_interacting(true); rooted!(in(*GlobalScope::get_cx()) let mut value: JSVal); - let _ = f.Call__(vec![], value.handle_mut(), ExceptionHandling::Rethrow); + let _ = f.Call__( + vec![], + value.handle_mut(), + ExceptionHandling::Rethrow, + can_gc, + ); ScriptThread::set_user_interacting(false); } diff --git a/components/script/dom/writablestreamdefaultcontroller.rs b/components/script/dom/writablestreamdefaultcontroller.rs index 2cad7bb62c5..a63aeef6661 100644 --- a/components/script/dom/writablestreamdefaultcontroller.rs +++ b/components/script/dom/writablestreamdefaultcontroller.rs @@ -373,6 +373,7 @@ impl WritableStreamDefaultController { self, result.handle_mut(), ExceptionHandling::Rethrow, + can_gc, )?; let is_promise = unsafe { if result.is_object() { @@ -445,6 +446,7 @@ impl WritableStreamDefaultController { &this_object.handle(), Some(reason), ExceptionHandling::Rethrow, + can_gc, ) } else { Ok(Promise::new_resolved(global, cx, (), can_gc)) @@ -471,6 +473,7 @@ impl WritableStreamDefaultController { chunk, self, ExceptionHandling::Rethrow, + can_gc, ) } else { Ok(Promise::new_resolved(global, cx, (), can_gc)) @@ -492,7 +495,7 @@ impl WritableStreamDefaultController { this_object.set(self.underlying_sink_obj.get()); let algo = self.close.borrow().clone(); let result = if let Some(algo) = algo { - algo.Call_(&this_object.handle(), ExceptionHandling::Rethrow) + algo.Call_(&this_object.handle(), ExceptionHandling::Rethrow, can_gc) } else { Ok(Promise::new_resolved(global, cx, (), can_gc)) }; @@ -688,7 +691,7 @@ impl WritableStreamDefaultController { // Let returnValue be the result of performing controller.[[strategySizeAlgorithm]], // passing in chunk, and interpreting the result as a completion record. - let result = strategy_size.Call__(chunk, ExceptionHandling::Rethrow); + let result = strategy_size.Call__(chunk, ExceptionHandling::Rethrow, can_gc); match result { // Let chunkSize be result.[[Value]]. diff --git a/components/script/microtask.rs b/components/script/microtask.rs index 2c06250a145..57f558c1aac 100644 --- a/components/script/microtask.rs +++ b/components/script/microtask.rs @@ -118,14 +118,18 @@ impl MicrotaskQueue { 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); + let _ = job + .callback + .Call_(&*target, ExceptionHandling::Report, can_gc); 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); + let _ = job + .callback + .Call_(&*target, ExceptionHandling::Report, can_gc); } }, Microtask::MediaElement(ref task) => { diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs index 66889f94ad3..56a588fb157 100644 --- a/components/script/script_thread.rs +++ b/components/script/script_thread.rs @@ -1238,7 +1238,7 @@ impl ScriptThread { // > in the relative high resolution time given frameTimestamp and doc's // > relevant global object as the timestamp. if should_run_rafs { - document.run_the_animation_frame_callbacks(); + document.run_the_animation_frame_callbacks(can_gc); } // Run the resize observer steps. diff --git a/components/script/timers.rs b/components/script/timers.rs index a08f06bf90e..9d14b594e86 100644 --- a/components/script/timers.rs +++ b/components/script/timers.rs @@ -558,7 +558,7 @@ impl JsTimerTask { InternalTimerCallback::FunctionTimerCallback(ref function, ref arguments) => { let arguments = self.collect_heap_args(arguments); rooted!(in(*GlobalScope::get_cx()) let mut value: JSVal); - let _ = function.Call_(this, arguments, value.handle_mut(), Report); + let _ = function.Call_(this, arguments, value.handle_mut(), Report, can_gc); }, }; ScriptThread::set_user_interacting(was_user_interacting); diff --git a/components/script_bindings/codegen/Bindings.conf b/components/script_bindings/codegen/Bindings.conf index 81295dc8aa8..bdc92a25ca8 100644 --- a/components/script_bindings/codegen/Bindings.conf +++ b/components/script_bindings/codegen/Bindings.conf @@ -417,6 +417,10 @@ DOMInterfaces = { 'canGc': ['CloneNode', 'SetTextContent'], }, +'NodeIterator': { + 'canGc': ['NextNode', 'PreviousNode'], +}, + 'Notification': { 'canGc': ['RequestPermission'], }, @@ -518,6 +522,10 @@ DOMInterfaces = { 'canGc': ['Encode'] }, +'TreeWalker': { + 'canGc': ['ParentNode', 'PreviousNode', 'NextNode', 'FirstChild', 'LastChild', 'PreviousSibling', 'NextSibling'] +}, + 'URL': { 'weakReferenceable': True, 'canGc': ['Parse', 'SearchParams'], @@ -598,7 +606,7 @@ DOMInterfaces = { }, 'XRTest': { - 'canGc': ['SimulateDeviceConnection', 'DisconnectAllDevices'], + 'canGc': ['SimulateDeviceConnection', 'DisconnectAllDevices', 'SimulateUserActivation'], }, 'XRView': { diff --git a/components/script_bindings/codegen/CodegenRust.py b/components/script_bindings/codegen/CodegenRust.py index ffd2589376a..731530dad76 100644 --- a/components/script_bindings/codegen/CodegenRust.py +++ b/components/script_bindings/codegen/CodegenRust.py @@ -7931,7 +7931,7 @@ class CGCallback(CGClass): args = args[2:] # Record the names of all the arguments, so we can use them when we call # the private method. - argnames = [arg.name for arg in args] + argnames = [arg.name for arg in args] + ["can_gc"] argnamesWithThis = ["s.get_context()", "thisValue.handle()"] + argnames argnamesWithoutThis = ["s.get_context()", "HandleValue::undefined()"] + argnames # Now that we've recorded the argnames for our call to our private @@ -7940,6 +7940,9 @@ class CGCallback(CGClass): args.append(Argument("ExceptionHandling", "aExceptionHandling", "ReportExceptions")) + args.append(Argument("CanGc", "can_gc")) + method.args.append(Argument("CanGc", "can_gc")) + # And now insert our template argument. argsWithoutThis = list(args) args.insert(0, Argument("&T", "thisObj"))