mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
script: Mark callback methods with CanGc. (#35753)
Signed-off-by: Josh Matthews <josh@joshmatthews.net>
This commit is contained in:
parent
3d320fa96a
commit
5650fa2e79
26 changed files with 133 additions and 67 deletions
|
@ -547,7 +547,7 @@ impl BaseAudioContextMethods<crate::DomTypeHolder> 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<crate::DomTypeHolder> 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());
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -1020,6 +1020,7 @@ impl CustomElementReaction {
|
|||
arguments,
|
||||
value.handle_mut(),
|
||||
ExceptionHandling::Report,
|
||||
can_gc,
|
||||
);
|
||||
},
|
||||
}
|
||||
|
|
|
@ -126,7 +126,7 @@ impl DataTransferItemMethods<crate::DomTypeHolder> 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());
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
|
|
@ -2380,7 +2380,7 @@ impl Document {
|
|||
}
|
||||
|
||||
/// <https://html.spec.whatwg.org/multipage/#run-the-animation-frame-callbacks>
|
||||
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);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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::<BeforeUnloadEvent>() {
|
||||
// Step 5
|
||||
if let Ok(value) =
|
||||
handler.Call_(object, event.upcast::<Event>(), exception_handle)
|
||||
{
|
||||
if let Ok(value) = handler.Call_(
|
||||
object,
|
||||
event.upcast::<Event>(),
|
||||
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::<Event>(), exception_handle);
|
||||
let _ = handler.Call_(
|
||||
object,
|
||||
event.upcast::<Event>(),
|
||||
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();
|
||||
|
||||
|
|
|
@ -640,9 +640,9 @@ impl HTMLCanvasElementMethods<crate::DomTypeHolder> 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());
|
||||
}
|
||||
}));
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -103,7 +103,7 @@ impl NodeIteratorMethods<crate::DomTypeHolder> for NodeIterator {
|
|||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#dom-nodeiterator-nextnode
|
||||
fn NextNode(&self) -> Fallible<Option<DomRoot<Node>>> {
|
||||
fn NextNode(&self, can_gc: CanGc) -> Fallible<Option<DomRoot<Node>>> {
|
||||
// https://dom.spec.whatwg.org/#concept-NodeIterator-traverse
|
||||
// Step 1.
|
||||
let node = self.reference_node.get();
|
||||
|
@ -116,7 +116,7 @@ impl NodeIteratorMethods<crate::DomTypeHolder> 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<crate::DomTypeHolder> 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<crate::DomTypeHolder> for NodeIterator {
|
|||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#dom-nodeiterator-previousnode
|
||||
fn PreviousNode(&self) -> Fallible<Option<DomRoot<Node>>> {
|
||||
fn PreviousNode(&self, can_gc: CanGc) -> Fallible<Option<DomRoot<Node>>> {
|
||||
// https://dom.spec.whatwg.org/#concept-NodeIterator-traverse
|
||||
// Step 1.
|
||||
let node = self.reference_node.get();
|
||||
|
@ -160,7 +160,7 @@ impl NodeIteratorMethods<crate::DomTypeHolder> 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<crate::DomTypeHolder> 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<crate::DomTypeHolder> for NodeIterator {
|
|||
|
||||
impl NodeIterator {
|
||||
// https://dom.spec.whatwg.org/#concept-node-filter
|
||||
fn accept_node(&self, node: &Node) -> Fallible<u16> {
|
||||
fn accept_node(&self, node: &Node, can_gc: CanGc) -> Fallible<u16> {
|
||||
// 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.
|
||||
|
|
|
@ -291,7 +291,7 @@ impl NotificationMethods<crate::DomTypeHolder> 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.
|
||||
|
|
|
@ -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<PerformanceObserverCallback> {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -148,7 +148,7 @@ impl ResizeObserver {
|
|||
}
|
||||
let _ = self
|
||||
.callback
|
||||
.Call_(self, entries, self, ExceptionHandling::Report);
|
||||
.Call_(self, entries, self, ExceptionHandling::Report, can_gc);
|
||||
}
|
||||
|
||||
/// <https://drafts.csswg.org/resize-observer/#has-skipped-observations-h>
|
||||
|
|
|
@ -1034,9 +1034,11 @@ impl TestBindingMethods<crate::DomTypeHolder> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -100,7 +100,7 @@ impl TreeWalkerMethods<crate::DomTypeHolder> for TreeWalker {
|
|||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#dom-treewalker-parentnode
|
||||
fn ParentNode(&self) -> Fallible<Option<DomRoot<Node>>> {
|
||||
fn ParentNode(&self, can_gc: CanGc) -> Fallible<Option<DomRoot<Node>>> {
|
||||
// "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<crate::DomTypeHolder> 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<crate::DomTypeHolder> for TreeWalker {
|
|||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#dom-treewalker-firstchild
|
||||
fn FirstChild(&self) -> Fallible<Option<DomRoot<Node>>> {
|
||||
fn FirstChild(&self, can_gc: CanGc) -> Fallible<Option<DomRoot<Node>>> {
|
||||
// "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<Option<DomRoot<Node>>> {
|
||||
fn LastChild(&self, can_gc: CanGc) -> Fallible<Option<DomRoot<Node>>> {
|
||||
// "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<Option<DomRoot<Node>>> {
|
||||
fn PreviousSibling(&self, can_gc: CanGc) -> Fallible<Option<DomRoot<Node>>> {
|
||||
// "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<Option<DomRoot<Node>>> {
|
||||
fn NextSibling(&self, can_gc: CanGc) -> Fallible<Option<DomRoot<Node>>> {
|
||||
// "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<Option<DomRoot<Node>>> {
|
||||
fn PreviousNode(&self, can_gc: CanGc) -> Fallible<Option<DomRoot<Node>>> {
|
||||
// "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<crate::DomTypeHolder> 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<crate::DomTypeHolder> 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<crate::DomTypeHolder> for TreeWalker {
|
|||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#dom-treewalker-nextnode
|
||||
fn NextNode(&self) -> Fallible<Option<DomRoot<Node>>> {
|
||||
fn NextNode(&self, can_gc: CanGc) -> Fallible<Option<DomRoot<Node>>> {
|
||||
// "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<crate::DomTypeHolder> 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<crate::DomTypeHolder> 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<Option<DomRoot<Node>>>
|
||||
where
|
||||
F: Fn(&Node) -> Option<DomRoot<Node>>,
|
||||
|
@ -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<Option<DomRoot<Node>>>
|
||||
where
|
||||
F: Fn(&Node) -> Option<DomRoot<Node>>,
|
||||
|
@ -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<u16> {
|
||||
fn accept_node(&self, node: &Node, can_gc: CanGc) -> Fallible<u16> {
|
||||
// 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<Node>;
|
||||
|
||||
fn next(&mut self) -> Option<DomRoot<Node>> {
|
||||
match self.NextNode() {
|
||||
match self.NextNode(CanGc::note()) {
|
||||
Ok(node) => node,
|
||||
Err(_) =>
|
||||
// The Err path happens only when a JavaScript
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -180,10 +180,15 @@ impl XRTestMethods<crate::DomTypeHolder> for XRTest {
|
|||
}
|
||||
|
||||
/// <https://github.com/immersive-web/webxr-test-api/blob/master/explainer.md>
|
||||
fn SimulateUserActivation(&self, f: Rc<Function>) {
|
||||
fn SimulateUserActivation(&self, f: Rc<Function>, 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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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]].
|
||||
|
|
|
@ -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) => {
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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': {
|
||||
|
|
|
@ -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"))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue