From 12d28dffc6c8d08e6620751e55d8a382c66443a2 Mon Sep 17 00:00:00 2001 From: Andreu Botella Date: Tue, 22 Mar 2022 11:33:29 +0100 Subject: fix(fetch): Fix uncaught rejection panic with `WebAssembly.instantiateStreaming` (#13925) When an exception is thrown during the processing of streaming WebAssembly, `op_wasm_streaming_abort` is called. This op calls into V8, which synchronously rejects the promise and calls into the promise rejection handler, if applicable. But calling an op borrows the isolate's `JsRuntimeState` for the duration of the op, which means it is borrowed when V8 calls into `promise_reject_callback`, which tries to borrow it again, panicking. This change changes `op_wasm_streaming_abort` from an op to a binding (`Deno.core.abortWasmStreaming`). Although that binding must borrow the `JsRuntimeState` in order to access the `WasmStreamingResource` stored in the `OpTable`, it also takes ownership of that `WasmStreamingResource` instance, which means it can drop any borrows of the `JsRuntimeState` before calling into V8. --- core/ops_builtin.rs | 23 ----------------------- 1 file changed, 23 deletions(-) (limited to 'core/ops_builtin.rs') diff --git a/core/ops_builtin.rs b/core/ops_builtin.rs index 23497ba36..4b566e916 100644 --- a/core/ops_builtin.rs +++ b/core/ops_builtin.rs @@ -26,7 +26,6 @@ pub(crate) fn init_builtins() -> Extension { op_print::decl(), op_resources::decl(), op_wasm_streaming_feed::decl(), - op_wasm_streaming_abort::decl(), op_wasm_streaming_set_url::decl(), op_void_sync::decl(), op_void_async::decl(), @@ -142,28 +141,6 @@ pub fn op_wasm_streaming_feed( Ok(()) } -/// Abort a WasmStreamingResource. -#[op] -pub fn op_wasm_streaming_abort( - state: &mut OpState, - rid: ResourceId, - exception: serde_v8::Value, -) -> Result<(), Error> { - let wasm_streaming = - state.resource_table.take::(rid)?; - - // At this point there are no clones of Rc on the - // resource table, and no one should own a reference because we're never - // cloning them. So we can be sure `wasm_streaming` is the only reference. - if let Ok(wsr) = Rc::try_unwrap(wasm_streaming) { - wsr.0.into_inner().abort(Some(exception.v8_value)); - } else { - panic!("Couldn't consume WasmStreamingResource."); - } - - Ok(()) -} - #[op] pub fn op_wasm_streaming_set_url( state: &mut OpState, -- cgit v1.2.3