diff options
author | Bartek IwaĆczuk <biwanczuk@gmail.com> | 2021-07-02 10:46:37 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-07-02 10:46:37 +0200 |
commit | 513f921219d32fe5deea264f6604b54b24d81d8f (patch) | |
tree | 17344527b40bdfcaaed0e55569faa0b4abffab61 /core/runtime.rs | |
parent | 5648b22fe102c212a653580d2e190283c057cc20 (diff) |
feat(core): pump V8 message loop on event loop tick (#11221)
This commit adds support for Atomics and FinalizationRegistry by integrating
V8's message loop into "JsRuntime::poll_event_loop".
Diffstat (limited to 'core/runtime.rs')
-rw-r--r-- | core/runtime.rs | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/core/runtime.rs b/core/runtime.rs index e734e0018..c2dc09f82 100644 --- a/core/runtime.rs +++ b/core/runtime.rs @@ -591,6 +591,17 @@ impl JsRuntime { } } + fn pump_v8_message_loop(&mut self) { + let scope = &mut self.handle_scope(); + while v8::Platform::pump_message_loop( + &v8::V8::get_current_platform(), + scope, + false, // don't block if there are no tasks + ) { + // do nothing + } + } + /// Runs event loop to completion /// /// This future resolves when: @@ -647,6 +658,8 @@ impl JsRuntime { // Top level module self.evaluate_pending_module(); + self.pump_v8_message_loop(); + let state = state_rc.borrow(); let module_map = module_map_rc.borrow(); @@ -1955,6 +1968,56 @@ main(); } #[test] + fn test_pump_message_loop() { + run_in_task(|cx| { + let mut runtime = JsRuntime::new(RuntimeOptions::default()); + runtime + .execute_script( + "pump_message_loop.js", + r#" +function assertEquals(a, b) { + if (a === b) return; + throw a + " does not equal " + b; +} +const sab = new SharedArrayBuffer(16); +const i32a = new Int32Array(sab); +globalThis.resolved = false; + +(function() { + const result = Atomics.waitAsync(i32a, 0, 0); + result.value.then( + (value) => { assertEquals("ok", value); globalThis.resolved = true; }, + () => { assertUnreachable(); + }); +})(); + +const notify_return_value = Atomics.notify(i32a, 0, 1); +assertEquals(1, notify_return_value); +"#, + ) + .unwrap(); + + match runtime.poll_event_loop(cx, false) { + Poll::Ready(Ok(())) => {} + _ => panic!(), + }; + + // noop script, will resolve promise from first script + runtime + .execute_script("pump_message_loop2.js", r#"assertEquals(1, 1);"#) + .unwrap(); + + // check that promise from `Atomics.waitAsync` has been resolved + runtime + .execute_script( + "pump_message_loop3.js", + r#"assertEquals(globalThis.resolved, true);"#, + ) + .unwrap(); + }) + } + + #[test] fn test_core_js_stack_frame() { let mut runtime = JsRuntime::new(RuntimeOptions::default()); // Call non-existent op so we get error from `core.js` |