Move unsafe to the wrap method for global objects (#38896)

The method now doesn't need unsafe in its signature because it no longer
accepts unsafe pointers as arguments. We move the unsafe marker to the
method itself.

Testing: I opened the browser and went to google.com; I ran some WPT
(IndexedDB) tests.
Fixes: #38361

---------

Signed-off-by: criskell <96352451+criskell@users.noreply.github.com>
This commit is contained in:
criskell 2025-08-25 19:02:55 -03:00 committed by GitHub
parent b9dc228e51
commit 9082217272
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 41 additions and 75 deletions

View file

@ -12,7 +12,6 @@ use embedder_traits::JavaScriptEvaluationError;
use embedder_traits::resources::{self, Resource}; use embedder_traits::resources::{self, Resource};
use ipc_channel::ipc::IpcSender; use ipc_channel::ipc::IpcSender;
use js::jsval::UndefinedValue; use js::jsval::UndefinedValue;
use js::rust::Runtime;
use js::rust::wrappers::JS_DefineDebuggerObject; use js::rust::wrappers::JS_DefineDebuggerObject;
use net_traits::ResourceThreads; use net_traits::ResourceThreads;
use profile_traits::{mem, time}; use profile_traits::{mem, time};
@ -61,7 +60,6 @@ impl DebuggerGlobalScope {
/// those threads cant generate pipeline ids, and they only contain one debuggee from one pipeline /// those threads cant generate pipeline ids, and they only contain one debuggee from one pipeline
#[allow(unsafe_code, clippy::too_many_arguments)] #[allow(unsafe_code, clippy::too_many_arguments)]
pub(crate) fn new( pub(crate) fn new(
runtime: &Runtime,
debugger_pipeline_id: PipelineId, debugger_pipeline_id: PipelineId,
script_to_devtools_sender: Option<IpcSender<ScriptToDevtoolsControlMsg>>, script_to_devtools_sender: Option<IpcSender<ScriptToDevtoolsControlMsg>>,
devtools_to_script_sender: IpcSender<DevtoolScriptControlMsg>, devtools_to_script_sender: IpcSender<DevtoolScriptControlMsg>,
@ -93,12 +91,8 @@ impl DebuggerGlobalScope {
devtools_to_script_sender, devtools_to_script_sender,
get_possible_breakpoints_result_sender: RefCell::new(None), get_possible_breakpoints_result_sender: RefCell::new(None),
}); });
let global = unsafe { let global =
DebuggerGlobalScopeBinding::Wrap::<crate::DomTypeHolder>( DebuggerGlobalScopeBinding::Wrap::<crate::DomTypeHolder>(GlobalScope::get_cx(), global);
JSContext::from_ptr(runtime.cx()),
global,
)
};
let realm = enter_realm(&*global); let realm = enter_realm(&*global);
define_all_exposed_interfaces(global.upcast(), InRealm::entered(&realm), can_gc); define_all_exposed_interfaces(global.upcast(), InRealm::entered(&realm), can_gc);

View file

@ -325,7 +325,6 @@ impl DedicatedWorkerGlobalScope {
control_receiver: Receiver<DedicatedWorkerControlMsg>, control_receiver: Receiver<DedicatedWorkerControlMsg>,
insecure_requests_policy: InsecureRequestsPolicy, insecure_requests_policy: InsecureRequestsPolicy,
) -> DomRoot<DedicatedWorkerGlobalScope> { ) -> DomRoot<DedicatedWorkerGlobalScope> {
let cx = runtime.cx();
let scope = Box::new(DedicatedWorkerGlobalScope::new_inherited( let scope = Box::new(DedicatedWorkerGlobalScope::new_inherited(
init, init,
worker_name, worker_name,
@ -344,12 +343,10 @@ impl DedicatedWorkerGlobalScope {
control_receiver, control_receiver,
insecure_requests_policy, insecure_requests_policy,
)); ));
unsafe { DedicatedWorkerGlobalScopeBinding::Wrap::<crate::DomTypeHolder>(
DedicatedWorkerGlobalScopeBinding::Wrap::<crate::DomTypeHolder>( GlobalScope::get_cx(),
SafeJSContext::from_ptr(cx), scope,
scope, )
)
}
} }
/// <https://html.spec.whatwg.org/multipage/#run-a-worker> /// <https://html.spec.whatwg.org/multipage/#run-a-worker>
@ -430,7 +427,6 @@ impl DedicatedWorkerGlobalScope {
Runtime::new_with_parent(Some(parent), Some(task_source)) Runtime::new_with_parent(Some(parent), Some(task_source))
}; };
let debugger_global = DebuggerGlobalScope::new( let debugger_global = DebuggerGlobalScope::new(
&runtime,
pipeline_id, pipeline_id,
init.to_devtools_sender.clone(), init.to_devtools_sender.clone(),
init.from_devtools_sender init.from_devtools_sender

View file

@ -73,7 +73,7 @@ impl DissimilarOriginWindow {
window_proxy: Dom::from_ref(window_proxy), window_proxy: Dom::from_ref(window_proxy),
location: Default::default(), location: Default::default(),
}); });
unsafe { DissimilarOriginWindowBinding::Wrap::<crate::DomTypeHolder>(cx, win) } DissimilarOriginWindowBinding::Wrap::<crate::DomTypeHolder>(cx, win)
} }
pub(crate) fn window_proxy(&self) -> DomRoot<WindowProxy> { pub(crate) fn window_proxy(&self) -> DomRoot<WindowProxy> {

View file

@ -19,8 +19,8 @@ use js::jsapi::{
JS_IsExceptionPending, JSAutoRealm, JSObject, NewArrayObject, Value, JS_IsExceptionPending, JSAutoRealm, JSObject, NewArrayObject, Value,
}; };
use js::jsval::{JSVal, ObjectValue, UndefinedValue}; use js::jsval::{JSVal, ObjectValue, UndefinedValue};
use js::rust::HandleValue;
use js::rust::wrappers::{Call, Construct1}; use js::rust::wrappers::{Call, Construct1};
use js::rust::{HandleValue, Runtime};
use net_traits::image_cache::ImageCache; use net_traits::image_cache::ImageCache;
use pixels::PixelFormat; use pixels::PixelFormat;
use script_traits::{DrawAPaintImageResult, PaintWorkletError, Painter}; use script_traits::{DrawAPaintImageResult, PaintWorkletError, Painter};
@ -43,12 +43,13 @@ use crate::dom::bindings::reflector::DomObject;
use crate::dom::bindings::root::{Dom, DomRoot}; use crate::dom::bindings::root::{Dom, DomRoot};
use crate::dom::bindings::str::DOMString; use crate::dom::bindings::str::DOMString;
use crate::dom::cssstylevalue::CSSStyleValue; use crate::dom::cssstylevalue::CSSStyleValue;
use crate::dom::globalscope::GlobalScope;
use crate::dom::paintrenderingcontext2d::PaintRenderingContext2D; use crate::dom::paintrenderingcontext2d::PaintRenderingContext2D;
use crate::dom::paintsize::PaintSize; use crate::dom::paintsize::PaintSize;
use crate::dom::stylepropertymapreadonly::StylePropertyMapReadOnly; use crate::dom::stylepropertymapreadonly::StylePropertyMapReadOnly;
use crate::dom::worklet::WorkletExecutor; use crate::dom::worklet::WorkletExecutor;
use crate::dom::workletglobalscope::{WorkletGlobalScope, WorkletGlobalScopeInit, WorkletTask}; use crate::dom::workletglobalscope::{WorkletGlobalScope, WorkletGlobalScopeInit, WorkletTask};
use crate::script_runtime::{CanGc, JSContext}; use crate::script_runtime::CanGc;
/// <https://drafts.css-houdini.org/css-paint-api/#paintworkletglobalscope> /// <https://drafts.css-houdini.org/css-paint-api/#paintworkletglobalscope>
#[dom_struct] #[dom_struct]
@ -86,7 +87,6 @@ pub(crate) struct PaintWorkletGlobalScope {
impl PaintWorkletGlobalScope { impl PaintWorkletGlobalScope {
#[allow(unsafe_code)] #[allow(unsafe_code)]
pub(crate) fn new( pub(crate) fn new(
runtime: &Runtime,
pipeline_id: PipelineId, pipeline_id: PipelineId,
base_url: ServoUrl, base_url: ServoUrl,
executor: WorkletExecutor, executor: WorkletExecutor,
@ -119,12 +119,7 @@ impl PaintWorkletGlobalScope {
missing_image_urls: Vec::new(), missing_image_urls: Vec::new(),
}), }),
}); });
unsafe { PaintWorkletGlobalScopeBinding::Wrap::<crate::DomTypeHolder>(GlobalScope::get_cx(), global)
PaintWorkletGlobalScopeBinding::Wrap::<crate::DomTypeHolder>(
JSContext::from_ptr(runtime.cx()),
global,
)
}
} }
pub(crate) fn image_cache(&self) -> Arc<dyn ImageCache> { pub(crate) fn image_cache(&self) -> Arc<dyn ImageCache> {

View file

@ -265,7 +265,6 @@ impl ServiceWorkerGlobalScope {
control_receiver: Receiver<ServiceWorkerControlMsg>, control_receiver: Receiver<ServiceWorkerControlMsg>,
closing: Arc<AtomicBool>, closing: Arc<AtomicBool>,
) -> DomRoot<ServiceWorkerGlobalScope> { ) -> DomRoot<ServiceWorkerGlobalScope> {
let cx = runtime.cx();
let scope = Box::new(ServiceWorkerGlobalScope::new_inherited( let scope = Box::new(ServiceWorkerGlobalScope::new_inherited(
init, init,
worker_url, worker_url,
@ -279,12 +278,7 @@ impl ServiceWorkerGlobalScope {
control_receiver, control_receiver,
closing, closing,
)); ));
unsafe { ServiceWorkerGlobalScopeBinding::Wrap::<crate::DomTypeHolder>(GlobalScope::get_cx(), scope)
ServiceWorkerGlobalScopeBinding::Wrap::<crate::DomTypeHolder>(
SafeJSContext::from_ptr(cx),
scope,
)
}
} }
/// <https://w3c.github.io/ServiceWorker/#run-service-worker-algorithm> /// <https://w3c.github.io/ServiceWorker/#run-service-worker-algorithm>

View file

@ -7,7 +7,6 @@ use std::collections::HashMap;
use base::id::PipelineId; use base::id::PipelineId;
use crossbeam_channel::Sender; use crossbeam_channel::Sender;
use dom_struct::dom_struct; use dom_struct::dom_struct;
use js::rust::Runtime;
use servo_url::ServoUrl; use servo_url::ServoUrl;
use crate::dom::bindings::cell::DomRefCell; use crate::dom::bindings::cell::DomRefCell;
@ -15,9 +14,9 @@ use crate::dom::bindings::codegen::Bindings::TestWorkletGlobalScopeBinding;
use crate::dom::bindings::codegen::Bindings::TestWorkletGlobalScopeBinding::TestWorkletGlobalScopeMethods; use crate::dom::bindings::codegen::Bindings::TestWorkletGlobalScopeBinding::TestWorkletGlobalScopeMethods;
use crate::dom::bindings::root::DomRoot; use crate::dom::bindings::root::DomRoot;
use crate::dom::bindings::str::DOMString; use crate::dom::bindings::str::DOMString;
use crate::dom::globalscope::GlobalScope;
use crate::dom::worklet::WorkletExecutor; use crate::dom::worklet::WorkletExecutor;
use crate::dom::workletglobalscope::{WorkletGlobalScope, WorkletGlobalScopeInit}; use crate::dom::workletglobalscope::{WorkletGlobalScope, WorkletGlobalScopeInit};
use crate::script_runtime::JSContext;
// check-tidy: no specs after this line // check-tidy: no specs after this line
@ -32,7 +31,6 @@ pub(crate) struct TestWorkletGlobalScope {
impl TestWorkletGlobalScope { impl TestWorkletGlobalScope {
#[allow(unsafe_code)] #[allow(unsafe_code)]
pub(crate) fn new( pub(crate) fn new(
runtime: &Runtime,
pipeline_id: PipelineId, pipeline_id: PipelineId,
base_url: ServoUrl, base_url: ServoUrl,
executor: WorkletExecutor, executor: WorkletExecutor,
@ -51,12 +49,7 @@ impl TestWorkletGlobalScope {
), ),
lookup_table: Default::default(), lookup_table: Default::default(),
}); });
unsafe { TestWorkletGlobalScopeBinding::Wrap::<crate::DomTypeHolder>(GlobalScope::get_cx(), global)
TestWorkletGlobalScopeBinding::Wrap::<crate::DomTypeHolder>(
JSContext::from_ptr(runtime.cx()),
global,
)
}
} }
pub(crate) fn perform_a_worklet_task(&self, task: TestWorkletTask) { pub(crate) fn perform_a_worklet_task(&self, task: TestWorkletTask) {

View file

@ -3202,9 +3202,7 @@ impl Window {
endpoints_list: Default::default(), endpoints_list: Default::default(),
}); });
unsafe { WindowBinding::Wrap::<crate::DomTypeHolder>(GlobalScope::get_cx(), win)
WindowBinding::Wrap::<crate::DomTypeHolder>(JSContext::from_ptr(runtime.cx()), win)
}
} }
pub(crate) fn pipeline_id(&self) -> PipelineId { pub(crate) fn pipeline_id(&self) -> PipelineId {

View file

@ -629,7 +629,6 @@ impl WorkletThread {
let executor = WorkletExecutor::new(worklet_id, self.primary_sender.clone()); let executor = WorkletExecutor::new(worklet_id, self.primary_sender.clone());
let result = WorkletGlobalScope::new( let result = WorkletGlobalScope::new(
global_type, global_type,
&self.runtime,
pipeline_id, pipeline_id,
base_url, base_url,
executor, executor,

View file

@ -13,7 +13,6 @@ use dom_struct::dom_struct;
use embedder_traits::JavaScriptEvaluationError; use embedder_traits::JavaScriptEvaluationError;
use ipc_channel::ipc::IpcSender; use ipc_channel::ipc::IpcSender;
use js::jsval::UndefinedValue; use js::jsval::UndefinedValue;
use js::rust::Runtime;
use net_traits::ResourceThreads; use net_traits::ResourceThreads;
use net_traits::image_cache::ImageCache; use net_traits::image_cache::ImageCache;
use profile_traits::{mem, time}; use profile_traits::{mem, time};
@ -56,7 +55,6 @@ impl WorkletGlobalScope {
/// Create a new heap-allocated `WorkletGlobalScope`. /// Create a new heap-allocated `WorkletGlobalScope`.
pub(crate) fn new( pub(crate) fn new(
scope_type: WorkletGlobalScopeType, scope_type: WorkletGlobalScopeType,
runtime: &Runtime,
pipeline_id: PipelineId, pipeline_id: PipelineId,
base_url: ServoUrl, base_url: ServoUrl,
executor: WorkletExecutor, executor: WorkletExecutor,
@ -65,14 +63,12 @@ impl WorkletGlobalScope {
let scope: DomRoot<WorkletGlobalScope> = match scope_type { let scope: DomRoot<WorkletGlobalScope> = match scope_type {
#[cfg(feature = "testbinding")] #[cfg(feature = "testbinding")]
WorkletGlobalScopeType::Test => DomRoot::upcast(TestWorkletGlobalScope::new( WorkletGlobalScopeType::Test => DomRoot::upcast(TestWorkletGlobalScope::new(
runtime,
pipeline_id, pipeline_id,
base_url, base_url,
executor, executor,
init, init,
)), )),
WorkletGlobalScopeType::Paint => DomRoot::upcast(PaintWorkletGlobalScope::new( WorkletGlobalScopeType::Paint => DomRoot::upcast(PaintWorkletGlobalScope::new(
runtime,
pipeline_id, pipeline_id,
base_url, base_url,
executor, executor,

View file

@ -939,7 +939,6 @@ impl ScriptThread {
pipeline_id, pipeline_id,
}; };
let debugger_global = DebuggerGlobalScope::new( let debugger_global = DebuggerGlobalScope::new(
&js_runtime.clone(),
PipelineId::new(), PipelineId::new(),
senders.devtools_server_sender.clone(), senders.devtools_server_sender.clone(),
senders.devtools_client_to_script_thread_sender.clone(), senders.devtools_client_to_script_thread_sender.clone(),

View file

@ -3312,7 +3312,7 @@ class CGWrapGlobalMethod(CGAbstractMethod):
Argument(f"Box<{descriptor.concreteType}>", 'object')] Argument(f"Box<{descriptor.concreteType}>", 'object')]
retval = f'DomRoot<{descriptor.concreteType}>' retval = f'DomRoot<{descriptor.concreteType}>'
CGAbstractMethod.__init__(self, descriptor, 'Wrap', retval, args, CGAbstractMethod.__init__(self, descriptor, 'Wrap', retval, args,
pub=True, unsafe=True, pub=True,
extra_decorators=['#[cfg_attr(crown, allow(crown::unrooted_must_root))]'], extra_decorators=['#[cfg_attr(crown, allow(crown::unrooted_must_root))]'],
templateArgs=['D: DomTypes']) templateArgs=['D: DomTypes'])
self.properties = properties self.properties = properties
@ -3328,35 +3328,37 @@ class CGWrapGlobalMethod(CGAbstractMethod):
membersStr = "\n".join(members) membersStr = "\n".join(members)
return CGGeneric(f""" return CGGeneric(f"""
let raw = Root::new(MaybeUnreflectedDom::from_box(object)); unsafe {{
let origin = (*raw.as_ptr()).upcast::<D::GlobalScope>().origin(); let raw = Root::new(MaybeUnreflectedDom::from_box(object));
let origin = (*raw.as_ptr()).upcast::<D::GlobalScope>().origin();
rooted!(in(*cx) let mut obj = ptr::null_mut::<JSObject>()); rooted!(in(*cx) let mut obj = ptr::null_mut::<JSObject>());
create_global_object::<D>( create_global_object::<D>(
cx, cx,
&Class.get().base, &Class.get().base,
raw.as_ptr() as *const libc::c_void, raw.as_ptr() as *const libc::c_void,
{TRACE_HOOK_NAME}::<D>, {TRACE_HOOK_NAME}::<D>,
obj.handle_mut(), obj.handle_mut(),
origin, origin,
{"true" if self.descriptor.useSystemCompartment else "false"}); {"true" if self.descriptor.useSystemCompartment else "false"});
assert!(!obj.is_null()); assert!(!obj.is_null());
let root = raw.reflect_with(obj.get()); let root = raw.reflect_with(obj.get());
let _ac = JSAutoRealm::new(*cx, obj.get()); let _ac = JSAutoRealm::new(*cx, obj.get());
rooted!(in(*cx) let mut canonical_proto = ptr::null_mut::<JSObject>()); rooted!(in(*cx) let mut canonical_proto = ptr::null_mut::<JSObject>());
GetProtoObject::<D>(cx, obj.handle(), canonical_proto.handle_mut()); GetProtoObject::<D>(cx, obj.handle(), canonical_proto.handle_mut());
assert!(JS_SetPrototype(*cx, obj.handle(), canonical_proto.handle())); assert!(JS_SetPrototype(*cx, obj.handle(), canonical_proto.handle()));
let mut immutable = false; let mut immutable = false;
assert!(JS_SetImmutablePrototype(*cx, obj.handle(), &mut immutable)); assert!(JS_SetImmutablePrototype(*cx, obj.handle(), &mut immutable));
assert!(immutable); assert!(immutable);
{membersStr} {membersStr}
{CopyLegacyUnforgeablePropertiesToInstance(self.descriptor)} {CopyLegacyUnforgeablePropertiesToInstance(self.descriptor)}
DomRoot::from_ref(&*root)\ DomRoot::from_ref(&*root)
}}
""") """)