mirror of
https://github.com/fluencelabs/wasm-bindgen
synced 2025-05-15 07:11:19 +00:00
Merge pull request #1588 from alexcrichton/exnptr
Communicate exceptions through global memory
This commit is contained in:
commit
c0df37b2f2
@ -974,28 +974,12 @@ impl TryToTokens for ast::ImportFunction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut exceptional_ret = quote!();
|
let mut exceptional_ret = quote!();
|
||||||
let exn_data = if self.catch {
|
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 });
|
|
||||||
convert_ret = quote! { Ok(#convert_ret) };
|
convert_ret = quote! { Ok(#convert_ret) };
|
||||||
exceptional_ret = quote! {
|
exceptional_ret = quote! {
|
||||||
if #exn_data[0] == 1 {
|
wasm_bindgen::__rt::take_last_exception()?;
|
||||||
return Err(
|
|
||||||
<
|
|
||||||
wasm_bindgen::JsValue as wasm_bindgen::convert::FromWasmAbi
|
|
||||||
>::from_abi(#exn_data[1], &mut wasm_bindgen::convert::GlobalStack::new())
|
|
||||||
)
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
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 rust_name = &self.rust_name;
|
||||||
let import_name = &self.shim;
|
let import_name = &self.shim;
|
||||||
@ -1055,7 +1039,6 @@ impl TryToTokens for ast::ImportFunction {
|
|||||||
#extern_fn
|
#extern_fn
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
#exn_data
|
|
||||||
let #ret_ident = {
|
let #ret_ident = {
|
||||||
let mut __stack = wasm_bindgen::convert::GlobalStack::new();
|
let mut __stack = wasm_bindgen::convert::GlobalStack::new();
|
||||||
#(#arg_conversions)*
|
#(#arg_conversions)*
|
||||||
|
@ -1419,16 +1419,14 @@ impl<'a> Context<'a> {
|
|||||||
if !self.should_write_global("handle_error") {
|
if !self.should_write_global("handle_error") {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
self.expose_uint32_memory();
|
self.require_internal_export("__wbindgen_exn_store")?;
|
||||||
if self.config.anyref {
|
if self.config.anyref {
|
||||||
self.expose_add_to_anyref_table()?;
|
self.expose_add_to_anyref_table()?;
|
||||||
self.global(
|
self.global(
|
||||||
"
|
"
|
||||||
function handleError(exnptr, e) {
|
function handleError(e) {
|
||||||
const idx = addToAnyrefTable(e);
|
const idx = addToAnyrefTable(e);
|
||||||
const view = getUint32Memory();
|
wasm.__wbindgen_exn_store(idx);
|
||||||
view[exnptr / 4] = 1;
|
|
||||||
view[exnptr / 4 + 1] = idx;
|
|
||||||
}
|
}
|
||||||
",
|
",
|
||||||
);
|
);
|
||||||
@ -1436,10 +1434,8 @@ impl<'a> Context<'a> {
|
|||||||
self.expose_add_heap_object();
|
self.expose_add_heap_object();
|
||||||
self.global(
|
self.global(
|
||||||
"
|
"
|
||||||
function handleError(exnptr, e) {
|
function handleError(e) {
|
||||||
const view = getUint32Memory();
|
wasm.__wbindgen_exn_store(addHeapObject(e));
|
||||||
view[exnptr / 4] = 1;
|
|
||||||
view[exnptr / 4 + 1] = addHeapObject(e);
|
|
||||||
}
|
}
|
||||||
",
|
",
|
||||||
);
|
);
|
||||||
@ -2115,7 +2111,7 @@ impl<'a> Context<'a> {
|
|||||||
|
|
||||||
fn export_function_table(&mut self) -> Result<(), Error> {
|
fn export_function_table(&mut self) -> Result<(), Error> {
|
||||||
if !self.should_write_global("wbg-function-table") {
|
if !self.should_write_global("wbg-function-table") {
|
||||||
return Ok(())
|
return Ok(());
|
||||||
}
|
}
|
||||||
let id = match self.module.tables.main_function_table()? {
|
let id = match self.module.tables.main_function_table()? {
|
||||||
Some(id) => id,
|
Some(id) => id,
|
||||||
@ -2192,7 +2188,7 @@ impl ExportedClass {
|
|||||||
field: &str,
|
field: &str,
|
||||||
js: &str,
|
js: &str,
|
||||||
prefix: &str,
|
prefix: &str,
|
||||||
ret_ty: &str
|
ret_ty: &str,
|
||||||
) -> &mut bool {
|
) -> &mut bool {
|
||||||
self.contents.push_str(docs);
|
self.contents.push_str(docs);
|
||||||
self.contents.push_str(prefix);
|
self.contents.push_str(prefix);
|
||||||
@ -2215,7 +2211,8 @@ impl ExportedClass {
|
|||||||
/// generated output is deterministic and we do so by ensuring that iteration of
|
/// generated output is deterministic and we do so by ensuring that iteration of
|
||||||
/// hash maps is consistently sorted.
|
/// hash maps is consistently sorted.
|
||||||
fn sorted_iter<K, V>(map: &HashMap<K, V>) -> impl Iterator<Item = (&K, &V)>
|
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<_>>();
|
let mut pairs = map.iter().collect::<Vec<_>>();
|
||||||
pairs.sort_by_key(|(k, _)| *k);
|
pairs.sort_by_key(|(k, _)| *k);
|
||||||
|
@ -928,7 +928,7 @@ impl<'a, 'b> Rust2Js<'a, 'b> {
|
|||||||
try {{\n\
|
try {{\n\
|
||||||
{}
|
{}
|
||||||
}} catch (e) {{\n\
|
}} catch (e) {{\n\
|
||||||
handleError(exnptr, e);\n\
|
handleError(e);\n\
|
||||||
}}\
|
}}\
|
||||||
",
|
",
|
||||||
&invoc
|
&invoc
|
||||||
@ -973,12 +973,6 @@ impl<'a, 'b> Rust2Js<'a, 'b> {
|
|||||||
let mut ret = String::new();
|
let mut ret = String::new();
|
||||||
ret.push_str("function(");
|
ret.push_str("function(");
|
||||||
ret.push_str(&self.shim_arguments.join(", "));
|
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(") {\n");
|
||||||
ret.push_str(&self.prelude);
|
ret.push_str(&self.prelude);
|
||||||
|
|
||||||
|
22
src/lib.rs
22
src/lib.rs
@ -1067,6 +1067,28 @@ pub mod __rt {
|
|||||||
pub fn link_mem_intrinsics() {
|
pub fn link_mem_intrinsics() {
|
||||||
crate::anyref::link_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`
|
/// A wrapper type around slices and vectors for binding the `Uint8ClampedArray`
|
||||||
|
Loading…
x
Reference in New Issue
Block a user