summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cli/tests/finalization_registry.js20
-rw-r--r--cli/tests/finalization_registry.js.out1
-rw-r--r--cli/tests/integration/run_tests.rs6
-rw-r--r--core/runtime.rs63
4 files changed, 90 insertions, 0 deletions
diff --git a/cli/tests/finalization_registry.js b/cli/tests/finalization_registry.js
new file mode 100644
index 000000000..f75979358
--- /dev/null
+++ b/cli/tests/finalization_registry.js
@@ -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();
diff --git a/cli/tests/finalization_registry.js.out b/cli/tests/finalization_registry.js.out
new file mode 100644
index 000000000..fee61413a
--- /dev/null
+++ b/cli/tests/finalization_registry.js.out
@@ -0,0 +1 @@
+FinalizationRegistry called!
diff --git a/cli/tests/integration/run_tests.rs b/cli/tests/integration/run_tests.rs
index 964d2dd7c..025ee07e1 100644
--- a/cli/tests/integration/run_tests.rs
+++ b/cli/tests/integration/run_tests.rs
@@ -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",
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`