From 23c166fcf1ef1773d44db367d6185fb388307e18 Mon Sep 17 00:00:00 2001 From: Delan Azabani Date: Fri, 18 Jul 2025 21:51:13 +0800 Subject: [PATCH] Run a script in a new DebuggerGlobalScope Signed-off-by: Delan Azabani Co-authored-by: atbrakhi --- components/script/dom/debuggerglobalscope.rs | 88 +++++++++++++++++++ components/script/dom/globalscope.rs | 8 +- components/script/dom/mod.rs | 1 + components/script/script_thread.rs | 18 ++++ .../webidls/DebuggerGlobalScope.webidl | 7 ++ .../webidls/EventTarget.webidl | 2 +- .../webidls/GlobalScope.webidl | 2 +- 7 files changed, 123 insertions(+), 3 deletions(-) create mode 100644 components/script/dom/debuggerglobalscope.rs create mode 100644 components/script_bindings/webidls/DebuggerGlobalScope.webidl diff --git a/components/script/dom/debuggerglobalscope.rs b/components/script/dom/debuggerglobalscope.rs new file mode 100644 index 00000000000..9075060aab1 --- /dev/null +++ b/components/script/dom/debuggerglobalscope.rs @@ -0,0 +1,88 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +use std::sync::Arc; + +use base::id::PipelineId; +use constellation_traits::ScriptToConstellationChan; +use dom_struct::dom_struct; +use js::jsval::UndefinedValue; +use js::rust::Runtime; +use net_traits::ResourceThreads; +use profile_traits::{mem, time}; +use servo_url::{ImmutableOrigin, MutableOrigin, ServoUrl}; + +use crate::dom::bindings::codegen::Bindings::DebuggerGlobalScopeBinding; +use crate::dom::bindings::root::DomRoot; +use crate::dom::globalscope::GlobalScope; +#[cfg(feature = "testbinding")] +#[cfg(feature = "webgpu")] +use crate::dom::webgpu::identityhub::IdentityHub; +use crate::script_module::ScriptFetchOptions; +use crate::script_runtime::{CanGc, JSContext}; + +#[dom_struct] +/// Global scope for interacting with the devtools Debugger API. +/// +/// +pub(crate) struct DebuggerGlobalScope { + global_scope: GlobalScope, +} + +impl DebuggerGlobalScope { + /// Create a new heap-allocated `DebuggerGlobalScope`. + #[allow(unsafe_code)] + pub(crate) fn new( + runtime: &Runtime, + mem_profiler_chan: mem::ProfilerChan, + time_profiler_chan: time::ProfilerChan, + script_to_constellation_chan: ScriptToConstellationChan, + resource_threads: ResourceThreads, + #[cfg(feature = "webgpu")] gpu_id_hub: Arc, + ) -> DomRoot { + let global = Box::new(Self { + global_scope: GlobalScope::new_inherited( + PipelineId::new(), // ??? or TEST_PIPELINE_ID, but that seems worse + None, // ? if needed, see script_thread:745 + mem_profiler_chan, + time_profiler_chan, + script_to_constellation_chan, // wrap it in a ScriptToConstellationChan + resource_threads, + MutableOrigin::new(ImmutableOrigin::new_opaque()), + ServoUrl::parse_with_base(None, "about:internal/debugger") + .expect("Guaranteed by argument"), // ??? + None, + Default::default(), + gpu_id_hub, + None, // ? if needed, see script_thread:745 + false, + ), + }); + + unsafe { + DebuggerGlobalScopeBinding::Wrap::( + JSContext::from_ptr(runtime.cx()), + global, + ) + } + } + + /// 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: &str, can_gc: CanGc) -> bool { + debug!("Evaluating Dom in a worklet."); + rooted!(in (*GlobalScope::get_cx()) let mut rval = UndefinedValue()); + self.global_scope.evaluate_js_on_global_with_result( + script, + rval.handle_mut(), + ScriptFetchOptions::default_classic_script(&self.global_scope), + self.global_scope.api_base_url(), + can_gc, + ) + } +} diff --git a/components/script/dom/globalscope.rs b/components/script/dom/globalscope.rs index 01ff74c7c49..b2ab674e29d 100644 --- a/components/script/dom/globalscope.rs +++ b/components/script/dom/globalscope.rs @@ -114,7 +114,7 @@ use crate::dom::reportingobserver::ReportingObserver; use crate::dom::serviceworker::ServiceWorker; use crate::dom::serviceworkerregistration::ServiceWorkerRegistration; use crate::dom::trustedtypepolicyfactory::TrustedTypePolicyFactory; -use crate::dom::types::MessageEvent; +use crate::dom::types::{DebuggerGlobalScope, MessageEvent}; use crate::dom::underlyingsourcecontainer::UnderlyingSourceType; #[cfg(feature = "webgpu")] use crate::dom::webgpu::gpudevice::GPUDevice; @@ -2530,6 +2530,9 @@ impl GlobalScope { // https://drafts.css-houdini.org/worklets/#script-settings-for-worklets return worklet.base_url(); } + if let Some(_debugger_global) = self.downcast::() { + return self.creation_url.clone(); + } unreachable!(); } @@ -2545,6 +2548,9 @@ impl GlobalScope { // TODO: is this the right URL to return? return worklet.base_url(); } + if let Some(_debugger_global) = self.downcast::() { + return self.creation_url.clone(); + } unreachable!(); } diff --git a/components/script/dom/mod.rs b/components/script/dom/mod.rs index 8190a0b1dda..3dabb64c11a 100644 --- a/components/script/dom/mod.rs +++ b/components/script/dom/mod.rs @@ -289,6 +289,7 @@ pub(crate) mod customevent; pub(crate) mod datatransfer; pub(crate) mod datatransferitem; pub(crate) mod datatransferitemlist; +pub(crate) mod debuggerglobalscope; pub(crate) mod dedicatedworkerglobalscope; pub(crate) mod defaultteereadrequest; pub(crate) mod defaultteeunderlyingsource; diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs index 18bf170f1f3..939303ebeb8 100644 --- a/components/script/script_thread.rs +++ b/components/script/script_thread.rs @@ -133,6 +133,7 @@ use crate::dom::htmlslotelement::HTMLSlotElement; use crate::dom::mutationobserver::MutationObserver; use crate::dom::node::{Node, NodeTraits, ShadowIncluding}; use crate::dom::servoparser::{ParserContext, ServoParser}; +use crate::dom::types::DebuggerGlobalScope; #[cfg(feature = "webgpu")] use crate::dom::webgpu::identityhub::IdentityHub; use crate::dom::window::Window; @@ -1004,6 +1005,23 @@ impl ScriptThread { /// messages on its port. pub(crate) fn start(&self, can_gc: CanGc) { debug!("Starting script thread."); + + let pipeline_id = PipelineId::new(); + let script_to_constellation_chan = ScriptToConstellationChan { + sender: self.senders.pipeline_to_constellation_sender.clone(), + pipeline_id, + }; + let debugger_global = DebuggerGlobalScope::new( + &self.js_runtime, + self.senders.memory_profiler_sender.clone(), + self.senders.time_profiler_sender.clone(), + script_to_constellation_chan, + self.resource_threads.clone(), + #[cfg(feature = "webgpu")] + self.gpu_id_hub.clone(), + ); + debugger_global.evaluate_js("console.log('hello world')", can_gc); + while self.handle_msgs(can_gc) { // Go on... debug!("Running script thread."); diff --git a/components/script_bindings/webidls/DebuggerGlobalScope.webidl b/components/script_bindings/webidls/DebuggerGlobalScope.webidl new file mode 100644 index 00000000000..9035f7a40a2 --- /dev/null +++ b/components/script_bindings/webidls/DebuggerGlobalScope.webidl @@ -0,0 +1,7 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +[Global=DebuggerGlobalScope, Exposed=DebuggerGlobalScope] +interface DebuggerGlobalScope: GlobalScope { +}; diff --git a/components/script_bindings/webidls/EventTarget.webidl b/components/script_bindings/webidls/EventTarget.webidl index a8a63cc2b32..411fb962d32 100644 --- a/components/script_bindings/webidls/EventTarget.webidl +++ b/components/script_bindings/webidls/EventTarget.webidl @@ -5,7 +5,7 @@ * https://dom.spec.whatwg.org/#interface-eventtarget */ -[Exposed=(Window,Worker,Worklet,DissimilarOriginWindow)] +[Exposed=(Window,Worker,Worklet,DissimilarOriginWindow,DebuggerGlobalScope)] interface EventTarget { [Throws] constructor(); undefined addEventListener( diff --git a/components/script_bindings/webidls/GlobalScope.webidl b/components/script_bindings/webidls/GlobalScope.webidl index 57206d13e6a..dfa44738781 100644 --- a/components/script_bindings/webidls/GlobalScope.webidl +++ b/components/script_bindings/webidls/GlobalScope.webidl @@ -5,6 +5,6 @@ // This interface is entirely internal to Servo, and should not be accessible to // web pages. -[Exposed=(Window,Worker,Worklet,DissimilarOriginWindow), +[Exposed=(Window,Worker,Worklet,DissimilarOriginWindow,DebuggerGlobalScope), Inline] interface GlobalScope : EventTarget {};