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();
|
||||
while v8::Platform::pump_message_loop(
|
||||
&v8::V8::get_current_platform(),
|
||||
|
@ -795,7 +795,12 @@ impl JsRuntime {
|
|||
// 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(
|
||||
|
@ -877,7 +882,7 @@ impl JsRuntime {
|
|||
state.waker.register(cx.waker());
|
||||
}
|
||||
|
||||
self.pump_v8_message_loop();
|
||||
self.pump_v8_message_loop()?;
|
||||
|
||||
// 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]
|
||||
fn terminate_execution() {
|
||||
let (mut isolate, _dispatch_count) = setup(Mode::Async);
|
||||
|
|
Loading…
Reference in a new issue