From 513f921219d32fe5deea264f6604b54b24d81d8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Fri, 2 Jul 2021 10:46:37 +0200 Subject: 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". --- core/runtime.rs | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) (limited to 'core') 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(); @@ -1954,6 +1967,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()); -- cgit v1.2.3