diff options
author | Andreu Botella <andreu@andreubotella.com> | 2022-03-22 11:33:29 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-03-22 11:33:29 +0100 |
commit | 12d28dffc6c8d08e6620751e55d8a382c66443a2 (patch) | |
tree | 9ad9058ec93c39d5b8015d80cd88d1fa4abf14bc /core/ops_builtin.rs | |
parent | c5792d6d1dcd2fe60e59e836015eac4f05a76039 (diff) |
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.
Diffstat (limited to 'core/ops_builtin.rs')
-rw-r--r-- | core/ops_builtin.rs | 23 |
1 files changed, 0 insertions, 23 deletions
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::<WasmStreamingResource>(rid)?; - - // At this point there are no clones of Rc<WasmStreamingResource> 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, |