refactor: propagate CanGc arguments through callers (#35591)

Signed-off-by: Auguste Baum <auguste.apple@gmail.com>
This commit is contained in:
Auguste Baum 2025-02-23 01:34:51 +01:00 committed by GitHub
parent 02199520f2
commit b0b0289014
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
74 changed files with 403 additions and 275 deletions

View file

@ -848,11 +848,12 @@ impl CanvasState {
y0: Finite<f64>, y0: Finite<f64>,
x1: Finite<f64>, x1: Finite<f64>,
y1: Finite<f64>, y1: Finite<f64>,
can_gc: CanGc,
) -> DomRoot<CanvasGradient> { ) -> DomRoot<CanvasGradient> {
CanvasGradient::new( CanvasGradient::new(
global, global,
CanvasGradientStyle::Linear(LinearGradientStyle::new(*x0, *y0, *x1, *y1, Vec::new())), CanvasGradientStyle::Linear(LinearGradientStyle::new(*x0, *y0, *x1, *y1, Vec::new())),
CanGc::note(), can_gc,
) )
} }
@ -867,6 +868,7 @@ impl CanvasState {
x1: Finite<f64>, x1: Finite<f64>,
y1: Finite<f64>, y1: Finite<f64>,
r1: Finite<f64>, r1: Finite<f64>,
can_gc: CanGc,
) -> Fallible<DomRoot<CanvasGradient>> { ) -> Fallible<DomRoot<CanvasGradient>> {
if *r0 < 0. || *r1 < 0. { if *r0 < 0. || *r1 < 0. {
return Err(Error::IndexSize); return Err(Error::IndexSize);
@ -883,7 +885,7 @@ impl CanvasState {
*r1, *r1,
Vec::new(), Vec::new(),
)), )),
CanGc::note(), can_gc,
)) ))
} }
@ -893,6 +895,7 @@ impl CanvasState {
global: &GlobalScope, global: &GlobalScope,
image: CanvasImageSource, image: CanvasImageSource,
mut repetition: DOMString, mut repetition: DOMString,
can_gc: CanGc,
) -> Fallible<Option<DomRoot<CanvasPattern>>> { ) -> Fallible<Option<DomRoot<CanvasPattern>>> {
let (image_data, image_size) = match image { let (image_data, image_size) = match image {
CanvasImageSource::HTMLImageElement(ref image) => { CanvasImageSource::HTMLImageElement(ref image) => {
@ -941,7 +944,7 @@ impl CanvasState {
image_size, image_size,
rep, rep,
self.is_origin_clean(image), self.is_origin_clean(image),
CanGc::note(), can_gc,
))) )))
} else { } else {
Err(Error::Syntax) Err(Error::Syntax)

View file

@ -48,6 +48,7 @@ impl AudioBufferSourceNode {
window: &Window, window: &Window,
context: &BaseAudioContext, context: &BaseAudioContext,
options: &AudioBufferSourceOptions, options: &AudioBufferSourceOptions,
can_gc: CanGc,
) -> Fallible<AudioBufferSourceNode> { ) -> Fallible<AudioBufferSourceNode> {
let node_options = Default::default(); let node_options = Default::default();
let source_node = AudioScheduledSourceNode::new_inherited( let source_node = AudioScheduledSourceNode::new_inherited(
@ -68,7 +69,7 @@ impl AudioBufferSourceNode {
*options.playbackRate, *options.playbackRate,
f32::MIN, f32::MIN,
f32::MAX, f32::MAX,
CanGc::note(), can_gc,
); );
let detune = AudioParam::new( let detune = AudioParam::new(
window, window,
@ -80,7 +81,7 @@ impl AudioBufferSourceNode {
*options.detune, *options.detune,
f32::MIN, f32::MIN,
f32::MAX, f32::MAX,
CanGc::note(), can_gc,
); );
let node = AudioBufferSourceNode { let node = AudioBufferSourceNode {
source_node, source_node,
@ -115,7 +116,7 @@ impl AudioBufferSourceNode {
options: &AudioBufferSourceOptions, options: &AudioBufferSourceOptions,
can_gc: CanGc, can_gc: CanGc,
) -> Fallible<DomRoot<AudioBufferSourceNode>> { ) -> Fallible<DomRoot<AudioBufferSourceNode>> {
let node = AudioBufferSourceNode::new_inherited(window, context, options)?; let node = AudioBufferSourceNode::new_inherited(window, context, options, can_gc)?;
Ok(reflect_dom_object_with_proto( Ok(reflect_dom_object_with_proto(
Box::new(node), Box::new(node),
window, window,

View file

@ -36,7 +36,7 @@ pub(crate) struct AudioListener {
} }
impl AudioListener { impl AudioListener {
fn new_inherited(window: &Window, context: &BaseAudioContext) -> AudioListener { fn new_inherited(window: &Window, context: &BaseAudioContext, can_gc: CanGc) -> AudioListener {
let node = context.listener(); let node = context.listener();
let position_x = AudioParam::new( let position_x = AudioParam::new(
@ -49,7 +49,7 @@ impl AudioListener {
0., // default value 0., // default value
f32::MIN, // min value f32::MIN, // min value
f32::MAX, // max value f32::MAX, // max value
CanGc::note(), can_gc,
); );
let position_y = AudioParam::new( let position_y = AudioParam::new(
window, window,
@ -61,7 +61,7 @@ impl AudioListener {
0., // default value 0., // default value
f32::MIN, // min value f32::MIN, // min value
f32::MAX, // max value f32::MAX, // max value
CanGc::note(), can_gc,
); );
let position_z = AudioParam::new( let position_z = AudioParam::new(
window, window,
@ -73,7 +73,7 @@ impl AudioListener {
0., // default value 0., // default value
f32::MIN, // min value f32::MIN, // min value
f32::MAX, // max value f32::MAX, // max value
CanGc::note(), can_gc,
); );
let forward_x = AudioParam::new( let forward_x = AudioParam::new(
window, window,
@ -85,7 +85,7 @@ impl AudioListener {
0., // default value 0., // default value
f32::MIN, // min value f32::MIN, // min value
f32::MAX, // max value f32::MAX, // max value
CanGc::note(), can_gc,
); );
let forward_y = AudioParam::new( let forward_y = AudioParam::new(
window, window,
@ -97,7 +97,7 @@ impl AudioListener {
0., // default value 0., // default value
f32::MIN, // min value f32::MIN, // min value
f32::MAX, // max value f32::MAX, // max value
CanGc::note(), can_gc,
); );
let forward_z = AudioParam::new( let forward_z = AudioParam::new(
window, window,
@ -109,7 +109,7 @@ impl AudioListener {
-1., // default value -1., // default value
f32::MIN, // min value f32::MIN, // min value
f32::MAX, // max value f32::MAX, // max value
CanGc::note(), can_gc,
); );
let up_x = AudioParam::new( let up_x = AudioParam::new(
window, window,
@ -121,7 +121,7 @@ impl AudioListener {
0., // default value 0., // default value
f32::MIN, // min value f32::MIN, // min value
f32::MAX, // max value f32::MAX, // max value
CanGc::note(), can_gc,
); );
let up_y = AudioParam::new( let up_y = AudioParam::new(
window, window,
@ -133,7 +133,7 @@ impl AudioListener {
1., // default value 1., // default value
f32::MIN, // min value f32::MIN, // min value
f32::MAX, // max value f32::MAX, // max value
CanGc::note(), can_gc,
); );
let up_z = AudioParam::new( let up_z = AudioParam::new(
window, window,
@ -145,7 +145,7 @@ impl AudioListener {
0., // default value 0., // default value
f32::MIN, // min value f32::MIN, // min value
f32::MAX, // max value f32::MAX, // max value
CanGc::note(), can_gc,
); );
AudioListener { AudioListener {
@ -168,7 +168,7 @@ impl AudioListener {
context: &BaseAudioContext, context: &BaseAudioContext,
can_gc: CanGc, can_gc: CanGc,
) -> DomRoot<AudioListener> { ) -> DomRoot<AudioListener> {
let node = AudioListener::new_inherited(window, context); let node = AudioListener::new_inherited(window, context, can_gc);
reflect_dom_object(Box::new(node), window, can_gc) reflect_dom_object(Box::new(node), window, can_gc)
} }
} }

View file

@ -42,8 +42,9 @@ impl BeforeUnloadEvent {
type_: Atom, type_: Atom,
bubbles: EventBubbles, bubbles: EventBubbles,
cancelable: EventCancelable, cancelable: EventCancelable,
can_gc: CanGc,
) -> DomRoot<BeforeUnloadEvent> { ) -> DomRoot<BeforeUnloadEvent> {
let ev = BeforeUnloadEvent::new_uninitialized(window, CanGc::note()); let ev = BeforeUnloadEvent::new_uninitialized(window, can_gc);
{ {
let event = ev.upcast::<Event>(); let event = ev.upcast::<Event>();
event.init_event(type_, bool::from(bubbles), bool::from(cancelable)); event.init_event(type_, bool::from(bubbles), bool::from(cancelable));

View file

@ -77,7 +77,12 @@ unsafe fn html_constructor(
// so we can do the spec's object-identity checks. // so we can do the spec's object-identity checks.
rooted!(in(*cx) let new_target_unwrapped = UnwrapObjectDynamic(call_args.new_target().to_object(), *cx, true)); rooted!(in(*cx) let new_target_unwrapped = UnwrapObjectDynamic(call_args.new_target().to_object(), *cx, true));
if new_target_unwrapped.is_null() { if new_target_unwrapped.is_null() {
throw_dom_exception(cx, global, Error::Type("new.target is null".to_owned())); throw_dom_exception(
cx,
global,
Error::Type("new.target is null".to_owned()),
can_gc,
);
return Err(()); return Err(());
} }
if call_args.callee() == new_target_unwrapped.get() { if call_args.callee() == new_target_unwrapped.get() {
@ -85,6 +90,7 @@ unsafe fn html_constructor(
cx, cx,
global, global,
Error::Type("new.target must not be the active function object".to_owned()), Error::Type("new.target must not be the active function object".to_owned()),
can_gc,
); );
return Err(()); return Err(());
} }
@ -98,6 +104,7 @@ unsafe fn html_constructor(
cx, cx,
global, global,
Error::Type("No custom element definition found for new.target".to_owned()), Error::Type("No custom element definition found for new.target".to_owned()),
can_gc,
); );
return Err(()); return Err(());
}, },
@ -105,7 +112,7 @@ unsafe fn html_constructor(
rooted!(in(*cx) let callee = UnwrapObjectStatic(call_args.callee())); rooted!(in(*cx) let callee = UnwrapObjectStatic(call_args.callee()));
if callee.is_null() { if callee.is_null() {
throw_dom_exception(cx, global, Error::Security); throw_dom_exception(cx, global, Error::Security, can_gc);
return Err(()); return Err(());
} }
@ -139,6 +146,7 @@ unsafe fn html_constructor(
cx, cx,
global, global,
Error::Type("Custom element does not extend the proper interface".to_owned()), Error::Type("Custom element does not extend the proper interface".to_owned()),
can_gc,
); );
return Err(()); return Err(());
} }
@ -178,7 +186,7 @@ unsafe fn html_constructor(
// Step 8.5 // Step 8.5
if !check_type(&element) { if !check_type(&element) {
throw_dom_exception(cx, global, Error::InvalidState); throw_dom_exception(cx, global, Error::InvalidState, can_gc);
return Err(()); return Err(());
} else { } else {
element element
@ -195,7 +203,7 @@ unsafe fn html_constructor(
// Step 13 // Step 13
if !check_type(&element) { if !check_type(&element) {
throw_dom_exception(cx, global, Error::InvalidState); throw_dom_exception(cx, global, Error::InvalidState, can_gc);
return Err(()); return Err(());
} else { } else {
element element
@ -206,7 +214,7 @@ unsafe fn html_constructor(
let s = "Top of construction stack marked AlreadyConstructed due to \ let s = "Top of construction stack marked AlreadyConstructed due to \
a custom element constructor constructing itself after super()" a custom element constructor constructing itself after super()"
.to_string(); .to_string();
throw_dom_exception(cx, global, Error::Type(s)); throw_dom_exception(cx, global, Error::Type(s), can_gc);
return Err(()); return Err(());
}, },
}; };

View file

@ -105,7 +105,12 @@ pub(crate) type Fallible<T> = Result<T, Error>;
pub(crate) type ErrorResult = Fallible<()>; pub(crate) type ErrorResult = Fallible<()>;
/// Set a pending exception for the given `result` on `cx`. /// Set a pending exception for the given `result` on `cx`.
pub(crate) fn throw_dom_exception(cx: SafeJSContext, global: &GlobalScope, result: Error) { pub(crate) fn throw_dom_exception(
cx: SafeJSContext,
global: &GlobalScope,
result: Error,
can_gc: CanGc,
) {
#[cfg(feature = "js_backtrace")] #[cfg(feature = "js_backtrace")]
unsafe { unsafe {
capture_stack!(in(*cx) let stack); capture_stack!(in(*cx) let stack);
@ -159,7 +164,7 @@ pub(crate) fn throw_dom_exception(cx: SafeJSContext, global: &GlobalScope, resul
unsafe { unsafe {
assert!(!JS_IsExceptionPending(*cx)); assert!(!JS_IsExceptionPending(*cx));
let exception = DOMException::new(global, code, CanGc::note()); let exception = DOMException::new(global, code, can_gc);
rooted!(in(*cx) let mut thrown = UndefinedValue()); rooted!(in(*cx) let mut thrown = UndefinedValue());
exception.to_jsval(*cx, thrown.handle_mut()); exception.to_jsval(*cx, thrown.handle_mut());
JS_SetPendingException(*cx, thrown.handle(), ExceptionStackBehavior::Capture); JS_SetPendingException(*cx, thrown.handle(), ExceptionStackBehavior::Capture);
@ -349,7 +354,7 @@ impl Error {
Error::JSFailed => (), Error::JSFailed => (),
_ => unsafe { assert!(!JS_IsExceptionPending(*cx)) }, _ => unsafe { assert!(!JS_IsExceptionPending(*cx)) },
} }
throw_dom_exception(cx, global, self); throw_dom_exception(cx, global, self, CanGc::note());
unsafe { unsafe {
assert!(JS_IsExceptionPending(*cx)); assert!(JS_IsExceptionPending(*cx));
assert!(JS_GetPendingException(*cx, rval)); assert!(JS_GetPendingException(*cx, rval));

View file

@ -44,7 +44,7 @@ use crate::dom::bindings::str::DOMString;
use crate::dom::bindings::utils::delete_property_by_id; use crate::dom::bindings::utils::delete_property_by_id;
use crate::dom::globalscope::{GlobalScope, GlobalScopeHelpers}; use crate::dom::globalscope::{GlobalScope, GlobalScopeHelpers};
use crate::realms::{AlreadyInRealm, InRealm}; use crate::realms::{AlreadyInRealm, InRealm};
use crate::script_runtime::JSContext as SafeJSContext; use crate::script_runtime::{CanGc, JSContext as SafeJSContext};
/// Determine if this id shadows any existing properties for this proxy. /// Determine if this id shadows any existing properties for this proxy.
pub(crate) unsafe extern "C" fn shadow_check_callback( pub(crate) unsafe extern "C" fn shadow_check_callback(
@ -253,7 +253,7 @@ pub(crate) unsafe fn report_cross_origin_denial(
if !JS_IsExceptionPending(*cx) { if !JS_IsExceptionPending(*cx) {
let global = GlobalScope::from_context(*cx, InRealm::Already(&in_realm_proof)); let global = GlobalScope::from_context(*cx, InRealm::Already(&in_realm_proof));
// TODO: include `id` and `access` in the exception message // TODO: include `id` and `access` in the exception message
throw_dom_exception(cx, &global, Error::Security); throw_dom_exception(cx, &global, Error::Security, CanGc::note());
} }
false false
} }

View file

@ -689,7 +689,7 @@ impl DomHelpers<crate::DomTypeHolder> for crate::DomTypeHolder {
global: &<crate::DomTypeHolder as DomTypes>::GlobalScope, global: &<crate::DomTypeHolder as DomTypes>::GlobalScope,
result: Error, result: Error,
) { ) {
throw_dom_exception(cx, global, result) throw_dom_exception(cx, global, result, CanGc::note())
} }
unsafe fn call_html_constructor< unsafe fn call_html_constructor<

View file

@ -601,7 +601,7 @@ impl CanvasRenderingContext2DMethods<crate::DomTypeHolder> for CanvasRenderingCo
y1: Finite<f64>, y1: Finite<f64>,
) -> DomRoot<CanvasGradient> { ) -> DomRoot<CanvasGradient> {
self.canvas_state self.canvas_state
.create_linear_gradient(&self.global(), x0, y0, x1, y1) .create_linear_gradient(&self.global(), x0, y0, x1, y1, CanGc::note())
} }
// https://html.spec.whatwg.org/multipage/#dom-context-2d-createradialgradient // https://html.spec.whatwg.org/multipage/#dom-context-2d-createradialgradient
@ -614,8 +614,16 @@ impl CanvasRenderingContext2DMethods<crate::DomTypeHolder> for CanvasRenderingCo
y1: Finite<f64>, y1: Finite<f64>,
r1: Finite<f64>, r1: Finite<f64>,
) -> Fallible<DomRoot<CanvasGradient>> { ) -> Fallible<DomRoot<CanvasGradient>> {
self.canvas_state self.canvas_state.create_radial_gradient(
.create_radial_gradient(&self.global(), x0, y0, r0, x1, y1, r1) &self.global(),
x0,
y0,
r0,
x1,
y1,
r1,
CanGc::note(),
)
} }
// https://html.spec.whatwg.org/multipage/#dom-context-2d-createpattern // https://html.spec.whatwg.org/multipage/#dom-context-2d-createpattern
@ -625,7 +633,7 @@ impl CanvasRenderingContext2DMethods<crate::DomTypeHolder> for CanvasRenderingCo
repetition: DOMString, repetition: DOMString,
) -> Fallible<Option<DomRoot<CanvasPattern>>> { ) -> Fallible<Option<DomRoot<CanvasPattern>>> {
self.canvas_state self.canvas_state
.create_pattern(&self.global(), image, repetition) .create_pattern(&self.global(), image, repetition, CanGc::note())
} }
// https://html.spec.whatwg.org/multipage/#dom-context-2d-linewidth // https://html.spec.whatwg.org/multipage/#dom-context-2d-linewidth

View file

@ -35,6 +35,7 @@ impl ConstantSourceNode {
window: &Window, window: &Window,
context: &BaseAudioContext, context: &BaseAudioContext,
options: &ConstantSourceOptions, options: &ConstantSourceOptions,
can_gc: CanGc,
) -> Fallible<ConstantSourceNode> { ) -> Fallible<ConstantSourceNode> {
let node_options = Default::default(); let node_options = Default::default();
let source_node = AudioScheduledSourceNode::new_inherited( let source_node = AudioScheduledSourceNode::new_inherited(
@ -55,7 +56,7 @@ impl ConstantSourceNode {
*options.offset, *options.offset,
f32::MIN, f32::MIN,
f32::MAX, f32::MAX,
CanGc::note(), can_gc,
); );
Ok(ConstantSourceNode { Ok(ConstantSourceNode {
@ -81,7 +82,7 @@ impl ConstantSourceNode {
options: &ConstantSourceOptions, options: &ConstantSourceOptions,
can_gc: CanGc, can_gc: CanGc,
) -> Fallible<DomRoot<ConstantSourceNode>> { ) -> Fallible<DomRoot<ConstantSourceNode>> {
let node = ConstantSourceNode::new_inherited(window, context, options)?; let node = ConstantSourceNode::new_inherited(window, context, options, can_gc)?;
Ok(reflect_dom_object_with_proto( Ok(reflect_dom_object_with_proto(
Box::new(node), Box::new(node),
window, window,

View file

@ -189,7 +189,7 @@ fn create_html_element(
// JavaScript objects associated realms global object. // JavaScript objects associated realms global object.
let ar = enter_realm(&*global); let ar = enter_realm(&*global);
throw_dom_exception(cx, &global, error); throw_dom_exception(cx, &global, error, can_gc);
report_pending_exception(cx, true, InRealm::Entered(&ar), can_gc); report_pending_exception(cx, true, InRealm::Entered(&ar), can_gc);
// Substep 2. Set result to a new element that implements the HTMLUnknownElement interface, // Substep 2. Set result to a new element that implements the HTMLUnknownElement interface,

View file

@ -81,6 +81,7 @@ impl CSSGroupingRuleMethods<crate::DomTypeHolder> for CSSGroupingRule {
index, index,
containing_rule_types, containing_rule_types,
parse_relative_rule_type, parse_relative_rule_type,
CanGc::note(),
) )
} }

View file

@ -80,67 +80,44 @@ impl CSSRule {
window: &Window, window: &Window,
parent_stylesheet: &CSSStyleSheet, parent_stylesheet: &CSSStyleSheet,
rule: StyleCssRule, rule: StyleCssRule,
can_gc: CanGc,
) -> DomRoot<CSSRule> { ) -> DomRoot<CSSRule> {
// be sure to update the match in as_specific when this is updated // be sure to update the match in as_specific when this is updated
match rule { match rule {
StyleCssRule::Import(s) => DomRoot::upcast(CSSImportRule::new( StyleCssRule::Import(s) => {
window, DomRoot::upcast(CSSImportRule::new(window, parent_stylesheet, s, can_gc))
parent_stylesheet, },
s, StyleCssRule::Style(s) => {
CanGc::note(), DomRoot::upcast(CSSStyleRule::new(window, parent_stylesheet, s, can_gc))
)), },
StyleCssRule::Style(s) => DomRoot::upcast(CSSStyleRule::new( StyleCssRule::FontFace(s) => {
window, DomRoot::upcast(CSSFontFaceRule::new(window, parent_stylesheet, s, can_gc))
parent_stylesheet, },
s,
CanGc::note(),
)),
StyleCssRule::FontFace(s) => DomRoot::upcast(CSSFontFaceRule::new(
window,
parent_stylesheet,
s,
CanGc::note(),
)),
StyleCssRule::FontFeatureValues(_) => unimplemented!(), StyleCssRule::FontFeatureValues(_) => unimplemented!(),
StyleCssRule::CounterStyle(_) => unimplemented!(), StyleCssRule::CounterStyle(_) => unimplemented!(),
StyleCssRule::Keyframes(s) => DomRoot::upcast(CSSKeyframesRule::new( StyleCssRule::Keyframes(s) => {
window, DomRoot::upcast(CSSKeyframesRule::new(window, parent_stylesheet, s, can_gc))
parent_stylesheet, },
s, StyleCssRule::Media(s) => {
CanGc::note(), DomRoot::upcast(CSSMediaRule::new(window, parent_stylesheet, s, can_gc))
)), },
StyleCssRule::Media(s) => DomRoot::upcast(CSSMediaRule::new( StyleCssRule::Namespace(s) => {
window, DomRoot::upcast(CSSNamespaceRule::new(window, parent_stylesheet, s, can_gc))
parent_stylesheet, },
s, StyleCssRule::Supports(s) => {
CanGc::note(), DomRoot::upcast(CSSSupportsRule::new(window, parent_stylesheet, s, can_gc))
)), },
StyleCssRule::Namespace(s) => DomRoot::upcast(CSSNamespaceRule::new(
window,
parent_stylesheet,
s,
CanGc::note(),
)),
StyleCssRule::Supports(s) => DomRoot::upcast(CSSSupportsRule::new(
window,
parent_stylesheet,
s,
CanGc::note(),
)),
StyleCssRule::Page(_) => unreachable!(), StyleCssRule::Page(_) => unreachable!(),
StyleCssRule::Container(_) => unimplemented!(), // TODO StyleCssRule::Container(_) => unimplemented!(), // TODO
StyleCssRule::Document(_) => unimplemented!(), // TODO StyleCssRule::Document(_) => unimplemented!(), // TODO
StyleCssRule::LayerBlock(s) => DomRoot::upcast(CSSLayerBlockRule::new( StyleCssRule::LayerBlock(s) => {
window, DomRoot::upcast(CSSLayerBlockRule::new(window, parent_stylesheet, s, can_gc))
parent_stylesheet, },
s,
CanGc::note(),
)),
StyleCssRule::LayerStatement(s) => DomRoot::upcast(CSSLayerStatementRule::new( StyleCssRule::LayerStatement(s) => DomRoot::upcast(CSSLayerStatementRule::new(
window, window,
parent_stylesheet, parent_stylesheet,
s, s,
CanGc::note(), can_gc,
)), )),
StyleCssRule::FontPaletteValues(_) => unimplemented!(), // TODO StyleCssRule::FontPaletteValues(_) => unimplemented!(), // TODO
StyleCssRule::Property(_) => unimplemented!(), // TODO StyleCssRule::Property(_) => unimplemented!(), // TODO

View file

@ -104,6 +104,7 @@ impl CSSRuleList {
idx: u32, idx: u32,
containing_rule_types: CssRuleTypes, containing_rule_types: CssRuleTypes,
parse_relative_rule_type: Option<CssRuleType>, parse_relative_rule_type: Option<CssRuleType>,
can_gc: CanGc,
) -> Fallible<u32> { ) -> Fallible<u32> {
let css_rules = if let RulesSource::Rules(ref rules) = self.rules { let css_rules = if let RulesSource::Rules(ref rules) = self.rules {
rules rules
@ -135,7 +136,7 @@ impl CSSRuleList {
)?; )?;
let parent_stylesheet = &*self.parent_stylesheet; let parent_stylesheet = &*self.parent_stylesheet;
let dom_rule = CSSRule::new_specific(window, parent_stylesheet, new_rule); let dom_rule = CSSRule::new_specific(window, parent_stylesheet, new_rule, can_gc);
self.dom_rules self.dom_rules
.borrow_mut() .borrow_mut()
.insert(index, MutNullableDom::new(Some(&*dom_rule))); .insert(index, MutNullableDom::new(Some(&*dom_rule)));
@ -189,6 +190,7 @@ impl CSSRuleList {
self.global().as_window(), self.global().as_window(),
parent_stylesheet, parent_stylesheet,
rules.read_with(&guard).0[idx as usize].clone(), rules.read_with(&guard).0[idx as usize].clone(),
CanGc::note(),
), ),
RulesSource::Keyframes(ref rules) => DomRoot::upcast(CSSKeyframeRule::new( RulesSource::Keyframes(ref rules) => DomRoot::upcast(CSSKeyframeRule::new(
self.global().as_window(), self.global().as_window(),

View file

@ -114,12 +114,12 @@ impl CSSStyleSheet {
self.origin_clean.set(origin_clean); self.origin_clean.set(origin_clean);
} }
pub(crate) fn medialist(&self) -> DomRoot<MediaList> { pub(crate) fn medialist(&self, can_gc: CanGc) -> DomRoot<MediaList> {
MediaList::new( MediaList::new(
self.global().as_window(), self.global().as_window(),
self, self,
self.style_stylesheet().media.clone(), self.style_stylesheet().media.clone(),
CanGc::note(), can_gc,
) )
} }
} }
@ -139,7 +139,7 @@ impl CSSStyleSheetMethods<crate::DomTypeHolder> for CSSStyleSheet {
return Err(Error::Security); return Err(Error::Security);
} }
self.rulelist() self.rulelist()
.insert_rule(&rule, index, CssRuleTypes::default(), None) .insert_rule(&rule, index, CssRuleTypes::default(), None, CanGc::note())
} }
// https://drafts.csswg.org/cssom/#dom-cssstylesheet-deleterule // https://drafts.csswg.org/cssom/#dom-cssstylesheet-deleterule

View file

@ -581,7 +581,7 @@ impl CustomElementRegistryMethods<crate::DomTypeHolder> for CustomElementRegistr
promise.reject_native(&DOMException::new( promise.reject_native(&DOMException::new(
self.window.as_global_scope(), self.window.as_global_scope(),
DOMErrorName::SyntaxError, DOMErrorName::SyntaxError,
CanGc::note(), can_gc,
)); ));
return promise; return promise;
} }
@ -850,7 +850,7 @@ pub(crate) fn upgrade_element(
let global = GlobalScope::current().expect("No current global"); let global = GlobalScope::current().expect("No current global");
let cx = GlobalScope::get_cx(); let cx = GlobalScope::get_cx();
let ar = enter_realm(&*global); let ar = enter_realm(&*global);
throw_dom_exception(cx, &global, error); throw_dom_exception(cx, &global, error, can_gc);
report_pending_exception(cx, true, InRealm::Entered(&ar), can_gc); report_pending_exception(cx, true, InRealm::Entered(&ar), can_gc);
return; return;

View file

@ -2101,6 +2101,7 @@ impl Document {
false, false,
false, false,
false, false,
can_gc,
); );
let event = event.upcast::<Event>(); let event = event.upcast::<Event>();
let result = event.fire(&target, can_gc); let result = event.fire(&target, can_gc);
@ -2540,7 +2541,7 @@ impl Document {
self.process_pending_parsing_blocking_script(can_gc); self.process_pending_parsing_blocking_script(can_gc);
// Step 3. // Step 3.
self.process_deferred_scripts(); self.process_deferred_scripts(can_gc);
}, },
LoadType::PageSource(_) => { LoadType::PageSource(_) => {
// We finished loading the page, so if the `Window` is still waiting for // We finished loading the page, so if the `Window` is still waiting for
@ -2553,7 +2554,7 @@ impl Document {
// this is the first opportunity to process them. // this is the first opportunity to process them.
// Step 3. // Step 3.
self.process_deferred_scripts(); self.process_deferred_scripts(can_gc);
}, },
_ => {}, _ => {},
} }
@ -2590,6 +2591,7 @@ impl Document {
atom!("beforeunload"), atom!("beforeunload"),
EventBubbles::Bubbles, EventBubbles::Bubbles,
EventCancelable::Cancelable, EventCancelable::Cancelable,
can_gc,
); );
let event = beforeunload_event.upcast::<Event>(); let event = beforeunload_event.upcast::<Event>();
event.set_trusted(true); event.set_trusted(true);
@ -2929,7 +2931,12 @@ impl Document {
/// <https://html.spec.whatwg.org/multipage/#the-end> step 5. /// <https://html.spec.whatwg.org/multipage/#the-end> step 5.
/// <https://html.spec.whatwg.org/multipage/#prepare-a-script> step 22.d. /// <https://html.spec.whatwg.org/multipage/#prepare-a-script> step 22.d.
pub(crate) fn asap_script_loaded(&self, element: &HTMLScriptElement, result: ScriptResult) { pub(crate) fn asap_script_loaded(
&self,
element: &HTMLScriptElement,
result: ScriptResult,
can_gc: CanGc,
) {
{ {
let mut scripts = self.asap_scripts_set.borrow_mut(); let mut scripts = self.asap_scripts_set.borrow_mut();
let idx = scripts let idx = scripts
@ -2938,7 +2945,7 @@ impl Document {
.unwrap(); .unwrap();
scripts.swap_remove(idx); scripts.swap_remove(idx);
} }
element.execute(result, CanGc::note()); element.execute(result, can_gc);
} }
// https://html.spec.whatwg.org/multipage/#list-of-scripts-that-will-execute-in-order-as-soon-as-possible // https://html.spec.whatwg.org/multipage/#list-of-scripts-that-will-execute-in-order-as-soon-as-possible
@ -2952,13 +2959,14 @@ impl Document {
&self, &self,
element: &HTMLScriptElement, element: &HTMLScriptElement,
result: ScriptResult, result: ScriptResult,
can_gc: CanGc,
) { ) {
self.asap_in_order_scripts_list.loaded(element, result); self.asap_in_order_scripts_list.loaded(element, result);
while let Some((element, result)) = self while let Some((element, result)) = self
.asap_in_order_scripts_list .asap_in_order_scripts_list
.take_next_ready_to_be_executed() .take_next_ready_to_be_executed()
{ {
element.execute(result, CanGc::note()); element.execute(result, can_gc);
} }
} }
@ -2971,11 +2979,11 @@ impl Document {
/// <https://html.spec.whatwg.org/multipage/#prepare-a-script> step 22.d. /// <https://html.spec.whatwg.org/multipage/#prepare-a-script> step 22.d.
pub(crate) fn deferred_script_loaded(&self, element: &HTMLScriptElement, result: ScriptResult) { pub(crate) fn deferred_script_loaded(&self, element: &HTMLScriptElement, result: ScriptResult) {
self.deferred_scripts.loaded(element, result); self.deferred_scripts.loaded(element, result);
self.process_deferred_scripts(); self.process_deferred_scripts(CanGc::note());
} }
/// <https://html.spec.whatwg.org/multipage/#the-end> step 3. /// <https://html.spec.whatwg.org/multipage/#the-end> step 3.
fn process_deferred_scripts(&self) { fn process_deferred_scripts(&self, can_gc: CanGc) {
if self.ready_state.get() != DocumentReadyState::Interactive { if self.ready_state.get() != DocumentReadyState::Interactive {
return; return;
} }
@ -2986,7 +2994,7 @@ impl Document {
} }
if let Some((element, result)) = self.deferred_scripts.take_next_ready_to_be_executed() if let Some((element, result)) = self.deferred_scripts.take_next_ready_to_be_executed()
{ {
element.execute(result, CanGc::note()); element.execute(result, can_gc);
} else { } else {
break; break;
} }
@ -5143,7 +5151,7 @@ impl DocumentMethods<crate::DomTypeHolder> for Document {
what_to_show: u32, what_to_show: u32,
filter: Option<Rc<NodeFilter>>, filter: Option<Rc<NodeFilter>>,
) -> DomRoot<NodeIterator> { ) -> DomRoot<NodeIterator> {
NodeIterator::new(self, root, what_to_show, filter) NodeIterator::new(self, root, what_to_show, filter, CanGc::note())
} }
// https://dom.spec.whatwg.org/#dom-document-createtreewalker // https://dom.spec.whatwg.org/#dom-document-createtreewalker
@ -5302,7 +5310,7 @@ impl DocumentMethods<crate::DomTypeHolder> for Document {
// https://html.spec.whatwg.org/multipage/#dom-document-getelementsbyname // https://html.spec.whatwg.org/multipage/#dom-document-getelementsbyname
fn GetElementsByName(&self, name: DOMString) -> DomRoot<NodeList> { fn GetElementsByName(&self, name: DOMString) -> DomRoot<NodeList> {
NodeList::new_elements_by_name_list(self.window(), self, name) NodeList::new_elements_by_name_list(self.window(), self, name, CanGc::note())
} }
// https://html.spec.whatwg.org/multipage/#dom-document-images // https://html.spec.whatwg.org/multipage/#dom-document-images

View file

@ -508,6 +508,7 @@ impl Element {
mode: ShadowRootMode, mode: ShadowRootMode,
clonable: bool, clonable: bool,
slot_assignment_mode: SlotAssignmentMode, slot_assignment_mode: SlotAssignmentMode,
can_gc: CanGc,
) -> Fallible<DomRoot<ShadowRoot>> { ) -> Fallible<DomRoot<ShadowRoot>> {
// Step 1. // Step 1.
// If elements namespace is not the HTML namespace, // If elements namespace is not the HTML namespace,
@ -539,7 +540,7 @@ impl Element {
mode, mode,
slot_assignment_mode, slot_assignment_mode,
clonable, clonable,
CanGc::note(), can_gc,
); );
self.ensure_rare_data().shadow_root = Some(Dom::from_ref(&*shadow_root)); self.ensure_rare_data().shadow_root = Some(Dom::from_ref(&*shadow_root));
shadow_root shadow_root
@ -3149,6 +3150,7 @@ impl ElementMethods<crate::DomTypeHolder> for Element {
init.mode, init.mode,
init.clonable, init.clonable,
init.slotAssignment, init.slotAssignment,
CanGc::note(),
)?; )?;
// Step 2. Return thiss shadow root. // Step 2. Return thiss shadow root.

View file

@ -300,6 +300,7 @@ impl ElementInternalsMethods<crate::DomTypeHolder> for ElementInternals {
NodeList::new_labels_list( NodeList::new_labels_list(
self.target_element.upcast::<Node>().owner_doc().window(), self.target_element.upcast::<Node>().owner_doc().window(),
&self.target_element, &self.target_element,
CanGc::note(),
) )
})) }))
} }

View file

@ -130,7 +130,7 @@ impl Gamepad {
xr: bool, xr: bool,
can_gc: CanGc, can_gc: CanGc,
) -> DomRoot<Gamepad> { ) -> DomRoot<Gamepad> {
let button_list = GamepadButtonList::init_buttons(global); let button_list = GamepadButtonList::init_buttons(global, can_gc);
let vibration_actuator = let vibration_actuator =
GamepadHapticActuator::new(global, gamepad_id, supported_haptic_effects, can_gc); GamepadHapticActuator::new(global, gamepad_id, supported_haptic_effects, can_gc);
let index = if xr { -1 } else { 0 }; let index = if xr { -1 } else { 0 };

View file

@ -62,27 +62,27 @@ impl GamepadButtonListMethods<crate::DomTypeHolder> for GamepadButtonList {
impl GamepadButtonList { impl GamepadButtonList {
/// Initialize the number of buttons in the "standard" gamepad mapping. /// Initialize the number of buttons in the "standard" gamepad mapping.
/// <https://www.w3.org/TR/gamepad/#dfn-initializing-buttons> /// <https://www.w3.org/TR/gamepad/#dfn-initializing-buttons>
pub(crate) fn init_buttons(global: &GlobalScope) -> DomRoot<GamepadButtonList> { pub(crate) fn init_buttons(global: &GlobalScope, can_gc: CanGc) -> DomRoot<GamepadButtonList> {
let standard_buttons = &[ let standard_buttons = &[
GamepadButton::new(global, false, false, CanGc::note()), // Bottom button in right cluster GamepadButton::new(global, false, false, can_gc), // Bottom button in right cluster
GamepadButton::new(global, false, false, CanGc::note()), // Right button in right cluster GamepadButton::new(global, false, false, can_gc), // Right button in right cluster
GamepadButton::new(global, false, false, CanGc::note()), // Left button in right cluster GamepadButton::new(global, false, false, can_gc), // Left button in right cluster
GamepadButton::new(global, false, false, CanGc::note()), // Top button in right cluster GamepadButton::new(global, false, false, can_gc), // Top button in right cluster
GamepadButton::new(global, false, false, CanGc::note()), // Top left front button GamepadButton::new(global, false, false, can_gc), // Top left front button
GamepadButton::new(global, false, false, CanGc::note()), // Top right front button GamepadButton::new(global, false, false, can_gc), // Top right front button
GamepadButton::new(global, false, false, CanGc::note()), // Bottom left front button GamepadButton::new(global, false, false, can_gc), // Bottom left front button
GamepadButton::new(global, false, false, CanGc::note()), // Bottom right front button GamepadButton::new(global, false, false, can_gc), // Bottom right front button
GamepadButton::new(global, false, false, CanGc::note()), // Left button in center cluster GamepadButton::new(global, false, false, can_gc), // Left button in center cluster
GamepadButton::new(global, false, false, CanGc::note()), // Right button in center cluster GamepadButton::new(global, false, false, can_gc), // Right button in center cluster
GamepadButton::new(global, false, false, CanGc::note()), // Left stick pressed button GamepadButton::new(global, false, false, can_gc), // Left stick pressed button
GamepadButton::new(global, false, false, CanGc::note()), // Right stick pressed button GamepadButton::new(global, false, false, can_gc), // Right stick pressed button
GamepadButton::new(global, false, false, CanGc::note()), // Top button in left cluster GamepadButton::new(global, false, false, can_gc), // Top button in left cluster
GamepadButton::new(global, false, false, CanGc::note()), // Bottom button in left cluster GamepadButton::new(global, false, false, can_gc), // Bottom button in left cluster
GamepadButton::new(global, false, false, CanGc::note()), // Left button in left cluster GamepadButton::new(global, false, false, can_gc), // Left button in left cluster
GamepadButton::new(global, false, false, CanGc::note()), // Right button in left cluster GamepadButton::new(global, false, false, can_gc), // Right button in left cluster
GamepadButton::new(global, false, false, CanGc::note()), // Center button in center cluster GamepadButton::new(global, false, false, can_gc), // Center button in center cluster
]; ];
rooted_vec!(let buttons <- standard_buttons.iter().map(DomRoot::as_traced)); rooted_vec!(let buttons <- standard_buttons.iter().map(DomRoot::as_traced));
Self::new(global, buttons.r(), CanGc::note()) Self::new(global, buttons.r(), can_gc)
} }
} }

View file

@ -796,6 +796,7 @@ impl GlobalScope {
} }
/// <https://w3c.github.io/ServiceWorker/#get-the-service-worker-registration-object> /// <https://w3c.github.io/ServiceWorker/#get-the-service-worker-registration-object>
#[allow(clippy::too_many_arguments)]
pub(crate) fn get_serviceworker_registration( pub(crate) fn get_serviceworker_registration(
&self, &self,
script_url: &ServoUrl, script_url: &ServoUrl,
@ -804,6 +805,7 @@ impl GlobalScope {
installing_worker: Option<ServiceWorkerId>, installing_worker: Option<ServiceWorkerId>,
_waiting_worker: Option<ServiceWorkerId>, _waiting_worker: Option<ServiceWorkerId>,
_active_worker: Option<ServiceWorkerId>, _active_worker: Option<ServiceWorkerId>,
can_gc: CanGc,
) -> DomRoot<ServiceWorkerRegistration> { ) -> DomRoot<ServiceWorkerRegistration> {
// Step 1 // Step 1
let mut registrations = self.registration_map.borrow_mut(); let mut registrations = self.registration_map.borrow_mut();
@ -815,11 +817,11 @@ impl GlobalScope {
// Step 2.1 -> 2.5 // Step 2.1 -> 2.5
let new_registration = let new_registration =
ServiceWorkerRegistration::new(self, scope.clone(), registration_id, CanGc::note()); ServiceWorkerRegistration::new(self, scope.clone(), registration_id, can_gc);
// Step 2.6 // Step 2.6
if let Some(worker_id) = installing_worker { if let Some(worker_id) = installing_worker {
let worker = self.get_serviceworker(script_url, scope, worker_id); let worker = self.get_serviceworker(script_url, scope, worker_id, can_gc);
new_registration.set_installing(&worker); new_registration.set_installing(&worker);
} }
@ -840,6 +842,7 @@ impl GlobalScope {
script_url: &ServoUrl, script_url: &ServoUrl,
scope: &ServoUrl, scope: &ServoUrl,
worker_id: ServiceWorkerId, worker_id: ServiceWorkerId,
can_gc: CanGc,
) -> DomRoot<ServiceWorker> { ) -> DomRoot<ServiceWorker> {
// Step 1 // Step 1
let mut workers = self.worker_map.borrow_mut(); let mut workers = self.worker_map.borrow_mut();
@ -850,13 +853,8 @@ impl GlobalScope {
} else { } else {
// Step 2.1 // Step 2.1
// TODO: step 2.2, worker state. // TODO: step 2.2, worker state.
let new_worker = ServiceWorker::new( let new_worker =
self, ServiceWorker::new(self, script_url.clone(), scope.clone(), worker_id, can_gc);
script_url.clone(),
scope.clone(),
worker_id,
CanGc::note(),
);
// Step 2.3 // Step 2.3
workers.insert(worker_id, Dom::from_ref(&*new_worker)); workers.insert(worker_id, Dom::from_ref(&*new_worker));
@ -3010,7 +3008,7 @@ impl GlobalScope {
.expect("GPUDevice should still be in devices hashmap") .expect("GPUDevice should still be in devices hashmap")
.root() .root()
{ {
device.lose(reason, msg); device.lose(reason, msg, CanGc::note());
} }
} }

View file

@ -357,7 +357,7 @@ impl Activatable for HTMLButtonElement {
} }
// https://html.spec.whatwg.org/multipage/#run-post-click-activation-steps // https://html.spec.whatwg.org/multipage/#run-post-click-activation-steps
fn activation_behavior(&self, _event: &Event, _target: &EventTarget, _can_gc: CanGc) { fn activation_behavior(&self, _event: &Event, _target: &EventTarget, can_gc: CanGc) {
let ty = self.button_type.get(); let ty = self.button_type.get();
match ty { match ty {
//https://html.spec.whatwg.org/multipage/#attr-button-type-submit-state //https://html.spec.whatwg.org/multipage/#attr-button-type-submit-state
@ -367,14 +367,14 @@ impl Activatable for HTMLButtonElement {
owner.submit( owner.submit(
SubmittedFrom::NotFromForm, SubmittedFrom::NotFromForm,
FormSubmitterElement::Button(self), FormSubmitterElement::Button(self),
CanGc::note(), can_gc,
); );
} }
}, },
ButtonType::Reset => { ButtonType::Reset => {
// TODO: is document owner fully active? // TODO: is document owner fully active?
if let Some(owner) = self.form_owner() { if let Some(owner) = self.form_owner() {
owner.reset(ResetFrom::NotFromForm, CanGc::note()); owner.reset(ResetFrom::NotFromForm, can_gc);
} }
}, },
_ => (), _ => (),

View file

@ -186,24 +186,24 @@ impl HTMLCanvasElement {
} }
} }
pub(crate) fn set_natural_width(&self, value: u32) { pub(crate) fn set_natural_width(&self, value: u32, can_gc: CanGc) {
let value = if value > UNSIGNED_LONG_MAX { let value = if value > UNSIGNED_LONG_MAX {
DEFAULT_WIDTH DEFAULT_WIDTH
} else { } else {
value value
}; };
let element = self.upcast::<Element>(); let element = self.upcast::<Element>();
element.set_uint_attribute(&html5ever::local_name!("width"), value, CanGc::note()); element.set_uint_attribute(&html5ever::local_name!("width"), value, can_gc);
} }
pub(crate) fn set_natural_height(&self, value: u32) { pub(crate) fn set_natural_height(&self, value: u32, can_gc: CanGc) {
let value = if value > UNSIGNED_LONG_MAX { let value = if value > UNSIGNED_LONG_MAX {
DEFAULT_HEIGHT DEFAULT_HEIGHT
} else { } else {
value value
}; };
let element = self.upcast::<Element>(); let element = self.upcast::<Element>();
element.set_uint_attribute(&html5ever::local_name!("height"), value, CanGc::note()); element.set_uint_attribute(&html5ever::local_name!("height"), value, can_gc);
} }
} }
@ -256,7 +256,7 @@ impl HTMLCanvasElement {
ref_filter_map(self.context.borrow(), |ctx| ctx.as_ref()) ref_filter_map(self.context.borrow(), |ctx| ctx.as_ref())
} }
fn get_or_init_2d_context(&self) -> Option<DomRoot<CanvasRenderingContext2D>> { fn get_or_init_2d_context(&self, can_gc: CanGc) -> Option<DomRoot<CanvasRenderingContext2D>> {
if let Some(ctx) = self.context() { if let Some(ctx) = self.context() {
return match *ctx { return match *ctx {
CanvasContext::Context2d(ref ctx) => Some(DomRoot::from_ref(ctx)), CanvasContext::Context2d(ref ctx) => Some(DomRoot::from_ref(ctx)),
@ -266,8 +266,7 @@ impl HTMLCanvasElement {
let window = self.owner_window(); let window = self.owner_window();
let size = self.get_size(); let size = self.get_size();
let context = let context = CanvasRenderingContext2D::new(window.as_global_scope(), self, size, can_gc);
CanvasRenderingContext2D::new(window.as_global_scope(), self, size, CanGc::note());
*self.context.borrow_mut() = Some(CanvasContext::Context2d(Dom::from_ref(&*context))); *self.context.borrow_mut() = Some(CanvasContext::Context2d(Dom::from_ref(&*context)));
Some(context) Some(context)
} }
@ -544,7 +543,7 @@ impl HTMLCanvasElementMethods<crate::DomTypeHolder> for HTMLCanvasElement {
Ok(match &*id { Ok(match &*id {
"2d" => self "2d" => self
.get_or_init_2d_context() .get_or_init_2d_context(can_gc)
.map(RenderingContext::CanvasRenderingContext2D), .map(RenderingContext::CanvasRenderingContext2D),
"webgl" | "experimental-webgl" => self "webgl" | "experimental-webgl" => self
.get_or_init_webgl_context(cx, options, can_gc) .get_or_init_webgl_context(cx, options, can_gc)

View file

@ -95,7 +95,12 @@ impl HTMLFormControlsCollectionMethods<crate::DomTypeHolder> for HTMLFormControl
// specifically HTMLFormElement::Elements(), // specifically HTMLFormElement::Elements(),
// and the collection filter excludes image inputs. // and the collection filter excludes image inputs.
Some(RadioNodeListOrElement::RadioNodeList( Some(RadioNodeListOrElement::RadioNodeList(
RadioNodeList::new_controls_except_image_inputs(window, &self.form, &name), RadioNodeList::new_controls_except_image_inputs(
window,
&self.form,
&name,
CanGc::note(),
),
)) ))
} }
// Step 3 // Step 3

View file

@ -445,12 +445,13 @@ impl HTMLFormElementMethods<crate::DomTypeHolder> for HTMLFormElement {
let name = Atom::from(name); let name = Atom::from(name);
// Step 1 // Step 1
let mut candidates = RadioNodeList::new_controls_except_image_inputs(&window, self, &name); let mut candidates =
RadioNodeList::new_controls_except_image_inputs(&window, self, &name, CanGc::note());
let mut candidates_length = candidates.Length(); let mut candidates_length = candidates.Length();
// Step 2 // Step 2
if candidates_length == 0 { if candidates_length == 0 {
candidates = RadioNodeList::new_images(&window, self, &name); candidates = RadioNodeList::new_images(&window, self, &name, CanGc::note());
candidates_length = candidates.Length(); candidates_length = candidates.Length();
} }
@ -1260,7 +1261,7 @@ impl HTMLFormElement {
let event = self let event = self
.upcast::<EventTarget>() .upcast::<EventTarget>()
.fire_bubbling_cancelable_event(atom!("reset"), CanGc::note()); .fire_bubbling_cancelable_event(atom!("reset"), can_gc);
if event.DefaultPrevented() { if event.DefaultPrevented() {
return; return;
} }

View file

@ -557,7 +557,7 @@ impl HTMLImageElement {
request.metadata = None; request.metadata = None;
if matches!(state, State::Broken) { if matches!(state, State::Broken) {
self.reject_image_decode_promises(); self.reject_image_decode_promises(can_gc);
} else if matches!(state, State::CompletelyAvailable) { } else if matches!(state, State::CompletelyAvailable) {
self.resolve_image_decode_promises(); self.resolve_image_decode_promises();
} }
@ -1170,7 +1170,7 @@ impl HTMLImageElement {
} }
// Step 2 for <https://html.spec.whatwg.org/multipage/#dom-img-decode> // Step 2 for <https://html.spec.whatwg.org/multipage/#dom-img-decode>
fn react_to_decode_image_sync_steps(&self, promise: Rc<Promise>) { fn react_to_decode_image_sync_steps(&self, promise: Rc<Promise>, can_gc: CanGc) {
let document = self.owner_document(); let document = self.owner_document();
// Step 2.1 of <https://html.spec.whatwg.org/multipage/#dom-img-decode> // Step 2.1 of <https://html.spec.whatwg.org/multipage/#dom-img-decode>
if !document.is_fully_active() || if !document.is_fully_active() ||
@ -1179,7 +1179,7 @@ impl HTMLImageElement {
promise.reject_native(&DOMException::new( promise.reject_native(&DOMException::new(
&document.global(), &document.global(),
DOMErrorName::EncodingError, DOMErrorName::EncodingError,
CanGc::note(), can_gc,
)); ));
} else if matches!( } else if matches!(
self.current_request.borrow().state, self.current_request.borrow().state,
@ -1201,13 +1201,13 @@ impl HTMLImageElement {
self.image_decode_promises.borrow_mut().clear(); self.image_decode_promises.borrow_mut().clear();
} }
fn reject_image_decode_promises(&self) { fn reject_image_decode_promises(&self, can_gc: CanGc) {
let document = self.owner_document(); let document = self.owner_document();
for promise in self.image_decode_promises.borrow().iter() { for promise in self.image_decode_promises.borrow().iter() {
promise.reject_native(&DOMException::new( promise.reject_native(&DOMException::new(
&document.global(), &document.global(),
DOMErrorName::EncodingError, DOMErrorName::EncodingError,
CanGc::note(), can_gc,
)); ));
} }
self.image_decode_promises.borrow_mut().clear(); self.image_decode_promises.borrow_mut().clear();
@ -1408,7 +1408,7 @@ impl MicrotaskRunnable for ImageElementMicrotask {
ref elem, ref elem,
ref promise, ref promise,
} => { } => {
elem.react_to_decode_image_sync_steps(promise.clone()); elem.react_to_decode_image_sync_steps(promise.clone(), can_gc);
}, },
} }
} }

View file

@ -1561,6 +1561,7 @@ impl HTMLInputElementMethods<crate::DomTypeHolder> for HTMLInputElement {
NodeList::new_labels_list( NodeList::new_labels_list(
self.upcast::<Node>().owner_doc().window(), self.upcast::<Node>().owner_doc().window(),
self.upcast::<HTMLElement>(), self.upcast::<HTMLElement>(),
CanGc::note(),
) )
})) }))
} }

View file

@ -1899,6 +1899,7 @@ impl HTMLMediaElement {
ShadowRootMode::Closed, ShadowRootMode::Closed,
false, false,
SlotAssignmentMode::Manual, SlotAssignmentMode::Manual,
can_gc,
) )
.unwrap(); .unwrap();
let document = self.owner_document(); let document = self.owner_document();

View file

@ -86,6 +86,7 @@ impl HTMLMeterElement {
ShadowRootMode::Closed, ShadowRootMode::Closed,
false, false,
SlotAssignmentMode::Manual, SlotAssignmentMode::Manual,
can_gc,
) )
.expect("Attaching UA shadow root failed"); .expect("Attaching UA shadow root failed");

View file

@ -344,8 +344,8 @@ fn finish_fetching_a_classic_script(
let document = elem.owner_document(); let document = elem.owner_document();
match script_kind { match script_kind {
ExternalScriptKind::Asap => document.asap_script_loaded(elem, load), ExternalScriptKind::Asap => document.asap_script_loaded(elem, load, can_gc),
ExternalScriptKind::AsapInOrder => document.asap_in_order_script_loaded(elem, load), ExternalScriptKind::AsapInOrder => document.asap_in_order_script_loaded(elem, load, can_gc),
ExternalScriptKind::Deferred => document.deferred_script_loaded(elem, load), ExternalScriptKind::Deferred => document.deferred_script_loaded(elem, load),
ExternalScriptKind::ParsingBlocking => { ExternalScriptKind::ParsingBlocking => {
document.pending_parsing_blocking_script_loaded(elem, load, can_gc) document.pending_parsing_blocking_script_loaded(elem, load, can_gc)

View file

@ -151,7 +151,8 @@ macro_rules! make_labels_getter(
use $crate::dom::nodelist::NodeList; use $crate::dom::nodelist::NodeList;
self.$memo.or_init(|| NodeList::new_labels_list( self.$memo.or_init(|| NodeList::new_labels_list(
self.upcast::<Node>().owner_doc().window(), self.upcast::<Node>().owner_doc().window(),
self.upcast::<HTMLElement>() self.upcast::<HTMLElement>(),
CanGc::note()
) )
) )
} }

View file

@ -81,9 +81,10 @@ impl MutationRecord {
can_gc: CanGc, can_gc: CanGc,
) -> DomRoot<MutationRecord> { ) -> DomRoot<MutationRecord> {
let window = target.owner_window(); let window = target.owner_window();
let added_nodes = added_nodes.map(|list| NodeList::new_simple_list_slice(&window, list)); let added_nodes =
added_nodes.map(|list| NodeList::new_simple_list_slice(&window, list, can_gc));
let removed_nodes = let removed_nodes =
removed_nodes.map(|list| NodeList::new_simple_list_slice(&window, list)); removed_nodes.map(|list| NodeList::new_simple_list_slice(&window, list, can_gc));
reflect_dom_object( reflect_dom_object(
Box::new(MutationRecord::new_inherited( Box::new(MutationRecord::new_inherited(
@ -158,13 +159,13 @@ impl MutationRecordMethods<crate::DomTypeHolder> for MutationRecord {
// https://dom.spec.whatwg.org/#dom-mutationrecord-addednodes // https://dom.spec.whatwg.org/#dom-mutationrecord-addednodes
fn AddedNodes(&self) -> DomRoot<NodeList> { fn AddedNodes(&self) -> DomRoot<NodeList> {
self.added_nodes self.added_nodes
.or_init(|| NodeList::empty(&self.target.owner_window())) .or_init(|| NodeList::empty(&self.target.owner_window(), CanGc::note()))
} }
// https://dom.spec.whatwg.org/#dom-mutationrecord-removednodes // https://dom.spec.whatwg.org/#dom-mutationrecord-removednodes
fn RemovedNodes(&self) -> DomRoot<NodeList> { fn RemovedNodes(&self) -> DomRoot<NodeList> {
self.removed_nodes self.removed_nodes
.or_init(|| NodeList::empty(&self.target.owner_window())) .or_init(|| NodeList::empty(&self.target.owner_window(), CanGc::note()))
} }
// https://dom.spec.whatwg.org/#dom-mutationrecord-previoussibling // https://dom.spec.whatwg.org/#dom-mutationrecord-previoussibling

View file

@ -1078,7 +1078,7 @@ impl Node {
pub(crate) fn query_selector_all(&self, selectors: DOMString) -> Fallible<DomRoot<NodeList>> { pub(crate) fn query_selector_all(&self, selectors: DOMString) -> Fallible<DomRoot<NodeList>> {
let window = self.owner_window(); let window = self.owner_window();
let iter = self.query_selector_iter(selectors)?; let iter = self.query_selector_iter(selectors)?;
Ok(NodeList::new_simple_list(&window, iter)) Ok(NodeList::new_simple_list(&window, iter, CanGc::note()))
} }
pub(crate) fn ancestors(&self) -> impl Iterator<Item = DomRoot<Node>> { pub(crate) fn ancestors(&self) -> impl Iterator<Item = DomRoot<Node>> {
@ -2650,7 +2650,8 @@ impl Node {
IsUserAgentWidget::No, IsUserAgentWidget::No,
shadow_root.Mode(), shadow_root.Mode(),
true, true,
shadow_root.SlotAssignment() shadow_root.SlotAssignment(),
can_gc
) )
.expect("placement of attached shadow root must be valid, as this is a copy of an existing one"); .expect("placement of attached shadow root must be valid, as this is a copy of an existing one");
@ -2925,7 +2926,7 @@ impl NodeMethods<crate::DomTypeHolder> for Node {
self.ensure_rare_data().child_list.or_init(|| { self.ensure_rare_data().child_list.or_init(|| {
let doc = self.owner_doc(); let doc = self.owner_doc();
let window = doc.window(); let window = doc.window();
NodeList::new_child_list(window, self) NodeList::new_child_list(window, self, CanGc::note())
}) })
} }

View file

@ -63,12 +63,13 @@ impl NodeIterator {
root_node: &Node, root_node: &Node,
what_to_show: u32, what_to_show: u32,
node_filter: Option<Rc<NodeFilter>>, node_filter: Option<Rc<NodeFilter>>,
can_gc: CanGc,
) -> DomRoot<NodeIterator> { ) -> DomRoot<NodeIterator> {
let filter = match node_filter { let filter = match node_filter {
None => Filter::None, None => Filter::None,
Some(jsfilter) => Filter::Callback(jsfilter), Some(jsfilter) => Filter::Callback(jsfilter),
}; };
NodeIterator::new_with_filter(document, root_node, what_to_show, filter, CanGc::note()) NodeIterator::new_with_filter(document, root_node, what_to_show, filter, can_gc)
} }
} }

View file

@ -54,38 +54,46 @@ impl NodeList {
reflect_dom_object(Box::new(NodeList::new_inherited(list_type)), window, can_gc) reflect_dom_object(Box::new(NodeList::new_inherited(list_type)), window, can_gc)
} }
pub(crate) fn new_simple_list<T>(window: &Window, iter: T) -> DomRoot<NodeList> pub(crate) fn new_simple_list<T>(window: &Window, iter: T, can_gc: CanGc) -> DomRoot<NodeList>
where where
T: Iterator<Item = DomRoot<Node>>, T: Iterator<Item = DomRoot<Node>>,
{ {
NodeList::new( NodeList::new(
window, window,
NodeListType::Simple(iter.map(|r| Dom::from_ref(&*r)).collect()), NodeListType::Simple(iter.map(|r| Dom::from_ref(&*r)).collect()),
CanGc::note(), can_gc,
) )
} }
pub(crate) fn new_simple_list_slice(window: &Window, slice: &[&Node]) -> DomRoot<NodeList> { pub(crate) fn new_simple_list_slice(
window: &Window,
slice: &[&Node],
can_gc: CanGc,
) -> DomRoot<NodeList> {
NodeList::new( NodeList::new(
window, window,
NodeListType::Simple(slice.iter().map(|r| Dom::from_ref(*r)).collect()), NodeListType::Simple(slice.iter().map(|r| Dom::from_ref(*r)).collect()),
CanGc::note(), can_gc,
) )
} }
pub(crate) fn new_child_list(window: &Window, node: &Node) -> DomRoot<NodeList> { pub(crate) fn new_child_list(window: &Window, node: &Node, can_gc: CanGc) -> DomRoot<NodeList> {
NodeList::new( NodeList::new(
window, window,
NodeListType::Children(ChildrenList::new(node)), NodeListType::Children(ChildrenList::new(node)),
CanGc::note(), can_gc,
) )
} }
pub(crate) fn new_labels_list(window: &Window, element: &HTMLElement) -> DomRoot<NodeList> { pub(crate) fn new_labels_list(
window: &Window,
element: &HTMLElement,
can_gc: CanGc,
) -> DomRoot<NodeList> {
NodeList::new( NodeList::new(
window, window,
NodeListType::Labels(LabelsList::new(element)), NodeListType::Labels(LabelsList::new(element)),
CanGc::note(), can_gc,
) )
} }
@ -93,16 +101,17 @@ impl NodeList {
window: &Window, window: &Window,
document: &Document, document: &Document,
name: DOMString, name: DOMString,
can_gc: CanGc,
) -> DomRoot<NodeList> { ) -> DomRoot<NodeList> {
NodeList::new( NodeList::new(
window, window,
NodeListType::ElementsByName(ElementsByNameList::new(document, name)), NodeListType::ElementsByName(ElementsByNameList::new(document, name)),
CanGc::note(), can_gc,
) )
} }
pub(crate) fn empty(window: &Window) -> DomRoot<NodeList> { pub(crate) fn empty(window: &Window, can_gc: CanGc) -> DomRoot<NodeList> {
NodeList::new(window, NodeListType::Simple(vec![]), CanGc::note()) NodeList::new(window, NodeListType::Simple(vec![]), can_gc)
} }
} }

View file

@ -272,7 +272,7 @@ impl NotificationMethods<crate::DomTypeHolder> for Notification {
// TODO: Step 3: Run these steps in parallel: // TODO: Step 3: Run these steps in parallel:
// Step 3.1: Let permissionState be the result of requesting permission to use "notifications". // Step 3.1: Let permissionState be the result of requesting permission to use "notifications".
let notification_permission = request_notification_permission(global); let notification_permission = request_notification_permission(global, can_gc);
// Step 3.2: Queue a global task on the DOM manipulation task source given global to run these steps: // Step 3.2: Queue a global task on the DOM manipulation task source given global to run these steps:
let trusted_promise = TrustedPromise::new(promise.clone()); let trusted_promise = TrustedPromise::new(promise.clone());
@ -542,13 +542,13 @@ fn get_notifications_permission_state(global: &GlobalScope) -> NotificationPermi
} }
} }
fn request_notification_permission(global: &GlobalScope) -> NotificationPermission { fn request_notification_permission(global: &GlobalScope, can_gc: CanGc) -> NotificationPermission {
let cx = GlobalScope::get_cx(); let cx = GlobalScope::get_cx();
let promise = &Promise::new(global, CanGc::note()); let promise = &Promise::new(global, can_gc);
let descriptor = PermissionDescriptor { let descriptor = PermissionDescriptor {
name: PermissionName::Notifications, name: PermissionName::Notifications,
}; };
let status = PermissionStatus::new(global, &descriptor, CanGc::note()); let status = PermissionStatus::new(global, &descriptor, can_gc);
// The implementation of `request_notification_permission` seemed to be synchronous // The implementation of `request_notification_permission` seemed to be synchronous
Permissions::permission_request(cx, promise, &descriptor, &status); Permissions::permission_request(cx, promise, &descriptor, &status);

View file

@ -194,7 +194,7 @@ impl OffscreenCanvasMethods<crate::DomTypeHolder> for OffscreenCanvas {
} }
if let Some(canvas) = &self.placeholder { if let Some(canvas) = &self.placeholder {
canvas.set_natural_width(value as _); canvas.set_natural_width(value as _, CanGc::note());
} }
} }
@ -216,7 +216,7 @@ impl OffscreenCanvasMethods<crate::DomTypeHolder> for OffscreenCanvas {
} }
if let Some(canvas) = &self.placeholder { if let Some(canvas) = &self.placeholder {
canvas.set_natural_height(value as _); canvas.set_natural_height(value as _, CanGc::note());
} }
} }
} }

View file

@ -179,7 +179,7 @@ impl OffscreenCanvasRenderingContext2DMethods<crate::DomTypeHolder>
y1: Finite<f64>, y1: Finite<f64>,
) -> DomRoot<CanvasGradient> { ) -> DomRoot<CanvasGradient> {
self.canvas_state self.canvas_state
.create_linear_gradient(&self.global(), x0, y0, x1, y1) .create_linear_gradient(&self.global(), x0, y0, x1, y1, CanGc::note())
} }
// https://html.spec.whatwg.org/multipage/#dom-context-2d-createradialgradient // https://html.spec.whatwg.org/multipage/#dom-context-2d-createradialgradient
@ -192,8 +192,16 @@ impl OffscreenCanvasRenderingContext2DMethods<crate::DomTypeHolder>
y1: Finite<f64>, y1: Finite<f64>,
r1: Finite<f64>, r1: Finite<f64>,
) -> Fallible<DomRoot<CanvasGradient>> { ) -> Fallible<DomRoot<CanvasGradient>> {
self.canvas_state self.canvas_state.create_radial_gradient(
.create_radial_gradient(&self.global(), x0, y0, r0, x1, y1, r1) &self.global(),
x0,
y0,
r0,
x1,
y1,
r1,
CanGc::note(),
)
} }
// https://html.spec.whatwg.org/multipage/#dom-context-2d-createpattern // https://html.spec.whatwg.org/multipage/#dom-context-2d-createpattern
@ -203,7 +211,7 @@ impl OffscreenCanvasRenderingContext2DMethods<crate::DomTypeHolder>
repetition: DOMString, repetition: DOMString,
) -> Fallible<Option<DomRoot<CanvasPattern>>> { ) -> Fallible<Option<DomRoot<CanvasPattern>>> {
self.canvas_state self.canvas_state
.create_pattern(&self.global(), image, repetition) .create_pattern(&self.global(), image, repetition, CanGc::note())
} }
// https://html.spec.whatwg.org/multipage/#dom-context-2d-save // https://html.spec.whatwg.org/multipage/#dom-context-2d-save

View file

@ -221,10 +221,12 @@ impl PaintWorkletGlobalScope {
device_pixel_ratio, device_pixel_ratio,
properties, properties,
arguments, arguments,
CanGc::note(),
) )
} }
/// <https://drafts.css-houdini.org/css-paint-api/#invoke-a-paint-callback> /// <https://drafts.css-houdini.org/css-paint-api/#invoke-a-paint-callback>
#[allow(clippy::too_many_arguments)]
#[allow(unsafe_code)] #[allow(unsafe_code)]
fn invoke_a_paint_callback( fn invoke_a_paint_callback(
&self, &self,
@ -234,6 +236,7 @@ impl PaintWorkletGlobalScope {
device_pixel_ratio: Scale<f32, CSSPixel, DevicePixel>, device_pixel_ratio: Scale<f32, CSSPixel, DevicePixel>,
properties: &StylePropertyMapReadOnly, properties: &StylePropertyMapReadOnly,
arguments: &[String], arguments: &[String],
can_gc: CanGc,
) -> DrawAPaintImageResult { ) -> DrawAPaintImageResult {
debug!( debug!(
"Invoking a paint callback {}({},{}) at {:?}.", "Invoking a paint callback {}({},{}) at {:?}.",
@ -308,14 +311,14 @@ impl PaintWorkletGlobalScope {
rendering_context.set_bitmap_dimensions(size_in_px, device_pixel_ratio); rendering_context.set_bitmap_dimensions(size_in_px, device_pixel_ratio);
// Step 9 // Step 9
let paint_size = PaintSize::new(self, size_in_px, CanGc::note()); let paint_size = PaintSize::new(self, size_in_px, can_gc);
// TODO: Step 10 // TODO: Step 10
// Steps 11-12 // Steps 11-12
debug!("Invoking paint function {}.", name); debug!("Invoking paint function {}.", name);
rooted_vec!(let mut arguments_values); rooted_vec!(let mut arguments_values);
for argument in arguments { for argument in arguments {
let style_value = CSSStyleValue::new(self.upcast(), argument.clone(), CanGc::note()); let style_value = CSSStyleValue::new(self.upcast(), argument.clone(), can_gc);
arguments_values.push(ObjectValue(style_value.reflector().get_jsobject().get())); arguments_values.push(ObjectValue(style_value.reflector().get_jsobject().get()));
} }
let arguments_value_array = HandleValueArray::from(&arguments_values); let arguments_value_array = HandleValueArray::from(&arguments_values);

View file

@ -63,6 +63,7 @@ impl PannerNode {
window: &Window, window: &Window,
context: &BaseAudioContext, context: &BaseAudioContext,
options: &PannerOptions, options: &PannerOptions,
can_gc: CanGc,
) -> Fallible<PannerNode> { ) -> Fallible<PannerNode> {
let node_options = options.parent.unwrap_or( let node_options = options.parent.unwrap_or(
2, 2,
@ -106,7 +107,7 @@ impl PannerNode {
options.position_x, // default value options.position_x, // default value
f32::MIN, // min value f32::MIN, // min value
f32::MAX, // max value f32::MAX, // max value
CanGc::note(), can_gc,
); );
let position_y = AudioParam::new( let position_y = AudioParam::new(
window, window,
@ -118,7 +119,7 @@ impl PannerNode {
options.position_y, // default value options.position_y, // default value
f32::MIN, // min value f32::MIN, // min value
f32::MAX, // max value f32::MAX, // max value
CanGc::note(), can_gc,
); );
let position_z = AudioParam::new( let position_z = AudioParam::new(
window, window,
@ -130,7 +131,7 @@ impl PannerNode {
options.position_z, // default value options.position_z, // default value
f32::MIN, // min value f32::MIN, // min value
f32::MAX, // max value f32::MAX, // max value
CanGc::note(), can_gc,
); );
let orientation_x = AudioParam::new( let orientation_x = AudioParam::new(
window, window,
@ -142,7 +143,7 @@ impl PannerNode {
options.orientation_x, // default value options.orientation_x, // default value
f32::MIN, // min value f32::MIN, // min value
f32::MAX, // max value f32::MAX, // max value
CanGc::note(), can_gc,
); );
let orientation_y = AudioParam::new( let orientation_y = AudioParam::new(
window, window,
@ -154,7 +155,7 @@ impl PannerNode {
options.orientation_y, // default value options.orientation_y, // default value
f32::MIN, // min value f32::MIN, // min value
f32::MAX, // max value f32::MAX, // max value
CanGc::note(), can_gc,
); );
let orientation_z = AudioParam::new( let orientation_z = AudioParam::new(
window, window,
@ -166,7 +167,7 @@ impl PannerNode {
options.orientation_z, // default value options.orientation_z, // default value
f32::MIN, // min value f32::MIN, // min value
f32::MAX, // max value f32::MAX, // max value
CanGc::note(), can_gc,
); );
Ok(PannerNode { Ok(PannerNode {
node, node,
@ -204,7 +205,7 @@ impl PannerNode {
options: &PannerOptions, options: &PannerOptions,
can_gc: CanGc, can_gc: CanGc,
) -> Fallible<DomRoot<PannerNode>> { ) -> Fallible<DomRoot<PannerNode>> {
let node = PannerNode::new_inherited(window, context, options)?; let node = PannerNode::new_inherited(window, context, options, can_gc)?;
Ok(reflect_dom_object_with_proto( Ok(reflect_dom_object_with_proto(
Box::new(node), Box::new(node),
window, window,

View file

@ -358,7 +358,7 @@ impl Performance {
// Step 7.3. // Step 7.3.
for o in observers.iter() { for o in observers.iter() {
o.notify(); o.notify(CanGc::note());
} }
} }

View file

@ -93,13 +93,13 @@ impl PerformanceObserver {
/// Trigger performance observer callback with the list of performance entries /// Trigger performance observer callback with the list of performance entries
/// buffered since the last callback call. /// buffered since the last callback call.
pub(crate) fn notify(&self) { pub(crate) fn notify(&self, can_gc: CanGc) {
if self.entries.borrow().is_empty() { if self.entries.borrow().is_empty() {
return; return;
} }
let entry_list = PerformanceEntryList::new(self.entries.borrow_mut().drain(..).collect()); let entry_list = PerformanceEntryList::new(self.entries.borrow_mut().drain(..).collect());
let observer_entry_list = let observer_entry_list =
PerformanceObserverEntryList::new(&self.global(), entry_list, CanGc::note()); PerformanceObserverEntryList::new(&self.global(), entry_list, can_gc);
// using self both as thisArg and as the second formal argument // using self both as thisArg and as the second formal argument
let _ = self let _ = self
.callback .callback

View file

@ -49,6 +49,7 @@ impl RadioNodeList {
window: &Window, window: &Window,
form: &HTMLFormElement, form: &HTMLFormElement,
name: &Atom, name: &Atom,
can_gc: CanGc,
) -> DomRoot<RadioNodeList> { ) -> DomRoot<RadioNodeList> {
RadioNodeList::new( RadioNodeList::new(
window, window,
@ -57,7 +58,7 @@ impl RadioNodeList {
RadioListMode::ControlsExceptImageInputs, RadioListMode::ControlsExceptImageInputs,
name.clone(), name.clone(),
)), )),
CanGc::note(), can_gc,
) )
} }
@ -65,11 +66,12 @@ impl RadioNodeList {
window: &Window, window: &Window,
form: &HTMLFormElement, form: &HTMLFormElement,
name: &Atom, name: &Atom,
can_gc: CanGc,
) -> DomRoot<RadioNodeList> { ) -> DomRoot<RadioNodeList> {
RadioNodeList::new( RadioNodeList::new(
window, window,
NodeListType::Radio(RadioList::new(form, RadioListMode::Images, name.clone())), NodeListType::Radio(RadioList::new(form, RadioListMode::Images, name.clone())),
CanGc::note(), can_gc,
) )
} }
} }

View file

@ -715,7 +715,7 @@ impl ReadableStreamDefaultController {
// First, throw the exception. // First, throw the exception.
// Note: this must be done manually here, // Note: this must be done manually here,
// because `enqueue_value_with_size` does not call into JS. // because `enqueue_value_with_size` does not call into JS.
throw_dom_exception(cx, &self.global(), error); throw_dom_exception(cx, &self.global(), error, CanGc::note());
// Then, get a handle to the JS val for the exception, // Then, get a handle to the JS val for the exception,
// and use that to error the stream. // and use that to error the stream.

View file

@ -28,12 +28,17 @@ pub(crate) struct RTCError {
} }
impl RTCError { impl RTCError {
fn new_inherited(global: &GlobalScope, init: &RTCErrorInit, message: DOMString) -> RTCError { fn new_inherited(
global: &GlobalScope,
init: &RTCErrorInit,
message: DOMString,
can_gc: CanGc,
) -> RTCError {
RTCError { RTCError {
exception: Dom::from_ref(&*DOMException::new( exception: Dom::from_ref(&*DOMException::new(
global, global,
DOMErrorName::from(&message).unwrap(), DOMErrorName::from(&message).unwrap(),
CanGc::note(), can_gc,
)), )),
error_detail: init.errorDetail, error_detail: init.errorDetail,
sdp_line_number: init.sdpLineNumber, sdp_line_number: init.sdpLineNumber,
@ -61,7 +66,7 @@ impl RTCError {
can_gc: CanGc, can_gc: CanGc,
) -> DomRoot<RTCError> { ) -> DomRoot<RTCError> {
reflect_dom_object_with_proto( reflect_dom_object_with_proto(
Box::new(RTCError::new_inherited(global, init, message)), Box::new(RTCError::new_inherited(global, init, message, can_gc)),
global, global,
proto, proto,
can_gc, can_gc,

View file

@ -46,7 +46,7 @@ impl ServiceWorkerContainer {
#[cfg_attr(crown, allow(crown::unrooted_must_root))] #[cfg_attr(crown, allow(crown::unrooted_must_root))]
pub(crate) fn new(global: &GlobalScope, can_gc: CanGc) -> DomRoot<ServiceWorkerContainer> { pub(crate) fn new(global: &GlobalScope, can_gc: CanGc) -> DomRoot<ServiceWorkerContainer> {
let client = Client::new(global.as_window(), CanGc::note()); let client = Client::new(global.as_window(), can_gc);
let container = ServiceWorkerContainer::new_inherited(&client); let container = ServiceWorkerContainer::new_inherited(&client);
reflect_dom_object(Box::new(container), global, can_gc) reflect_dom_object(Box::new(container), global, can_gc)
} }
@ -244,6 +244,7 @@ impl RegisterJobResultHandler {
installing_worker, installing_worker,
waiting_worker, waiting_worker,
active_worker, active_worker,
CanGc::note()
); );
// Step 1.4 // Step 1.4

View file

@ -12,6 +12,7 @@ use crate::dom::bindings::str::DOMString;
use crate::dom::cssstylesheet::CSSStyleSheet; use crate::dom::cssstylesheet::CSSStyleSheet;
use crate::dom::element::Element; use crate::dom::element::Element;
use crate::dom::medialist::MediaList; use crate::dom::medialist::MediaList;
use crate::script_runtime::CanGc;
#[dom_struct] #[dom_struct]
pub(crate) struct StyleSheet { pub(crate) struct StyleSheet {
@ -55,7 +56,9 @@ impl StyleSheetMethods<crate::DomTypeHolder> for StyleSheet {
// https://drafts.csswg.org/cssom/#dom-stylesheet-media // https://drafts.csswg.org/cssom/#dom-stylesheet-media
fn Media(&self) -> DomRoot<MediaList> { fn Media(&self) -> DomRoot<MediaList> {
self.downcast::<CSSStyleSheet>().unwrap().medialist() self.downcast::<CSSStyleSheet>()
.unwrap()
.medialist(CanGc::note())
} }
// https://drafts.csswg.org/cssom/#dom-stylesheet-title // https://drafts.csswg.org/cssom/#dom-stylesheet-title

View file

@ -81,14 +81,10 @@ impl TouchEvent {
alt_key: bool, alt_key: bool,
shift_key: bool, shift_key: bool,
meta_key: bool, meta_key: bool,
can_gc: CanGc,
) -> DomRoot<TouchEvent> { ) -> DomRoot<TouchEvent> {
let ev = TouchEvent::new_uninitialized( let ev =
window, TouchEvent::new_uninitialized(window, touches, changed_touches, target_touches, can_gc);
touches,
changed_touches,
target_touches,
CanGc::note(),
);
ev.upcast::<UIEvent>().InitUIEvent( ev.upcast::<UIEvent>().InitUIEvent(
type_, type_,
bool::from(can_bubble), bool::from(can_bubble),

View file

@ -50,13 +50,16 @@ impl WebGLBuffer {
} }
} }
pub(crate) fn maybe_new(context: &WebGLRenderingContext) -> Option<DomRoot<Self>> { pub(crate) fn maybe_new(
context: &WebGLRenderingContext,
can_gc: CanGc,
) -> Option<DomRoot<Self>> {
let (sender, receiver) = webgl_channel().unwrap(); let (sender, receiver) = webgl_channel().unwrap();
context.send_command(WebGLCommand::CreateBuffer(sender)); context.send_command(WebGLCommand::CreateBuffer(sender));
receiver receiver
.recv() .recv()
.unwrap() .unwrap()
.map(|id| WebGLBuffer::new(context, id, CanGc::note())) .map(|id| WebGLBuffer::new(context, id, can_gc))
} }
pub(crate) fn new( pub(crate) fn new(

View file

@ -139,11 +139,14 @@ impl WebGLFramebuffer {
} }
} }
pub(crate) fn maybe_new(context: &WebGLRenderingContext) -> Option<DomRoot<Self>> { pub(crate) fn maybe_new(
context: &WebGLRenderingContext,
can_gc: CanGc,
) -> Option<DomRoot<Self>> {
let (sender, receiver) = webgl_channel().unwrap(); let (sender, receiver) = webgl_channel().unwrap();
context.send_command(WebGLCommand::CreateFramebuffer(sender)); context.send_command(WebGLCommand::CreateFramebuffer(sender));
let id = receiver.recv().unwrap()?; let id = receiver.recv().unwrap()?;
let framebuffer = WebGLFramebuffer::new(context, id, CanGc::note()); let framebuffer = WebGLFramebuffer::new(context, id, can_gc);
Some(framebuffer) Some(framebuffer)
} }
@ -154,8 +157,9 @@ impl WebGLFramebuffer {
session: &XRSession, session: &XRSession,
context: &WebGLRenderingContext, context: &WebGLRenderingContext,
size: Size2D<i32, Viewport>, size: Size2D<i32, Viewport>,
can_gc: CanGc,
) -> Option<DomRoot<Self>> { ) -> Option<DomRoot<Self>> {
let framebuffer = Self::maybe_new(context)?; let framebuffer = Self::maybe_new(context, can_gc)?;
framebuffer.size.set(Some((size.width, size.height))); framebuffer.size.set(Some((size.width, size.height)));
framebuffer.status.set(constants::FRAMEBUFFER_COMPLETE); framebuffer.status.set(constants::FRAMEBUFFER_COMPLETE);
framebuffer.xr_session.set(Some(session)); framebuffer.xr_session.set(Some(session));

View file

@ -69,13 +69,16 @@ impl WebGLProgram {
} }
} }
pub(crate) fn maybe_new(context: &WebGLRenderingContext) -> Option<DomRoot<Self>> { pub(crate) fn maybe_new(
context: &WebGLRenderingContext,
can_gc: CanGc,
) -> Option<DomRoot<Self>> {
let (sender, receiver) = webgl_channel().unwrap(); let (sender, receiver) = webgl_channel().unwrap();
context.send_command(WebGLCommand::CreateProgram(sender)); context.send_command(WebGLCommand::CreateProgram(sender));
receiver receiver
.recv() .recv()
.unwrap() .unwrap()
.map(|id| WebGLProgram::new(context, id, CanGc::note())) .map(|id| WebGLProgram::new(context, id, can_gc))
} }
pub(crate) fn new( pub(crate) fn new(
@ -320,7 +323,11 @@ impl WebGLProgram {
Ok(()) Ok(())
} }
pub(crate) fn get_active_uniform(&self, index: u32) -> WebGLResult<DomRoot<WebGLActiveInfo>> { pub(crate) fn get_active_uniform(
&self,
index: u32,
can_gc: CanGc,
) -> WebGLResult<DomRoot<WebGLActiveInfo>> {
if self.is_deleted() { if self.is_deleted() {
return Err(WebGLError::InvalidValue); return Err(WebGLError::InvalidValue);
} }
@ -333,12 +340,16 @@ impl WebGLProgram {
data.size.unwrap_or(1), data.size.unwrap_or(1),
data.type_, data.type_,
data.name().into(), data.name().into(),
CanGc::note(), can_gc,
)) ))
} }
/// glGetActiveAttrib /// glGetActiveAttrib
pub(crate) fn get_active_attrib(&self, index: u32) -> WebGLResult<DomRoot<WebGLActiveInfo>> { pub(crate) fn get_active_attrib(
&self,
index: u32,
can_gc: CanGc,
) -> WebGLResult<DomRoot<WebGLActiveInfo>> {
if self.is_deleted() { if self.is_deleted() {
return Err(WebGLError::InvalidValue); return Err(WebGLError::InvalidValue);
} }
@ -351,7 +362,7 @@ impl WebGLProgram {
data.size, data.size,
data.type_, data.type_,
data.name.clone().into(), data.name.clone().into(),
CanGc::note(), can_gc,
)) ))
} }
@ -406,6 +417,7 @@ impl WebGLProgram {
pub(crate) fn get_uniform_location( pub(crate) fn get_uniform_location(
&self, &self,
name: DOMString, name: DOMString,
can_gc: CanGc,
) -> WebGLResult<Option<DomRoot<WebGLUniformLocation>>> { ) -> WebGLResult<Option<DomRoot<WebGLUniformLocation>>> {
if !self.is_linked() || self.is_deleted() { if !self.is_linked() || self.is_deleted() {
return Err(WebGLError::InvalidOperation); return Err(WebGLError::InvalidOperation);
@ -458,7 +470,7 @@ impl WebGLProgram {
self.link_generation.get(), self.link_generation.get(),
size, size,
type_, type_,
CanGc::note(), can_gc,
))) )))
} }

View file

@ -2943,12 +2943,12 @@ impl WebGLRenderingContextMethods<crate::DomTypeHolder> for WebGLRenderingContex
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.5 // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.5
fn CreateBuffer(&self) -> Option<DomRoot<WebGLBuffer>> { fn CreateBuffer(&self) -> Option<DomRoot<WebGLBuffer>> {
WebGLBuffer::maybe_new(self) WebGLBuffer::maybe_new(self, CanGc::note())
} }
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.6 // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.6
fn CreateFramebuffer(&self) -> Option<DomRoot<WebGLFramebuffer>> { fn CreateFramebuffer(&self) -> Option<DomRoot<WebGLFramebuffer>> {
WebGLFramebuffer::maybe_new(self) WebGLFramebuffer::maybe_new(self, CanGc::note())
} }
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.7 // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.7
@ -2963,7 +2963,7 @@ impl WebGLRenderingContextMethods<crate::DomTypeHolder> for WebGLRenderingContex
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9 // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9
fn CreateProgram(&self) -> Option<DomRoot<WebGLProgram>> { fn CreateProgram(&self) -> Option<DomRoot<WebGLProgram>> {
WebGLProgram::maybe_new(self) WebGLProgram::maybe_new(self, CanGc::note())
} }
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9 // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9
@ -3137,7 +3137,7 @@ impl WebGLRenderingContextMethods<crate::DomTypeHolder> for WebGLRenderingContex
index: u32, index: u32,
) -> Option<DomRoot<WebGLActiveInfo>> { ) -> Option<DomRoot<WebGLActiveInfo>> {
handle_potential_webgl_error!(self, self.validate_ownership(program), return None); handle_potential_webgl_error!(self, self.validate_ownership(program), return None);
match program.get_active_uniform(index) { match program.get_active_uniform(index, CanGc::note()) {
Ok(ret) => Some(ret), Ok(ret) => Some(ret),
Err(e) => { Err(e) => {
self.webgl_error(e); self.webgl_error(e);
@ -3153,7 +3153,11 @@ impl WebGLRenderingContextMethods<crate::DomTypeHolder> for WebGLRenderingContex
index: u32, index: u32,
) -> Option<DomRoot<WebGLActiveInfo>> { ) -> Option<DomRoot<WebGLActiveInfo>> {
handle_potential_webgl_error!(self, self.validate_ownership(program), return None); handle_potential_webgl_error!(self, self.validate_ownership(program), return None);
handle_potential_webgl_error!(self, program.get_active_attrib(index).map(Some), None) handle_potential_webgl_error!(
self,
program.get_active_attrib(index, CanGc::note()).map(Some),
None
)
} }
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
@ -3472,7 +3476,11 @@ impl WebGLRenderingContextMethods<crate::DomTypeHolder> for WebGLRenderingContex
name: DOMString, name: DOMString,
) -> Option<DomRoot<WebGLUniformLocation>> { ) -> Option<DomRoot<WebGLUniformLocation>> {
handle_potential_webgl_error!(self, self.validate_ownership(program), return None); handle_potential_webgl_error!(self, self.validate_ownership(program), return None);
handle_potential_webgl_error!(self, program.get_uniform_location(name), None) handle_potential_webgl_error!(
self,
program.get_uniform_location(name, CanGc::note()),
None
)
} }
#[allow(unsafe_code)] #[allow(unsafe_code)]

View file

@ -245,7 +245,7 @@ impl AsyncWGPUListener for GPUAdapter {
String::new(), String::new(),
can_gc, can_gc,
); );
device.lose(GPUDeviceLostReason::Unknown, e.to_string()); device.lose(GPUDeviceLostReason::Unknown, e.to_string(), can_gc);
promise.resolve_native(&device); promise.resolve_native(&device);
}, },
WebGPUResponse::None => unreachable!("Failed to get a response for RequestDevice"), WebGPUResponse::None => unreachable!("Failed to get a response for RequestDevice"),

View file

@ -81,6 +81,7 @@ impl GPUBindGroup {
pub(crate) fn create( pub(crate) fn create(
device: &GPUDevice, device: &GPUDevice,
descriptor: &GPUBindGroupDescriptor, descriptor: &GPUBindGroupDescriptor,
can_gc: CanGc,
) -> DomRoot<GPUBindGroup> { ) -> DomRoot<GPUBindGroup> {
let entries = descriptor let entries = descriptor
.entries .entries
@ -114,7 +115,7 @@ impl GPUBindGroup {
device.id(), device.id(),
&descriptor.layout, &descriptor.layout,
descriptor.parent.label.clone(), descriptor.parent.label.clone(),
CanGc::note(), can_gc,
) )
} }
} }

View file

@ -75,6 +75,7 @@ impl GPUBindGroupLayout {
pub(crate) fn create( pub(crate) fn create(
device: &GPUDevice, device: &GPUDevice,
descriptor: &GPUBindGroupLayoutDescriptor, descriptor: &GPUBindGroupLayoutDescriptor,
can_gc: CanGc,
) -> Fallible<DomRoot<GPUBindGroupLayout>> { ) -> Fallible<DomRoot<GPUBindGroupLayout>> {
let entries = descriptor let entries = descriptor
.entries .entries
@ -111,7 +112,7 @@ impl GPUBindGroupLayout {
device.channel().clone(), device.channel().clone(),
bgl, bgl,
descriptor.parent.label.clone(), descriptor.parent.label.clone(),
CanGc::note(), can_gc,
)) ))
} }
} }

View file

@ -137,6 +137,7 @@ impl GPUBuffer {
pub(crate) fn create( pub(crate) fn create(
device: &GPUDevice, device: &GPUDevice,
descriptor: &GPUBufferDescriptor, descriptor: &GPUBufferDescriptor,
can_gc: CanGc,
) -> Fallible<DomRoot<GPUBuffer>> { ) -> Fallible<DomRoot<GPUBuffer>> {
let desc = wgt::BufferDescriptor { let desc = wgt::BufferDescriptor {
label: (&descriptor.parent).convert(), label: (&descriptor.parent).convert(),
@ -175,7 +176,7 @@ impl GPUBuffer {
descriptor.usage, descriptor.usage,
mapping, mapping,
descriptor.parent.label.clone(), descriptor.parent.label.clone(),
CanGc::note(), can_gc,
)) ))
} }
} }

View file

@ -88,6 +88,7 @@ impl GPUCommandEncoder {
pub(crate) fn create( pub(crate) fn create(
device: &GPUDevice, device: &GPUDevice,
descriptor: &GPUCommandEncoderDescriptor, descriptor: &GPUCommandEncoderDescriptor,
can_gc: CanGc,
) -> DomRoot<GPUCommandEncoder> { ) -> DomRoot<GPUCommandEncoder> {
let command_encoder_id = device.global().wgpu_id_hub().create_command_encoder_id(); let command_encoder_id = device.global().wgpu_id_hub().create_command_encoder_id();
device device
@ -110,7 +111,7 @@ impl GPUCommandEncoder {
device, device,
encoder, encoder,
descriptor.parent.label.clone(), descriptor.parent.label.clone(),
CanGc::note(), can_gc,
) )
} }
} }

View file

@ -46,7 +46,7 @@ impl GPUCompilationInfo {
Self::new( Self::new(
global, global,
if let Some(error) = error { if let Some(error) = error {
vec![GPUCompilationMessage::from(global, error)] vec![GPUCompilationMessage::from(global, error, can_gc)]
} else { } else {
Vec::new() Vec::new()
}, },

View file

@ -68,7 +68,11 @@ impl GPUCompilationMessage {
) )
} }
pub(crate) fn from(global: &GlobalScope, info: ShaderCompilationInfo) -> DomRoot<Self> { pub(crate) fn from(
global: &GlobalScope,
info: ShaderCompilationInfo,
can_gc: CanGc,
) -> DomRoot<Self> {
GPUCompilationMessage::new( GPUCompilationMessage::new(
global, global,
info.message.into(), info.message.into(),
@ -77,7 +81,7 @@ impl GPUCompilationMessage {
info.line_pos, info.line_pos,
info.offset, info.offset,
info.length, info.length,
CanGc::note(), can_gc,
) )
} }
} }

View file

@ -369,10 +369,10 @@ impl GPUDevice {
} }
/// <https://gpuweb.github.io/gpuweb/#lose-the-device> /// <https://gpuweb.github.io/gpuweb/#lose-the-device>
pub(crate) fn lose(&self, reason: GPUDeviceLostReason, msg: String) { pub(crate) fn lose(&self, reason: GPUDeviceLostReason, msg: String, can_gc: CanGc) {
let lost_promise = &(*self.lost_promise.borrow()); let lost_promise = &(*self.lost_promise.borrow());
let global = &self.global(); let global = &self.global();
let lost = GPUDeviceLostInfo::new(global, msg.into(), reason, CanGc::note()); let lost = GPUDeviceLostInfo::new(global, msg.into(), reason, can_gc);
lost_promise.resolve_native(&*lost); lost_promise.resolve_native(&*lost);
} }
} }
@ -410,7 +410,7 @@ impl GPUDeviceMethods<crate::DomTypeHolder> for GPUDevice {
/// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-createbuffer> /// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-createbuffer>
fn CreateBuffer(&self, descriptor: &GPUBufferDescriptor) -> Fallible<DomRoot<GPUBuffer>> { fn CreateBuffer(&self, descriptor: &GPUBufferDescriptor) -> Fallible<DomRoot<GPUBuffer>> {
GPUBuffer::create(self, descriptor) GPUBuffer::create(self, descriptor, CanGc::note())
} }
/// <https://gpuweb.github.io/gpuweb/#GPUDevice-createBindGroupLayout> /// <https://gpuweb.github.io/gpuweb/#GPUDevice-createBindGroupLayout>
@ -419,7 +419,7 @@ impl GPUDeviceMethods<crate::DomTypeHolder> for GPUDevice {
&self, &self,
descriptor: &GPUBindGroupLayoutDescriptor, descriptor: &GPUBindGroupLayoutDescriptor,
) -> Fallible<DomRoot<GPUBindGroupLayout>> { ) -> Fallible<DomRoot<GPUBindGroupLayout>> {
GPUBindGroupLayout::create(self, descriptor) GPUBindGroupLayout::create(self, descriptor, CanGc::note())
} }
/// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-createpipelinelayout> /// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-createpipelinelayout>
@ -427,12 +427,12 @@ impl GPUDeviceMethods<crate::DomTypeHolder> for GPUDevice {
&self, &self,
descriptor: &GPUPipelineLayoutDescriptor, descriptor: &GPUPipelineLayoutDescriptor,
) -> DomRoot<GPUPipelineLayout> { ) -> DomRoot<GPUPipelineLayout> {
GPUPipelineLayout::create(self, descriptor) GPUPipelineLayout::create(self, descriptor, CanGc::note())
} }
/// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-createbindgroup> /// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-createbindgroup>
fn CreateBindGroup(&self, descriptor: &GPUBindGroupDescriptor) -> DomRoot<GPUBindGroup> { fn CreateBindGroup(&self, descriptor: &GPUBindGroupDescriptor) -> DomRoot<GPUBindGroup> {
GPUBindGroup::create(self, descriptor) GPUBindGroup::create(self, descriptor, CanGc::note())
} }
/// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-createshadermodule> /// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-createshadermodule>
@ -478,17 +478,17 @@ impl GPUDeviceMethods<crate::DomTypeHolder> for GPUDevice {
&self, &self,
descriptor: &GPUCommandEncoderDescriptor, descriptor: &GPUCommandEncoderDescriptor,
) -> DomRoot<GPUCommandEncoder> { ) -> DomRoot<GPUCommandEncoder> {
GPUCommandEncoder::create(self, descriptor) GPUCommandEncoder::create(self, descriptor, CanGc::note())
} }
/// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-createtexture> /// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-createtexture>
fn CreateTexture(&self, descriptor: &GPUTextureDescriptor) -> Fallible<DomRoot<GPUTexture>> { fn CreateTexture(&self, descriptor: &GPUTextureDescriptor) -> Fallible<DomRoot<GPUTexture>> {
GPUTexture::create(self, descriptor) GPUTexture::create(self, descriptor, CanGc::note())
} }
/// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-createsampler> /// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-createsampler>
fn CreateSampler(&self, descriptor: &GPUSamplerDescriptor) -> DomRoot<GPUSampler> { fn CreateSampler(&self, descriptor: &GPUSamplerDescriptor) -> DomRoot<GPUSampler> {
GPUSampler::create(self, descriptor) GPUSampler::create(self, descriptor, CanGc::note())
} }
/// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-createrenderpipeline> /// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-createrenderpipeline>
@ -526,7 +526,7 @@ impl GPUDeviceMethods<crate::DomTypeHolder> for GPUDevice {
&self, &self,
descriptor: &GPURenderBundleEncoderDescriptor, descriptor: &GPURenderBundleEncoderDescriptor,
) -> Fallible<DomRoot<GPURenderBundleEncoder>> { ) -> Fallible<DomRoot<GPURenderBundleEncoder>> {
GPURenderBundleEncoder::create(self, descriptor) GPURenderBundleEncoder::create(self, descriptor, CanGc::note())
} }
/// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-pusherrorscope> /// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-pusherrorscope>

View file

@ -83,6 +83,7 @@ impl GPUPipelineLayout {
pub(crate) fn create( pub(crate) fn create(
device: &GPUDevice, device: &GPUDevice,
descriptor: &GPUPipelineLayoutDescriptor, descriptor: &GPUPipelineLayoutDescriptor,
can_gc: CanGc,
) -> DomRoot<GPUPipelineLayout> { ) -> DomRoot<GPUPipelineLayout> {
let bgls = descriptor let bgls = descriptor
.bindGroupLayouts .bindGroupLayouts
@ -114,7 +115,7 @@ impl GPUPipelineLayout {
pipeline_layout, pipeline_layout,
descriptor.parent.label.clone(), descriptor.parent.label.clone(),
bgls, bgls,
CanGc::note(), can_gc,
) )
} }
} }

View file

@ -83,6 +83,7 @@ impl GPURenderBundleEncoder {
pub(crate) fn create( pub(crate) fn create(
device: &GPUDevice, device: &GPUDevice,
descriptor: &GPURenderBundleEncoderDescriptor, descriptor: &GPURenderBundleEncoderDescriptor,
can_gc: CanGc,
) -> Fallible<DomRoot<GPURenderBundleEncoder>> { ) -> Fallible<DomRoot<GPURenderBundleEncoder>> {
let desc = RenderBundleEncoderDescriptor { let desc = RenderBundleEncoderDescriptor {
label: (&descriptor.parent.parent).convert(), label: (&descriptor.parent.parent).convert(),
@ -124,7 +125,7 @@ impl GPURenderBundleEncoder {
device, device,
device.channel().clone(), device.channel().clone(),
descriptor.parent.parent.label.clone(), descriptor.parent.parent.label.clone(),
CanGc::note(), can_gc,
)) ))
} }
} }

View file

@ -82,6 +82,7 @@ impl GPUSampler {
pub(crate) fn create( pub(crate) fn create(
device: &GPUDevice, device: &GPUDevice,
descriptor: &GPUSamplerDescriptor, descriptor: &GPUSamplerDescriptor,
can_gc: CanGc,
) -> DomRoot<GPUSampler> { ) -> DomRoot<GPUSampler> {
let sampler_id = device.global().wgpu_id_hub().create_sampler_id(); let sampler_id = device.global().wgpu_id_hub().create_sampler_id();
let compare_enable = descriptor.compare.is_some(); let compare_enable = descriptor.compare.is_some();
@ -121,7 +122,7 @@ impl GPUSampler {
compare_enable, compare_enable,
sampler, sampler,
descriptor.parent.label.clone(), descriptor.parent.label.clone(),
CanGc::note(), can_gc,
) )
} }
} }

View file

@ -94,7 +94,7 @@ impl GPUShaderModule {
WebGPUShaderModule(program_id), WebGPUShaderModule(program_id),
descriptor.parent.label.clone(), descriptor.parent.label.clone(),
promise.clone(), promise.clone(),
CanGc::note(), can_gc,
); );
let sender = response_async(&promise, &*shader_module); let sender = response_async(&promise, &*shader_module);
device device

View file

@ -131,6 +131,7 @@ impl GPUTexture {
pub(crate) fn create( pub(crate) fn create(
device: &GPUDevice, device: &GPUDevice,
descriptor: &GPUTextureDescriptor, descriptor: &GPUTextureDescriptor,
can_gc: CanGc,
) -> Fallible<DomRoot<GPUTexture>> { ) -> Fallible<DomRoot<GPUTexture>> {
let (desc, size) = convert_texture_descriptor(descriptor, device)?; let (desc, size) = convert_texture_descriptor(descriptor, device)?;
@ -160,7 +161,7 @@ impl GPUTexture {
descriptor.format, descriptor.format,
descriptor.usage, descriptor.usage,
descriptor.parent.label.clone(), descriptor.parent.label.clone(),
CanGc::note(), can_gc,
)) ))
} }
} }

View file

@ -265,7 +265,7 @@ impl XRWebGLLayerMethods<crate::DomTypeHolder> for XRWebGLLayer {
let size = session let size = session
.with_session(|session| session.recommended_framebuffer_resolution()) .with_session(|session| session.recommended_framebuffer_resolution())
.ok_or(Error::Operation)?; .ok_or(Error::Operation)?;
let framebuffer = WebGLFramebuffer::maybe_new_webxr(session, &context, size) let framebuffer = WebGLFramebuffer::maybe_new_webxr(session, &context, size, can_gc)
.ok_or(Error::Operation)?; .ok_or(Error::Operation)?;
// Step 9.3. "Allocate and initialize resources compatible with sessions XR device, // Step 9.3. "Allocate and initialize resources compatible with sessions XR device,

View file

@ -546,9 +546,9 @@ impl Window {
self.webxr_registry.clone() self.webxr_registry.clone()
} }
fn new_paint_worklet(&self) -> DomRoot<Worklet> { fn new_paint_worklet(&self, can_gc: CanGc) -> DomRoot<Worklet> {
debug!("Creating new paint worklet."); debug!("Creating new paint worklet.");
Worklet::new(self, WorkletGlobalScopeType::Paint, CanGc::note()) Worklet::new(self, WorkletGlobalScopeType::Paint, can_gc)
} }
pub(crate) fn register_image_cache_listener( pub(crate) fn register_image_cache_listener(
@ -1708,7 +1708,8 @@ impl Window {
// https://drafts.css-houdini.org/css-paint-api-1/#paint-worklet // https://drafts.css-houdini.org/css-paint-api-1/#paint-worklet
pub(crate) fn paint_worklet(&self) -> DomRoot<Worklet> { pub(crate) fn paint_worklet(&self) -> DomRoot<Worklet> {
self.paint_worklet.or_init(|| self.new_paint_worklet()) self.paint_worklet
.or_init(|| self.new_paint_worklet(CanGc::note()))
} }
pub(crate) fn has_document(&self) -> bool { pub(crate) fn has_document(&self) -> bool {

View file

@ -1168,7 +1168,7 @@ unsafe fn throw_security_error(cx: *mut JSContext, realm: InRealm) -> bool {
if !JS_IsExceptionPending(cx) { if !JS_IsExceptionPending(cx) {
let safe_context = SafeJSContext::from_ptr(cx); let safe_context = SafeJSContext::from_ptr(cx);
let global = GlobalScope::from_context(cx, realm); let global = GlobalScope::from_context(cx, realm);
throw_dom_exception(safe_context, &global, Error::Security); throw_dom_exception(safe_context, &global, Error::Security, CanGc::note());
} }
false false
} }

View file

@ -501,14 +501,14 @@ impl WorkletThread {
should_gc: false, should_gc: false,
gc_threshold: MIN_GC_THRESHOLD, gc_threshold: MIN_GC_THRESHOLD,
}); });
thread.run(); thread.run(CanGc::note());
}) })
.expect("Couldn't start worklet thread"); .expect("Couldn't start worklet thread");
control_sender control_sender
} }
/// The main event loop for a worklet thread /// The main event loop for a worklet thread
fn run(&mut self) { fn run(&mut self, can_gc: CanGc) {
loop { loop {
// The handler for data messages // The handler for data messages
let message = self.role.receiver.recv().unwrap(); let message = self.role.receiver.recv().unwrap();
@ -552,10 +552,10 @@ impl WorkletThread {
// try to become the cold backup. // try to become the cold backup.
if self.role.is_cold_backup { if self.role.is_cold_backup {
if let Some(control) = self.control_buffer.take() { if let Some(control) = self.control_buffer.take() {
self.process_control(control, CanGc::note()); self.process_control(control, can_gc);
} }
while let Ok(control) = self.control_receiver.try_recv() { while let Ok(control) = self.control_receiver.try_recv() {
self.process_control(control, CanGc::note()); self.process_control(control, can_gc);
} }
self.gc(); self.gc();
} else if self.control_buffer.is_none() { } else if self.control_buffer.is_none() {

View file

@ -235,13 +235,13 @@ pub(crate) struct XMLHttpRequest {
} }
impl XMLHttpRequest { impl XMLHttpRequest {
fn new_inherited(global: &GlobalScope) -> XMLHttpRequest { fn new_inherited(global: &GlobalScope, can_gc: CanGc) -> XMLHttpRequest {
XMLHttpRequest { XMLHttpRequest {
eventtarget: XMLHttpRequestEventTarget::new_inherited(), eventtarget: XMLHttpRequestEventTarget::new_inherited(),
ready_state: Cell::new(XMLHttpRequestState::Unsent), ready_state: Cell::new(XMLHttpRequestState::Unsent),
timeout: Cell::new(Duration::ZERO), timeout: Cell::new(Duration::ZERO),
with_credentials: Cell::new(false), with_credentials: Cell::new(false),
upload: Dom::from_ref(&*XMLHttpRequestUpload::new(global, CanGc::note())), upload: Dom::from_ref(&*XMLHttpRequestUpload::new(global, can_gc)),
response_url: DomRefCell::new(String::new()), response_url: DomRefCell::new(String::new()),
status: DomRefCell::new(HttpStatus::new_error()), status: DomRefCell::new(HttpStatus::new_error()),
response: DomRefCell::new(vec![]), response: DomRefCell::new(vec![]),
@ -278,7 +278,7 @@ impl XMLHttpRequest {
can_gc: CanGc, can_gc: CanGc,
) -> DomRoot<XMLHttpRequest> { ) -> DomRoot<XMLHttpRequest> {
reflect_dom_object_with_proto( reflect_dom_object_with_proto(
Box::new(XMLHttpRequest::new_inherited(global)), Box::new(XMLHttpRequest::new_inherited(global, can_gc)),
global, global,
proto, proto,
can_gc, can_gc,

View file

@ -352,7 +352,7 @@ impl ModuleTree {
&owner.global(), &owner.global(),
Some(ModuleHandler::new_boxed(Box::new( Some(ModuleHandler::new_boxed(Box::new(
task!(fetched_resolve: move || { task!(fetched_resolve: move || {
this.notify_owner_to_finish(identity, options); this.notify_owner_to_finish(identity, options,CanGc::note());
}), }),
))), ))),
None, None,
@ -950,6 +950,7 @@ impl ModuleOwner {
&self, &self,
module_identity: ModuleIdentity, module_identity: ModuleIdentity,
fetch_options: ScriptFetchOptions, fetch_options: ScriptFetchOptions,
can_gc: CanGc,
) { ) {
match &self { match &self {
ModuleOwner::Worker(_) => unimplemented!(), ModuleOwner::Worker(_) => unimplemented!(),
@ -991,9 +992,9 @@ impl ModuleOwner {
if !asynch && (*script.root()).get_parser_inserted() { if !asynch && (*script.root()).get_parser_inserted() {
document.deferred_script_loaded(&script.root(), load); document.deferred_script_loaded(&script.root(), load);
} else if !asynch && !(*script.root()).get_non_blocking() { } else if !asynch && !(*script.root()).get_non_blocking() {
document.asap_in_order_script_loaded(&script.root(), load); document.asap_in_order_script_loaded(&script.root(), load, can_gc);
} else { } else {
document.asap_script_loaded(&script.root(), load); document.asap_script_loaded(&script.root(), load, can_gc);
}; };
}, },
} }
@ -1841,7 +1842,7 @@ pub(crate) fn fetch_inline_module_script(
module_tree.set_rethrow_error(exception); module_tree.set_rethrow_error(exception);
module_tree.set_status(ModuleStatus::Finished); module_tree.set_status(ModuleStatus::Finished);
global.set_inline_module_map(script_id, module_tree); global.set_inline_module_map(script_id, module_tree);
owner.notify_owner_to_finish(ModuleIdentity::ScriptId(script_id), options); owner.notify_owner_to_finish(ModuleIdentity::ScriptId(script_id), options, can_gc);
}, },
} }
} }

View file

@ -1073,6 +1073,7 @@ unsafe extern "C" fn consume_stream(
cx, cx,
&global, &global,
Error::Type("Response has unsupported MIME type".to_string()), Error::Type("Response has unsupported MIME type".to_string()),
CanGc::note(),
); );
return false; return false;
} }
@ -1085,6 +1086,7 @@ unsafe extern "C" fn consume_stream(
cx, cx,
&global, &global,
Error::Type("Response.type must be 'basic', 'cors' or 'default'".to_string()), Error::Type("Response.type must be 'basic', 'cors' or 'default'".to_string()),
CanGc::note(),
); );
return false; return false;
}, },
@ -1096,6 +1098,7 @@ unsafe extern "C" fn consume_stream(
cx, cx,
&global, &global,
Error::Type("Response does not have ok status".to_string()), Error::Type("Response does not have ok status".to_string()),
CanGc::note(),
); );
return false; return false;
} }
@ -1106,6 +1109,7 @@ unsafe extern "C" fn consume_stream(
cx, cx,
&global, &global,
Error::Type("There was an error consuming the Response".to_string()), Error::Type("There was an error consuming the Response".to_string()),
CanGc::note(),
); );
return false; return false;
} }
@ -1116,6 +1120,7 @@ unsafe extern "C" fn consume_stream(
cx, cx,
&global, &global,
Error::Type("Response already consumed".to_string()), Error::Type("Response already consumed".to_string()),
CanGc::note(),
); );
return false; return false;
} }
@ -1126,6 +1131,7 @@ unsafe extern "C" fn consume_stream(
cx, cx,
&global, &global,
Error::Type("expected Response or Promise resolving to Response".to_string()), Error::Type("expected Response or Promise resolving to Response".to_string()),
CanGc::note(),
); );
return false; return false;
} }

View file

@ -145,13 +145,23 @@ unsafe fn object_has_to_json_property(
rooted!(in(cx) let mut value = UndefinedValue()); rooted!(in(cx) let mut value = UndefinedValue());
let result = JS_GetProperty(cx, object, name.as_ptr(), value.handle_mut()); let result = JS_GetProperty(cx, object, name.as_ptr(), value.handle_mut());
if !result { if !result {
throw_dom_exception(SafeJSContext::from_ptr(cx), global_scope, Error::JSFailed); throw_dom_exception(
SafeJSContext::from_ptr(cx),
global_scope,
Error::JSFailed,
CanGc::note(),
);
false false
} else { } else {
result && JS_TypeOfValue(cx, value.handle()) == JSType::JSTYPE_FUNCTION result && JS_TypeOfValue(cx, value.handle()) == JSType::JSTYPE_FUNCTION
} }
} else if JS_IsExceptionPending(cx) { } else if JS_IsExceptionPending(cx) {
throw_dom_exception(SafeJSContext::from_ptr(cx), global_scope, Error::JSFailed); throw_dom_exception(
SafeJSContext::from_ptr(cx),
global_scope,
Error::JSFailed,
CanGc::note(),
);
false false
} else { } else {
false false
@ -216,7 +226,12 @@ pub(crate) unsafe fn jsval_to_webdriver(
_ => return Err(WebDriverJSError::UnknownType), _ => return Err(WebDriverJSError::UnknownType),
}, },
Err(error) => { Err(error) => {
throw_dom_exception(SafeJSContext::from_ptr(cx), global_scope, error); throw_dom_exception(
SafeJSContext::from_ptr(cx),
global_scope,
error,
CanGc::note(),
);
return Err(WebDriverJSError::JSError); return Err(WebDriverJSError::JSError);
}, },
}; };
@ -229,7 +244,12 @@ pub(crate) unsafe fn jsval_to_webdriver(
err @ Err(_) => return err, err @ Err(_) => return err,
}, },
Err(error) => { Err(error) => {
throw_dom_exception(SafeJSContext::from_ptr(cx), global_scope, error); throw_dom_exception(
SafeJSContext::from_ptr(cx),
global_scope,
error,
CanGc::note(),
);
return Err(WebDriverJSError::JSError); return Err(WebDriverJSError::JSError);
}, },
} }
@ -267,7 +287,12 @@ pub(crate) unsafe fn jsval_to_webdriver(
) { ) {
jsval_to_webdriver(cx, global_scope, value.handle()) jsval_to_webdriver(cx, global_scope, value.handle())
} else { } else {
throw_dom_exception(SafeJSContext::from_ptr(cx), global_scope, Error::JSFailed); throw_dom_exception(
SafeJSContext::from_ptr(cx),
global_scope,
Error::JSFailed,
CanGc::note(),
);
Err(WebDriverJSError::JSError) Err(WebDriverJSError::JSError)
} }
} else { } else {
@ -1077,7 +1102,7 @@ pub(crate) fn handle_get_property(
} }
}, },
Err(error) => { Err(error) => {
throw_dom_exception(cx, &node.global(), error); throw_dom_exception(cx, &node.global(), error, CanGc::note());
WebDriverJSValue::Undefined WebDriverJSValue::Undefined
}, },
} }