script: pass &mut JSContext inside worklet code (#44441)

Testing: It compiles 
Part of #40600

Signed-off-by: Gae24 <96017547+Gae24@users.noreply.github.com>
This commit is contained in:
Gae24
2026-04-23 07:58:09 +02:00
committed by GitHub
parent 353e5248f1
commit 20e94989eb
7 changed files with 128 additions and 95 deletions

View File

@@ -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<crate::DomTypeHolder> for CSS {
}
/// <https://drafts.css-houdini.org/css-paint-api-1/#paint-worklet>
fn PaintWorklet(win: &Window) -> DomRoot<Worklet> {
win.paint_worklet()
fn PaintWorklet(cx: &mut JSContext, win: &Window) -> DomRoot<Worklet> {
win.paint_worklet(cx)
}
/// <https://drafts.css-houdini.org/css-properties-values-api/#the-registerproperty-function>

View File

@@ -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 {
/// <https://drafts.css-houdini.org/css-paint-api/#draw-a-paint-image>
fn draw_a_paint_image(
&self,
cx: &mut JSContext,
name: &Atom,
size_in_px: Size2D<f32, CSSPixel>,
device_pixel_ratio: Scale<f32, CSSPixel, DevicePixel>,
@@ -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<f32, CSSPixel>,
size_in_dpx: Size2D<u32, DevicePixel>,
device_pixel_ratio: Scale<f32, CSSPixel, DevicePixel>,
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::<JSObject>());
rooted!(&in(cx) let mut result = null_mut::<JSObject>());
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<crate::DomTypeHolder> for PaintWorkletGlobal
#[expect(unsafe_code)]
#[cfg_attr(crown, expect(crown::unrooted_must_root))]
/// <https://drafts.css-houdini.org/css-paint-api/#dom-paintworkletglobalscope-registerpaint>
fn RegisterPaint(&self, name: DOMString, paint_ctor: Rc<VoidFunction>) -> Fallible<()> {
fn RegisterPaint(
&self,
cx: &mut JSContext,
name: DOMString,
paint_ctor: Rc<VoidFunction>,
) -> 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<crate::DomTypeHolder> for PaintWorkletGlobal
// Step 4-6.
let property_names: Vec<String> =
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<String> =
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<crate::DomTypeHolder> 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<crate::DomTypeHolder> 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(

View File

@@ -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<HandleObject>, can_gc: CanGc) -> DomRoot<TestWorklet> {
let worklet = Worklet::new(window, WorkletGlobalScopeType::Test, can_gc);
reflect_dom_object_with_proto(
fn new(
cx: &mut JSContext,
window: &Window,
proto: Option<HandleObject>,
) -> DomRoot<TestWorklet> {
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<crate::DomTypeHolder> for TestWorklet {
fn Constructor(
cx: &mut JSContext,
window: &Window,
proto: Option<HandleObject>,
can_gc: CanGc,
) -> Fallible<DomRoot<TestWorklet>> {
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<Promise> {
self.worklet.AddModule(moduleURL, options, comp, can_gc)
self.worklet.AddModule(realm, module_url, options)
}
fn Lookup(&self, key: DOMString) -> Option<DOMString> {

View File

@@ -690,9 +690,9 @@ impl Window {
self.webxr_registry.clone()
}
fn new_paint_worklet(&self, can_gc: CanGc) -> DomRoot<Worklet> {
fn new_paint_worklet(&self, cx: &mut JSContext) -> DomRoot<Worklet> {
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<Worklet> {
self.paint_worklet
.or_init(|| self.new_paint_worklet(CanGc::deprecated_note()))
pub(crate) fn paint_worklet(&self, cx: &mut JSContext) -> DomRoot<Worklet> {
self.paint_worklet.or_init(|| self.new_paint_worklet(cx))
}
pub(crate) fn has_document(&self) -> bool {

View File

@@ -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<Worklet> {
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<crate::DomTypeHolder> for Worklet {
/// <https://drafts.css-houdini.org/worklets/#dom-worklet-addmodule>
fn AddModule(
&self,
realm: &mut CurrentRealm,
module_url: USVString,
options: &WorkletOptions,
comp: InRealm,
can_gc: CanGc,
) -> Rc<Promise> {
// 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<crate::DomTypeHolder> 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<bool>,
global_type: WorkletGlobalScopeType,
base_url: ServoUrl,
cx: &mut js::context::JSContext,
cx: &mut JSContext,
) -> DomRoot<WorkletGlobalScope> {
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),
}
}

View File

@@ -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]
/// <https://drafts.css-houdini.org/worklets/#workletglobalscope>
@@ -60,7 +61,7 @@ impl WorkletGlobalScope {
inherited_secure_context: Option<bool>,
executor: WorkletExecutor,
init: &WorkletGlobalScopeInit,
cx: &mut js::context::JSContext,
cx: &mut JSContext,
) -> DomRoot<WorkletGlobalScope> {
let scope: DomRoot<WorkletGlobalScope> = 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::<TestWorkletGlobalScope>() {
@@ -190,7 +186,7 @@ impl WorkletGlobalScope {
None => warn!("This is not a test worklet."),
},
WorkletTask::Paint(task) => match self.downcast::<PaintWorkletGlobalScope>() {
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."),
},
}

View File

@@ -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': {