mirror of
https://github.com/denoland/deno.git
synced 2024-11-25 15:29:32 -05:00
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".
This commit is contained in:
parent
5648b22fe1
commit
513f921219
4 changed files with 90 additions and 0 deletions
20
cli/tests/finalization_registry.js
Normal file
20
cli/tests/finalization_registry.js
Normal file
|
@ -0,0 +1,20 @@
|
|||
// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.
|
||||
"use strict";
|
||||
|
||||
function assertEquals(a, b) {
|
||||
if (a === b) return;
|
||||
throw a + " does not equal " + b;
|
||||
}
|
||||
|
||||
const registry = new FinalizationRegistry((value) => {
|
||||
assertEquals(value, "called!");
|
||||
Deno.core.print("FinalizationRegistry called!\n");
|
||||
});
|
||||
|
||||
(function () {
|
||||
let x = {};
|
||||
registry.register(x, "called!");
|
||||
x = null;
|
||||
})();
|
||||
|
||||
gc();
|
1
cli/tests/finalization_registry.js.out
Normal file
1
cli/tests/finalization_registry.js.out
Normal file
|
@ -0,0 +1 @@
|
|||
FinalizationRegistry called!
|
|
@ -660,6 +660,12 @@ itest!(heapstats {
|
|||
output: "heapstats.js.out",
|
||||
});
|
||||
|
||||
itest!(finalization_registry {
|
||||
args:
|
||||
"run --quiet --unstable --v8-flags=--expose-gc finalization_registry.js",
|
||||
output: "finalization_registry.js.out",
|
||||
});
|
||||
|
||||
itest!(https_import {
|
||||
args: "run --quiet --reload --cert tls/RootCA.pem https_import.ts",
|
||||
output: "https_import.ts.out",
|
||||
|
|
|
@ -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());
|
||||
|
|
Loading…
Reference in a new issue