mirror of
https://github.com/servo/servo
synced 2026-04-25 17:15:48 +02:00
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:
@@ -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>
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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> {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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."),
|
||||
},
|
||||
}
|
||||
|
||||
@@ -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': {
|
||||
|
||||
Reference in New Issue
Block a user