diff --git a/components/script/dom/css/css.rs b/components/script/dom/css/css.rs index 2c8fd56b5f8..2fc3b391ad4 100644 --- a/components/script/dom/css/css.rs +++ b/components/script/dom/css/css.rs @@ -4,6 +4,7 @@ use cssparser::{Parser, ParserInput, serialize_identifier}; use dom_struct::dom_struct; +use js::context::JSContext; use script_bindings::codegen::GenericBindings::CSSBinding::PropertyDefinition; use style::stylesheets::supports_rule::{Declaration, parse_condition_or_declaration}; use style::stylesheets::{CssRuleType, UrlExtraData}; @@ -70,8 +71,8 @@ impl CSSMethods for CSS { } /// - fn PaintWorklet(win: &Window) -> DomRoot { - win.paint_worklet() + fn PaintWorklet(cx: &mut JSContext, win: &Window) -> DomRoot { + win.paint_worklet(cx) } /// diff --git a/components/script/dom/paintworkletglobalscope.rs b/components/script/dom/paintworkletglobalscope.rs index d6c1225dcd3..77df8380121 100644 --- a/components/script/dom/paintworkletglobalscope.rs +++ b/components/script/dom/paintworkletglobalscope.rs @@ -4,7 +4,7 @@ use std::cell::Cell; use std::collections::hash_map::Entry; -use std::ptr::null_mut; +use std::ptr::{NonNull, null_mut}; use std::rc::Rc; use std::sync::{Arc, Mutex}; use std::thread; @@ -14,13 +14,13 @@ use crossbeam_channel::{Sender, unbounded}; use dom_struct::dom_struct; use euclid::{Scale, Size2D}; use js::context::JSContext; -use js::jsapi::{ - HandleValueArray, Heap, IsCallable, IsConstructor, JS_ClearPendingException, - JS_IsExceptionPending, JSAutoRealm, JSObject, NewArrayObject, Value, -}; +use js::jsapi::{HandleValueArray, Heap, IsCallable, IsConstructor, JSObject, Value}; use js::jsval::{JSVal, ObjectValue, UndefinedValue}; +use js::realm::AutoRealm; use js::rust::HandleValue; -use js::rust::wrappers::{Call, Construct1}; +use js::rust::wrappers2::{ + Call, Construct1, JS_ClearPendingException, JS_IsExceptionPending, NewArrayObject, +}; use net_traits::image_cache::ImageCache; use pixels::PixelFormat; use script_traits::{DrawAPaintImageResult, PaintWorkletError, Painter}; @@ -130,7 +130,7 @@ impl PaintWorkletGlobalScope { self.image_cache.clone() } - pub(crate) fn perform_a_worklet_task(&self, task: PaintWorkletTask) { + pub(crate) fn perform_a_worklet_task(&self, cx: &mut JSContext, task: PaintWorkletTask) { match task { PaintWorkletTask::DrawAPaintImage( name, @@ -153,10 +153,16 @@ impl PaintWorkletGlobalScope { let map = StylePropertyMapReadOnly::from_iter( self.upcast(), properties.iter().cloned(), - CanGc::deprecated_note(), + CanGc::from_cx(cx), + ); + let result = self.draw_a_paint_image( + cx, + &name, + size, + device_pixel_ratio, + &map, + &arguments, ); - let result = - self.draw_a_paint_image(&name, size, device_pixel_ratio, &map, &arguments); if (result.image_key.is_some()) && (result.missing_image_urls.is_empty()) { *self.cached_name.borrow_mut() = name; self.cached_size.set(size); @@ -179,10 +185,16 @@ impl PaintWorkletGlobalScope { let map = StylePropertyMapReadOnly::from_iter( self.upcast(), properties.iter().cloned(), - CanGc::deprecated_note(), + CanGc::from_cx(cx), + ); + let result = self.draw_a_paint_image( + cx, + &name, + size, + device_pixel_ratio, + &map, + &arguments, ); - let result = - self.draw_a_paint_image(&name, size, device_pixel_ratio, &map, &arguments); if (result.image_key.is_some()) && (result.missing_image_urls.is_empty()) { *self.cached_name.borrow_mut() = name; *self.cached_properties.borrow_mut() = properties; @@ -197,6 +209,7 @@ impl PaintWorkletGlobalScope { /// fn draw_a_paint_image( &self, + cx: &mut JSContext, name: &Atom, size_in_px: Size2D, device_pixel_ratio: Scale, @@ -213,13 +226,13 @@ impl PaintWorkletGlobalScope { // TODO: document paint definitions. self.invoke_a_paint_callback( + cx, name, size_in_px, size_in_dpx, device_pixel_ratio, properties, arguments, - CanGc::deprecated_note(), ) } @@ -228,26 +241,29 @@ impl PaintWorkletGlobalScope { #[expect(unsafe_code)] fn invoke_a_paint_callback( &self, + cx: &mut JSContext, name: &Atom, size_in_px: Size2D, size_in_dpx: Size2D, device_pixel_ratio: Scale, properties: &StylePropertyMapReadOnly, arguments: &[String], - can_gc: CanGc, ) -> DrawAPaintImageResult { debug!( "Invoking a paint callback {}({},{}) at {:?}.", name, size_in_px.width, size_in_px.height, device_pixel_ratio ); - let cx = WorkletGlobalScope::get_cx(); - let _ac = JSAutoRealm::new(*cx, self.worklet_global.reflector().get_jsobject().get()); + let mut realm = AutoRealm::new( + cx, + NonNull::new(self.worklet_global.reflector().get_jsobject().get()).unwrap(), + ); + let cx = &mut *realm; // TODO: Steps 1-2.1. // Step 2.2-5.1. - rooted!(in(*cx) let mut class_constructor = UndefinedValue()); - rooted!(in(*cx) let mut paint_function = UndefinedValue()); + rooted!(&in(cx) let mut class_constructor = UndefinedValue()); + rooted!(&in(cx) let mut paint_function = UndefinedValue()); let rendering_context = match self.paint_definitions.borrow().get(name) { None => { // Step 2.2. @@ -271,21 +287,21 @@ impl PaintWorkletGlobalScope { // prepopulate the paint instance in `RegisterPaint`, to avoid calling it in // the primary worklet thread. // https://github.com/servo/servo/issues/17377 - rooted!(in(*cx) let mut paint_instance = UndefinedValue()); + rooted!(&in(cx) let mut paint_instance = UndefinedValue()); match self.paint_class_instances.borrow_mut().entry(name.clone()) { Entry::Occupied(entry) => paint_instance.set(entry.get().get()), Entry::Vacant(entry) => { // Step 5.2-5.3 let args = HandleValueArray::empty(); - rooted!(in(*cx) let mut result = null_mut::()); + rooted!(&in(cx) let mut result = null_mut::()); unsafe { - Construct1(*cx, class_constructor.handle(), &args, result.handle_mut()); + Construct1(cx, class_constructor.handle(), &args, result.handle_mut()); } paint_instance.set(ObjectValue(result.get())); - if unsafe { JS_IsExceptionPending(*cx) } { + if unsafe { JS_IsExceptionPending(cx) } { debug!("Paint constructor threw an exception {}.", name); unsafe { - JS_ClearPendingException(*cx); + JS_ClearPendingException(cx); } self.paint_definitions .borrow_mut() @@ -309,18 +325,19 @@ impl PaintWorkletGlobalScope { rendering_context.set_bitmap_dimensions(size_in_px, device_pixel_ratio); // Step 9 - let paint_size = PaintSize::new(self, size_in_px, can_gc); + let paint_size = PaintSize::new(self, size_in_px, CanGc::from_cx(cx)); // TODO: Step 10 // Steps 11-12 debug!("Invoking paint function {}.", name); rooted_vec!(let mut arguments_values); for argument in arguments { - let style_value = CSSStyleValue::new(self.upcast(), argument.clone(), can_gc); + let style_value = + CSSStyleValue::new(self.upcast(), argument.clone(), CanGc::from_cx(cx)); arguments_values.push(ObjectValue(style_value.reflector().get_jsobject().get())); } let arguments_value_array = HandleValueArray::from(&arguments_values); - rooted!(in(*cx) let argument_object = unsafe { NewArrayObject(*cx, &arguments_value_array) }); + rooted!(&in(cx) let argument_object = unsafe { NewArrayObject(cx, &arguments_value_array) }); rooted_vec!(let mut callback_args); callback_args.push(ObjectValue( @@ -331,10 +348,10 @@ impl PaintWorkletGlobalScope { callback_args.push(ObjectValue(argument_object.get())); let args = HandleValueArray::from(&callback_args); - rooted!(in(*cx) let mut result = UndefinedValue()); + rooted!(&in(cx) let mut result = UndefinedValue()); unsafe { Call( - *cx, + cx, paint_instance.handle(), paint_function.handle(), &args, @@ -344,10 +361,10 @@ impl PaintWorkletGlobalScope { let missing_image_urls = rendering_context.take_missing_image_urls(); // Step 13. - if unsafe { JS_IsExceptionPending(*cx) } { + if unsafe { JS_IsExceptionPending(cx) } { debug!("Paint function threw an exception {}.", name); unsafe { - JS_ClearPendingException(*cx); + JS_ClearPendingException(cx); } return self.invalid_image(size_in_dpx, missing_image_urls); } @@ -497,11 +514,15 @@ impl PaintWorkletGlobalScopeMethods for PaintWorkletGlobal #[expect(unsafe_code)] #[cfg_attr(crown, expect(crown::unrooted_must_root))] /// - fn RegisterPaint(&self, name: DOMString, paint_ctor: Rc) -> Fallible<()> { + fn RegisterPaint( + &self, + cx: &mut JSContext, + name: DOMString, + paint_ctor: Rc, + ) -> Fallible<()> { let name = Atom::from(name); - let cx = WorkletGlobalScope::get_cx(); - rooted!(in(*cx) let paint_obj = paint_ctor.callback_holder().get()); - rooted!(in(*cx) let paint_val = ObjectValue(paint_obj.get())); + rooted!(&in(cx) let paint_obj = paint_ctor.callback_holder().get()); + rooted!(&in(cx) let paint_val = ObjectValue(paint_obj.get())); debug!("Registering paint image name {}.", name); @@ -517,17 +538,19 @@ impl PaintWorkletGlobalScopeMethods for PaintWorkletGlobal // Step 4-6. let property_names: Vec = - get_property(cx, paint_obj.handle(), c"inputProperties", ())?.unwrap_or_default(); + get_property(cx.into(), paint_obj.handle(), c"inputProperties", ())? + .unwrap_or_default(); let properties = property_names.into_iter().map(Atom::from).collect(); // Step 7-9. let input_arguments: Vec = - get_property(cx, paint_obj.handle(), c"inputArguments", ())?.unwrap_or_default(); + get_property(cx.into(), paint_obj.handle(), c"inputArguments", ())?.unwrap_or_default(); // TODO: Steps 10-11. // Steps 12-13. - let alpha: bool = get_property(cx, paint_obj.handle(), c"alpha", ())?.unwrap_or(true); + let alpha: bool = + get_property(cx.into(), paint_obj.handle(), c"alpha", ())?.unwrap_or(true); // Step 14 if unsafe { !IsConstructor(paint_obj.get()) } { @@ -535,17 +558,22 @@ impl PaintWorkletGlobalScopeMethods for PaintWorkletGlobal } // Steps 15-16 - rooted!(in(*cx) let mut prototype = UndefinedValue()); - get_property_jsval(cx, paint_obj.handle(), c"prototype", prototype.handle_mut())?; + rooted!(&in(cx) let mut prototype = UndefinedValue()); + get_property_jsval( + cx.into(), + paint_obj.handle(), + c"prototype", + prototype.handle_mut(), + )?; if !prototype.is_object() { return Err(Error::Type(c"Prototype is not an object.".to_owned())); } - rooted!(in(*cx) let prototype = prototype.to_object()); + rooted!(&in(cx) let prototype = prototype.to_object()); // Steps 17-18 - rooted!(in(*cx) let mut paint_function = UndefinedValue()); + rooted!(&in(cx) let mut paint_function = UndefinedValue()); get_property_jsval( - cx, + cx.into(), prototype.handle(), c"paint", paint_function.handle_mut(), @@ -555,7 +583,7 @@ impl PaintWorkletGlobalScopeMethods for PaintWorkletGlobal } // Step 19. - let Some(context) = PaintRenderingContext2D::new(self, CanGc::deprecated_note()) else { + let Some(context) = PaintRenderingContext2D::new(self, CanGc::from_cx(cx)) else { return Err(Error::Operation(None)); }; let definition = PaintDefinition::new( diff --git a/components/script/dom/testing/testworklet.rs b/components/script/dom/testing/testworklet.rs index 26b008b54fe..d684c8b13bf 100644 --- a/components/script/dom/testing/testworklet.rs +++ b/components/script/dom/testing/testworklet.rs @@ -6,21 +6,21 @@ use std::rc::Rc; use dom_struct::dom_struct; +use js::context::JSContext; +use js::realm::CurrentRealm; use js::rust::HandleObject; use crate::dom::bindings::codegen::Bindings::TestWorkletBinding::TestWorkletMethods; use crate::dom::bindings::codegen::Bindings::WorkletBinding::Worklet_Binding::WorkletMethods; use crate::dom::bindings::codegen::Bindings::WorkletBinding::WorkletOptions; use crate::dom::bindings::error::Fallible; -use crate::dom::bindings::reflector::{DomGlobal, Reflector, reflect_dom_object_with_proto}; +use crate::dom::bindings::reflector::{DomGlobal, Reflector, reflect_dom_object_with_proto_and_cx}; use crate::dom::bindings::root::{Dom, DomRoot}; use crate::dom::bindings::str::{DOMString, USVString}; use crate::dom::promise::Promise; use crate::dom::window::Window; use crate::dom::worklet::Worklet; use crate::dom::workletglobalscope::WorkletGlobalScopeType; -use crate::realms::InRealm; -use crate::script_runtime::CanGc; use crate::script_thread::ScriptThread; #[dom_struct] @@ -37,35 +37,37 @@ impl TestWorklet { } } - fn new(window: &Window, proto: Option, can_gc: CanGc) -> DomRoot { - let worklet = Worklet::new(window, WorkletGlobalScopeType::Test, can_gc); - reflect_dom_object_with_proto( + fn new( + cx: &mut JSContext, + window: &Window, + proto: Option, + ) -> DomRoot { + let worklet = Worklet::new(cx, window, WorkletGlobalScopeType::Test); + reflect_dom_object_with_proto_and_cx( Box::new(TestWorklet::new_inherited(&worklet)), window, proto, - can_gc, + cx, ) } } impl TestWorkletMethods for TestWorklet { fn Constructor( + cx: &mut JSContext, window: &Window, proto: Option, - can_gc: CanGc, ) -> Fallible> { - Ok(TestWorklet::new(window, proto, can_gc)) + Ok(TestWorklet::new(cx, window, proto)) } - #[expect(non_snake_case)] fn AddModule( &self, - moduleURL: USVString, + realm: &mut CurrentRealm, + module_url: USVString, options: &WorkletOptions, - comp: InRealm, - can_gc: CanGc, ) -> Rc { - self.worklet.AddModule(moduleURL, options, comp, can_gc) + self.worklet.AddModule(realm, module_url, options) } fn Lookup(&self, key: DOMString) -> Option { diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index 3ca8950868e..ffb0f0e5732 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -690,9 +690,9 @@ impl Window { self.webxr_registry.clone() } - fn new_paint_worklet(&self, can_gc: CanGc) -> DomRoot { + fn new_paint_worklet(&self, cx: &mut JSContext) -> DomRoot { debug!("Creating new paint worklet."); - Worklet::new(self, WorkletGlobalScopeType::Paint, can_gc) + Worklet::new(cx, self, WorkletGlobalScopeType::Paint) } pub(crate) fn register_image_cache_listener( @@ -2451,9 +2451,8 @@ impl Window { } // https://drafts.css-houdini.org/css-paint-api-1/#paint-worklet - pub(crate) fn paint_worklet(&self) -> DomRoot { - self.paint_worklet - .or_init(|| self.new_paint_worklet(CanGc::deprecated_note())) + pub(crate) fn paint_worklet(&self, cx: &mut JSContext) -> DomRoot { + self.paint_worklet.or_init(|| self.new_paint_worklet(cx)) } pub(crate) fn has_document(&self) -> bool { diff --git a/components/script/dom/worklet.rs b/components/script/dom/worklet.rs index 3ed4b9325cc..b35f49d63d9 100644 --- a/components/script/dom/worklet.rs +++ b/components/script/dom/worklet.rs @@ -20,7 +20,9 @@ use std::thread; use crossbeam_channel::{Receiver, Sender, unbounded}; use dom_struct::dom_struct; +use js::context::JSContext; use js::jsapi::{GCReason, JSGCParamKey, JSTracer}; +use js::realm::CurrentRealm; use js::rust::wrappers2::{JS_GC, JS_GetGCParameter}; use malloc_size_of::malloc_size_of_is_0; use net_traits::blob_url_store::UrlWithBlobClaim; @@ -41,7 +43,7 @@ use crate::dom::bindings::codegen::Bindings::WorkletBinding::{WorkletMethods, Wo use crate::dom::bindings::error::Error; use crate::dom::bindings::inheritance::Castable; use crate::dom::bindings::refcounted::TrustedPromise; -use crate::dom::bindings::reflector::{DomGlobal, Reflector, reflect_dom_object}; +use crate::dom::bindings::reflector::{DomGlobal, Reflector, reflect_dom_object_with_cx}; use crate::dom::bindings::root::{Dom, DomRoot}; use crate::dom::bindings::str::USVString; use crate::dom::bindings::trace::{CustomTraceable, JSTraceable, RootedTraceableBox}; @@ -56,7 +58,6 @@ use crate::dom::workletglobalscope::{ }; use crate::fetch::{CspViolationsProcessor, load_whole_resource}; use crate::messaging::{CommonScriptMsg, MainThreadScriptMsg}; -use crate::realms::InRealm; use crate::script_runtime::{CanGc, Runtime, ScriptThreadEventCategory}; use crate::script_thread::ScriptThread; use crate::task::TaskBox; @@ -107,15 +108,15 @@ impl Worklet { } pub(crate) fn new( + cx: &mut JSContext, window: &Window, global_type: WorkletGlobalScopeType, - can_gc: CanGc, ) -> DomRoot { debug!("Creating worklet {:?}.", global_type); - reflect_dom_object( + reflect_dom_object_with_cx( Box::new(Worklet::new_inherited(window, global_type)), window, - can_gc, + cx, ) } @@ -134,13 +135,12 @@ impl WorkletMethods for Worklet { /// fn AddModule( &self, + realm: &mut CurrentRealm, module_url: USVString, options: &WorkletOptions, - comp: InRealm, - can_gc: CanGc, ) -> Rc { // Step 1. - let promise = Promise::new_in_current_realm(comp, can_gc); + let promise = Promise::new_in_realm(realm); // Step 3. let module_url_record = match self.window.Document().base_url().join(&module_url.0) { @@ -148,7 +148,7 @@ impl WorkletMethods for Worklet { Err(err) => { // Step 4. debug!("URL {:?} parse error {:?}.", module_url.0, err); - promise.reject_error(Error::Syntax(None), can_gc); + promise.reject_error(Error::Syntax(None), CanGc::from_cx(realm)); return promise; }, }; @@ -534,14 +534,14 @@ impl WorkletThread { } /// The main event loop for a worklet thread - fn run(&mut self, cx: &mut js::context::JSContext) { + fn run(&mut self, cx: &mut JSContext) { loop { // The handler for data messages let message = self.role.receiver.recv().unwrap(); match message { // The whole point of this thread pool is to perform tasks! WorkletData::Task(id, task) => { - self.perform_a_worklet_task(id, task); + self.perform_a_worklet_task(cx, id, task); }, // To start swapping roles, get ready to perform an atomic swap, // and block waiting for the other end to finish it. @@ -615,7 +615,7 @@ impl WorkletThread { /// Perform a GC. #[expect(unsafe_code)] - fn gc(&mut self, cx: &mut js::context::JSContext) { + fn gc(&mut self, cx: &mut JSContext) { debug!( "BEGIN GC (usage = {}, threshold = {}).", self.current_memory_usage(), @@ -641,7 +641,7 @@ impl WorkletThread { inherited_secure_context: Option, global_type: WorkletGlobalScopeType, base_url: ServoUrl, - cx: &mut js::context::JSContext, + cx: &mut JSContext, ) -> DomRoot { match self.global_scopes.entry(worklet_id) { hash_map::Entry::Occupied(entry) => DomRoot::from_ref(entry.get()), @@ -677,7 +677,7 @@ impl WorkletThread { credentials: RequestCredentials, pending_tasks_struct: PendingTasksStruct, promise: TrustedPromise, - cx: &mut js::context::JSContext, + cx: &mut JSContext, ) { debug!("Fetching from {}.", script_url); // Step 1. @@ -742,9 +742,9 @@ impl WorkletThread { } /// Perform a task. - fn perform_a_worklet_task(&self, worklet_id: WorkletId, task: WorkletTask) { + fn perform_a_worklet_task(&self, cx: &mut JSContext, worklet_id: WorkletId, task: WorkletTask) { match self.global_scopes.get(&worklet_id) { - Some(global) => global.perform_a_worklet_task(task), + Some(global) => global.perform_a_worklet_task(cx, task), None => warn!("No such worklet as {:?}.", worklet_id), } } diff --git a/components/script/dom/workletglobalscope.rs b/components/script/dom/workletglobalscope.rs index c3c44ff543f..ebcbf996742 100644 --- a/components/script/dom/workletglobalscope.rs +++ b/components/script/dom/workletglobalscope.rs @@ -9,6 +9,7 @@ use crossbeam_channel::Sender; use devtools_traits::ScriptToDevtoolsControlMsg; use dom_struct::dom_struct; use embedder_traits::{JavaScriptEvaluationError, ScriptToEmbedderChan}; +use js::context::JSContext; use net_traits::ResourceThreads; use net_traits::image_cache::ImageCache; use profile_traits::{mem, time}; @@ -33,7 +34,7 @@ use crate::dom::webgpu::identityhub::IdentityHub; use crate::dom::worklet::WorkletExecutor; use crate::messaging::MainThreadScriptMsg; use crate::realms::enter_auto_realm; -use crate::script_runtime::{IntroductionType, JSContext}; +use crate::script_runtime::IntroductionType; #[dom_struct] /// @@ -60,7 +61,7 @@ impl WorkletGlobalScope { inherited_secure_context: Option, executor: WorkletExecutor, init: &WorkletGlobalScopeInit, - cx: &mut js::context::JSContext, + cx: &mut JSContext, ) -> DomRoot { let scope: DomRoot = match scope_type { #[cfg(feature = "testbinding")] @@ -130,16 +131,11 @@ impl WorkletGlobalScope { } } - /// Get the JS context. - pub(crate) fn get_cx() -> JSContext { - GlobalScope::get_cx() - } - /// Evaluate a JS script in this global. pub(crate) fn evaluate_js( &self, script: Cow<'_, str>, - cx: &mut js::context::JSContext, + cx: &mut JSContext, ) -> Result<(), JavaScriptEvaluationError> { let mut realm = enter_auto_realm(cx, self); let cx = &mut realm.current_realm(); @@ -182,7 +178,7 @@ impl WorkletGlobalScope { } /// Perform a worklet task - pub(crate) fn perform_a_worklet_task(&self, task: WorkletTask) { + pub(crate) fn perform_a_worklet_task(&self, cx: &mut JSContext, task: WorkletTask) { match task { #[cfg(feature = "testbinding")] WorkletTask::Test(task) => match self.downcast::() { @@ -190,7 +186,7 @@ impl WorkletGlobalScope { None => warn!("This is not a test worklet."), }, WorkletTask::Paint(task) => match self.downcast::() { - Some(global) => global.perform_a_worklet_task(task), + Some(global) => global.perform_a_worklet_task(cx, task), None => warn!("This is not a paint worklet."), }, } diff --git a/components/script_bindings/codegen/Bindings.conf b/components/script_bindings/codegen/Bindings.conf index 38490bb437c..290fbd94c83 100644 --- a/components/script_bindings/codegen/Bindings.conf +++ b/components/script_bindings/codegen/Bindings.conf @@ -126,6 +126,10 @@ DOMInterfaces = { 'canGc': ['IsConditionalMediationAvailable', 'WillRequestConditionalCreation'], }, +'CSS': { + 'cx': ['PaintWorklet'], +}, + 'CSSGroupingRule': { 'cx': ['CssRules', 'InsertRule', 'DeleteRule'], }, @@ -746,6 +750,10 @@ DOMInterfaces = { 'cx': ['CreateLinearGradient', 'CreatePattern', 'CreateRadialGradient', 'GetTransform'], }, +'PaintWorkletGlobalScope': { + 'cx': ['RegisterPaint'], +}, + 'PerformanceObserver': { 'canGc': ['SupportedEntryTypes'], }, @@ -856,8 +864,8 @@ DOMInterfaces = { }, 'TestWorklet': { - 'inRealms': ['AddModule'], - 'canGc': ['AddModule'], + 'cx': ['Constructor'], + 'realm': ['AddModule'], }, 'Text': { @@ -955,8 +963,7 @@ DOMInterfaces = { }, 'Worklet': { - 'inRealms': ['AddModule'], - 'canGc': ['AddModule'], + 'realm': ['AddModule'], }, 'XMLDocument': {