From 8194aa7c1ede7751fd6558983f314a564005f30b Mon Sep 17 00:00:00 2001 From: shuppy Date: Thu, 31 Jul 2025 10:46:37 +0800 Subject: [PATCH] script: Implement jsglue trap for runJobs() (#38265) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit in the [SpiderMonkey Debugger API](https://firefox-source-docs.mozilla.org/js/Debugger/), hooks like [onNewGlobalObject()](https://firefox-source-docs.mozilla.org/js/Debugger/Debugger.html#onnewglobalobject-global) use an AutoDebuggerJobQueueInterruption to [switch to a new microtask queue](https://github.com/servo/mozjs/blob/b14aebff23ac4d5b0652060ef949334bda08b22f/mozjs-sys/mozjs/js/src/debugger/Debugger.cpp#L2834-L2841) and avoid clobbering the debuggee’s microtask queue. this in turn relies on JobQueue::runJobs(), which is [not yet implemented in RustJobQueue](https://github.com/servo/mozjs/blob/b14aebff23ac4d5b0652060ef949334bda08b22f/mozjs-sys/src/jsglue.cpp#L76-L78). this patch bumps mozjs to servo/mozjs#597, which implements [runJobs()](https://github.com/servo/mozjs/blob/b14aebff23ac4d5b0652060ef949334bda08b22f/mozjs-sys/mozjs/js/public/Promise.h#L61-L76) for RustJobQueue by calling into Servo’s MicrotaskQueue::checkpoint() via a new function in JobQueueTraps. SpiderMonkey [does not own external job queues](https://github.com/servo/mozjs/blob/b14aebff23ac4d5b0652060ef949334bda08b22f/mozjs-sys/mozjs/js/public/Promise.h#L117-L123), so the lifetime of these queues is managed in Servo, where they are stored in a Vec-based stack. stack-like behaviour is adequate for SpiderMonkey’s save and restore patterns, as far as we can tell, but we’ve added an assertion just in case. Testing: manually tested working in devtools debugger patch (#37667), where it will undergo automated tests Signed-off-by: Delan Azabani Co-authored-by: atbrakhi --- Cargo.lock | 6 +++--- components/script/script_runtime.rs | 12 ++++++++++++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ec40b8813ba..ff09d540e3c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5240,7 +5240,7 @@ dependencies = [ [[package]] name = "mozjs" version = "0.14.1" -source = "git+https://github.com/servo/mozjs#b23161580b082e1ccfa3273d94f43f6168aedc3d" +source = "git+https://github.com/servo/mozjs#4035b0c4e9e2df5cacc68c4b71e7375a48605902" dependencies = [ "bindgen 0.71.1", "cc", @@ -5251,8 +5251,8 @@ dependencies = [ [[package]] name = "mozjs_sys" -version = "0.128.13-2" -source = "git+https://github.com/servo/mozjs#b23161580b082e1ccfa3273d94f43f6168aedc3d" +version = "0.128.13-3" +source = "git+https://github.com/servo/mozjs#4035b0c4e9e2df5cacc68c4b71e7375a48605902" dependencies = [ "bindgen 0.71.1", "cc", diff --git a/components/script/script_runtime.rs b/components/script/script_runtime.rs index c054ae6afef..283aa9329f1 100644 --- a/components/script/script_runtime.rs +++ b/components/script/script_runtime.rs @@ -87,6 +87,7 @@ use crate::task_source::SendableTaskSource; static JOB_QUEUE_TRAPS: JobQueueTraps = JobQueueTraps { getIncumbentGlobal: Some(get_incumbent_global), enqueuePromiseJob: Some(enqueue_promise_job), + runJobs: Some(run_jobs), empty: Some(empty), pushNewInterruptQueue: Some(push_new_interrupt_queue), popInterruptQueue: Some(pop_interrupt_queue), @@ -241,6 +242,17 @@ unsafe extern "C" fn get_incumbent_global(_: *const c_void, _: *mut RawJSContext result } +#[allow(unsafe_code)] +unsafe extern "C" fn run_jobs(microtask_queue: *const c_void, cx: *mut RawJSContext) { + let cx = JSContext::from_ptr(cx); + wrap_panic(&mut || { + let microtask_queue = &*(microtask_queue as *const MicrotaskQueue); + // TODO: run Promise- and User-variant Microtasks, and do #notify-about-rejected-promises. + // Those will require real `target_provider` and `globalscopes` values. + microtask_queue.checkpoint(cx, |_| None, vec![], CanGc::note()); + }); +} + #[allow(unsafe_code)] unsafe extern "C" fn empty(extra: *const c_void) -> bool { let mut result = false;