summaryrefslogtreecommitdiff
path: root/core/runtime.rs
diff options
context:
space:
mode:
authorBartek IwaƄczuk <biwanczuk@gmail.com>2021-07-02 10:46:37 +0200
committerGitHub <noreply@github.com>2021-07-02 10:46:37 +0200
commit513f921219d32fe5deea264f6604b54b24d81d8f (patch)
tree17344527b40bdfcaaed0e55569faa0b4abffab61 /core/runtime.rs
parent5648b22fe102c212a653580d2e190283c057cc20 (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.rs63
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`