mirror of
https://github.com/denoland/deno.git
synced 2024-11-29 16:30:56 -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",
|
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 {
|
itest!(https_import {
|
||||||
args: "run --quiet --reload --cert tls/RootCA.pem https_import.ts",
|
args: "run --quiet --reload --cert tls/RootCA.pem https_import.ts",
|
||||||
output: "https_import.ts.out",
|
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
|
/// Runs event loop to completion
|
||||||
///
|
///
|
||||||
/// This future resolves when:
|
/// This future resolves when:
|
||||||
|
@ -647,6 +658,8 @@ impl JsRuntime {
|
||||||
// Top level module
|
// Top level module
|
||||||
self.evaluate_pending_module();
|
self.evaluate_pending_module();
|
||||||
|
|
||||||
|
self.pump_v8_message_loop();
|
||||||
|
|
||||||
let state = state_rc.borrow();
|
let state = state_rc.borrow();
|
||||||
let module_map = module_map_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]
|
#[test]
|
||||||
fn test_core_js_stack_frame() {
|
fn test_core_js_stack_frame() {
|
||||||
let mut runtime = JsRuntime::new(RuntimeOptions::default());
|
let mut runtime = JsRuntime::new(RuntimeOptions::default());
|
||||||
|
|
Loading…
Reference in a new issue