E549 script: Implement jsglue trap for runJobs() by delan · Pull Request #38265 · servo/servo · GitHub
[go: up one dir, main page]

Skip to content

Conversation

delan
Copy link
Member
@delan delan commented Jul 25, 2025

in the SpiderMonkey Debugger API, hooks like onNewGlobalObject() use an AutoDebuggerJobQueueInterruption to switch to a new microtask queue and avoid clobbering the debuggee’s microtask queue. this in turn relies on JobQueue::runJobs(), which is not yet implemented in RustJobQueue.

this patch bumps mozjs to servo/mozjs#597, which implements runJobs() for RustJobQueue by calling into Servo’s MicrotaskQueue::checkpoint() via a new function in JobQueueTraps.

SpiderMonkey does not own external job queues, 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

@delan delan changed the title script: Implement jsglue trap for runJobs() script: Implement jsglue trap for runJobs() Jul 25, 2025
@delan delan changed the title script: Implement jsglue trap for runJobs() script: Implement jsglue trap for runJobs() Jul 25, 2025
Base automatically changed from mozjs-savejobqueue to main July 28, 2025 12:05
Co-authored-by: atbrakhi <atbrakhi@igalia.com>
Signed-off-by: Delan Azabani <dazabani@igalia.com>
@delan delan marked this pull request as ready for review July 28, 2025 13:21
@delan delan requested a review from gterzian as a code owner July 28, 2025 13:21
@delan delan requested review from jdm and removed request for gterzian July 28, 2025 13:21
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.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to be honest, i’m not yet sure how to plumb those values into here across the rust-C++-rust ffi boundaries. doing so may require further mozjs changes.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I understand correctly, I think the easiest thing here will be to add a method to ScriptThread like this:

fn perform_a_microtask_checkpoint_with_queue(queue: Rc<MicrotaskQueue>, can_gc: CanGc) {
    with_script_thread(|script_thread| script_thread.do_perform_a_microtask_checkpoint_with_queue(queue, can_gc))
}

and extract ScriptThread::perform_microtask_checkpoint into ScriptThread::do_perform_a_microtask_checkpoint_with_queue, and ScriptThread::perform_a_microtask_checkpoint can pass self.microtask_queue.

Copy link
7440 Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Granted, that will need adjusting when we support debugging worker globals. Then we'll need to find a way to invoke https://doc.servo.org/script/dom/globalscope/struct.GlobalScope.html#method.perform_a_microtask_checkpoint instead.

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.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I understand correctly, I think the easiest thing here will be to add a method to ScriptThread like this:

fn perform_a_microtask_checkpoint_with_queue(queue: Rc<MicrotaskQueue>, can_gc: CanGc) {
    with_script_thread(|script_thread| script_thread.do_perform_a_microtask_checkpoint_with_queue(queue, can_gc))
}

and extract ScriptThread::perform_microtask_checkpoint into ScriptThread::do_perform_a_microtask_checkpoint_with_queue, and ScriptThread::perform_a_microtask_checkpoint can pass self.microtask_queue.

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.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Granted, that will need adjusting when we support debugging worker globals. Then we'll need to find a way to invoke https://doc.servo.org/script/dom/globalscope/struct.GlobalScope.html#method.perform_a_microtask_checkpoint instead.

@jdm
Copy link
Member
jdm commented Jul 31, 2025

For future reference: please don't merge breaking mozjs changes until the corresponding Servo PR is approved, because it makes it much harder to test other changes in the meantime.

@delan
Copy link
Member Author
delan commented Jul 31, 2025

For future reference: please don't merge breaking mozjs changes until the corresponding Servo PR is approved, because it makes it much harder to test other changes in the meantime.

sorry, should have thought of that. won’t happen again :)

@delan delan added this pull request to the merge queue Jul 31, 2025
Merged via the queue into main with commit 8194aa7 Jul 31, 2025
22 checks passed
@delan delan deleted the mozjs-runjobs branch July 31, 2025 03:15
minghuaw pushed a commit to minghuaw/servo that referenced this pull request Aug 1, 2025
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 (servo#37667),
where it will undergo automated tests

Signed-off-by: Delan Azabani <dazabani@igalia.com>
Co-authored-by: atbrakhi <atbrakhi@igalia.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants
0