mirror of
https://github.com/denoland/deno.git
synced 2024-12-24 08:09:08 -05:00
fix(core): handle exception from Wasm termination (#15014)
Co-authored-by: Augusto Lenz <augustollenz@gmail.com>
This commit is contained in:
parent
f92b2dc053
commit
68d50f964a
1 changed files with 58 additions and 3 deletions
|
@ -785,7 +785,7 @@ impl JsRuntime {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pump_v8_message_loop(&mut self) {
|
fn pump_v8_message_loop(&mut self) -> Result<(), Error> {
|
||||||
let scope = &mut self.handle_scope();
|
let scope = &mut self.handle_scope();
|
||||||
while v8::Platform::pump_message_loop(
|
while v8::Platform::pump_message_loop(
|
||||||
&v8::V8::get_current_platform(),
|
&v8::V8::get_current_platform(),
|
||||||
|
@ -795,7 +795,12 @@ impl JsRuntime {
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
scope.perform_microtask_checkpoint();
|
let tc_scope = &mut v8::TryCatch::new(scope);
|
||||||
|
tc_scope.perform_microtask_checkpoint();
|
||||||
|
match tc_scope.exception() {
|
||||||
|
None => Ok(()),
|
||||||
|
Some(exception) => exception_to_err_result(tc_scope, exception, false),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn poll_value(
|
pub fn poll_value(
|
||||||
|
@ -877,7 +882,7 @@ impl JsRuntime {
|
||||||
state.waker.register(cx.waker());
|
state.waker.register(cx.waker());
|
||||||
}
|
}
|
||||||
|
|
||||||
self.pump_v8_message_loop();
|
self.pump_v8_message_loop()?;
|
||||||
|
|
||||||
// Ops
|
// Ops
|
||||||
{
|
{
|
||||||
|
@ -2273,6 +2278,56 @@ pub mod tests {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn terminate_execution_webassembly() {
|
||||||
|
let (mut isolate, _dispatch_count) = setup(Mode::Async);
|
||||||
|
let v8_isolate_handle = isolate.v8_isolate().thread_safe_handle();
|
||||||
|
|
||||||
|
let terminator_thread = std::thread::spawn(move || {
|
||||||
|
// allow deno to boot and run
|
||||||
|
std::thread::sleep(std::time::Duration::from_millis(1000));
|
||||||
|
|
||||||
|
// terminate execution
|
||||||
|
let ok = v8_isolate_handle.terminate_execution();
|
||||||
|
assert!(ok);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Run an infinite loop in Webassemby code, which should be terminated.
|
||||||
|
isolate.execute_script("infinite_wasm_loop.js",
|
||||||
|
r#"
|
||||||
|
(async () => {
|
||||||
|
console.log("Begin");
|
||||||
|
const wasmCode = new Uint8Array([
|
||||||
|
0, 97, 115, 109, 1, 0, 0, 0, 1, 4, 1,
|
||||||
|
96, 0, 0, 3, 2, 1, 0, 7, 17, 1, 13,
|
||||||
|
105, 110, 102, 105, 110, 105, 116, 101, 95, 108, 111,
|
||||||
|
111, 112, 0, 0, 10, 9, 1, 7, 0, 3, 64,
|
||||||
|
12, 0, 11, 11,
|
||||||
|
]);
|
||||||
|
const wasmModule = await WebAssembly.compile(wasmCode);
|
||||||
|
const wasmInstance = new WebAssembly.Instance(wasmModule);
|
||||||
|
wasmInstance.exports.infinite_loop();
|
||||||
|
})();
|
||||||
|
"#).expect("wasm infinite loop failed");
|
||||||
|
match futures::executor::block_on(isolate.run_event_loop(false)) {
|
||||||
|
Ok(_) => panic!("execution should be terminated"),
|
||||||
|
Err(e) => {
|
||||||
|
assert_eq!(e.to_string(), "Uncaught Error: execution terminated")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Cancel the execution-terminating exception in order to allow script
|
||||||
|
// execution again.
|
||||||
|
let ok = isolate.v8_isolate().cancel_terminate_execution();
|
||||||
|
assert!(ok);
|
||||||
|
|
||||||
|
// Verify that the isolate usable again.
|
||||||
|
isolate
|
||||||
|
.execute_script("simple.js", "1 + 1")
|
||||||
|
.expect("execution should be possible again");
|
||||||
|
|
||||||
|
terminator_thread.join().unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn terminate_execution() {
|
fn terminate_execution() {
|
||||||
let (mut isolate, _dispatch_count) = setup(Mode::Async);
|
let (mut isolate, _dispatch_count) = setup(Mode::Async);
|
||||||
|
|
Loading…
Reference in a new issue