diff --git a/crates/backend/src/codegen.rs b/crates/backend/src/codegen.rs index fc81c1bf..b6eae8c1 100644 --- a/crates/backend/src/codegen.rs +++ b/crates/backend/src/codegen.rs @@ -974,28 +974,12 @@ impl TryToTokens for ast::ImportFunction { } let mut exceptional_ret = quote!(); - let exn_data = if self.catch { - let exn_data = Ident::new("exn_data", Span::call_site()); - let exn_data_ptr = Ident::new("exn_data_ptr", Span::call_site()); - abi_argument_names.push(exn_data_ptr.clone()); - abi_arguments.push(quote! { #exn_data_ptr: *mut u32 }); + if self.catch { convert_ret = quote! { Ok(#convert_ret) }; exceptional_ret = quote! { - if #exn_data[0] == 1 { - return Err( - < - wasm_bindgen::JsValue as wasm_bindgen::convert::FromWasmAbi - >::from_abi(#exn_data[1], &mut wasm_bindgen::convert::GlobalStack::new()) - ) - } + wasm_bindgen::__rt::take_last_exception()?; }; - quote! { - let mut #exn_data = [0; 2]; - let #exn_data_ptr = #exn_data.as_mut_ptr(); - } - } else { - quote!() - }; + } let rust_name = &self.rust_name; let import_name = &self.shim; @@ -1055,7 +1039,6 @@ impl TryToTokens for ast::ImportFunction { #extern_fn unsafe { - #exn_data let #ret_ident = { let mut __stack = wasm_bindgen::convert::GlobalStack::new(); #(#arg_conversions)* diff --git a/crates/cli-support/src/js/mod.rs b/crates/cli-support/src/js/mod.rs index dad09461..94793302 100644 --- a/crates/cli-support/src/js/mod.rs +++ b/crates/cli-support/src/js/mod.rs @@ -1419,16 +1419,14 @@ impl<'a> Context<'a> { if !self.should_write_global("handle_error") { return Ok(()); } - self.expose_uint32_memory(); + self.require_internal_export("__wbindgen_exn_store")?; if self.config.anyref { self.expose_add_to_anyref_table()?; self.global( " - function handleError(exnptr, e) { + function handleError(e) { const idx = addToAnyrefTable(e); - const view = getUint32Memory(); - view[exnptr / 4] = 1; - view[exnptr / 4 + 1] = idx; + wasm.__wbindgen_exn_store(idx); } ", ); @@ -1436,10 +1434,8 @@ impl<'a> Context<'a> { self.expose_add_heap_object(); self.global( " - function handleError(exnptr, e) { - const view = getUint32Memory(); - view[exnptr / 4] = 1; - view[exnptr / 4 + 1] = addHeapObject(e); + function handleError(e) { + wasm.__wbindgen_exn_store(addHeapObject(e)); } ", ); @@ -2115,7 +2111,7 @@ impl<'a> Context<'a> { fn export_function_table(&mut self) -> Result<(), Error> { if !self.should_write_global("wbg-function-table") { - return Ok(()) + return Ok(()); } let id = match self.module.tables.main_function_table()? { Some(id) => id, @@ -2192,7 +2188,7 @@ impl ExportedClass { field: &str, js: &str, prefix: &str, - ret_ty: &str + ret_ty: &str, ) -> &mut bool { self.contents.push_str(docs); self.contents.push_str(prefix); @@ -2215,7 +2211,8 @@ impl ExportedClass { /// generated output is deterministic and we do so by ensuring that iteration of /// hash maps is consistently sorted. fn sorted_iter<K, V>(map: &HashMap<K, V>) -> impl Iterator<Item = (&K, &V)> - where K: Ord, +where + K: Ord, { let mut pairs = map.iter().collect::<Vec<_>>(); pairs.sort_by_key(|(k, _)| *k); diff --git a/crates/cli-support/src/js/rust2js.rs b/crates/cli-support/src/js/rust2js.rs index b2d39ada..097f3413 100644 --- a/crates/cli-support/src/js/rust2js.rs +++ b/crates/cli-support/src/js/rust2js.rs @@ -928,7 +928,7 @@ impl<'a, 'b> Rust2Js<'a, 'b> { try {{\n\ {} }} catch (e) {{\n\ - handleError(exnptr, e);\n\ + handleError(e);\n\ }}\ ", &invoc @@ -973,12 +973,6 @@ impl<'a, 'b> Rust2Js<'a, 'b> { let mut ret = String::new(); ret.push_str("function("); ret.push_str(&self.shim_arguments.join(", ")); - if self.catch { - if self.shim_arguments.len() > 0 { - ret.push_str(", ") - } - ret.push_str("exnptr"); - } ret.push_str(") {\n"); ret.push_str(&self.prelude); diff --git a/src/lib.rs b/src/lib.rs index f6097f99..0d8ffe5b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1067,6 +1067,28 @@ pub mod __rt { pub fn link_mem_intrinsics() { crate::anyref::link_intrinsics(); } + + static mut GLOBAL_EXNDATA: [u32; 2] = [0; 2]; + + #[no_mangle] + pub unsafe extern "C" fn __wbindgen_exn_store(idx: u32) { + assert_eq!(GLOBAL_EXNDATA[0], 0); + GLOBAL_EXNDATA[0] = 1; + GLOBAL_EXNDATA[1] = idx; + } + + pub fn take_last_exception() -> Result<(), super::JsValue> { + unsafe { + let ret = if GLOBAL_EXNDATA[0] == 1 { + Err(super::JsValue:: _new(GLOBAL_EXNDATA[1])) + } else { + Ok(()) + }; + GLOBAL_EXNDATA[0] = 0; + GLOBAL_EXNDATA[1] = 0; + return ret; + } + } } /// A wrapper type around slices and vectors for binding the `Uint8ClampedArray`