diff --git a/crates/wasi-common/src/wasi.rs b/crates/wasi-common/src/wasi.rs index 2ae7257e66..214057e766 100644 --- a/crates/wasi-common/src/wasi.rs +++ b/crates/wasi-common/src/wasi.rs @@ -23,9 +23,9 @@ impl types::GuestErrorConversion for WasiCtx { } impl types::UserErrorConversion for WasiCtx { - fn errno_from_error(&self, e: Error) -> Errno { + fn errno_from_error(&self, e: Error) -> Result { debug!("Error: {:?}", e); - e.into() + Ok(e.into()) } } diff --git a/crates/wasi-common/wig/src/hostcalls.rs b/crates/wasi-common/wig/src/hostcalls.rs index a01926743b..359792a1bf 100644 --- a/crates/wasi-common/wig/src/hostcalls.rs +++ b/crates/wasi-common/wig/src/hostcalls.rs @@ -13,8 +13,6 @@ pub fn define(args: TokenStream) -> TokenStream { let mut ret = TokenStream::new(); - let old = true; - for module in doc.modules() { for func in module.funcs() { // `proc_exit` is special; it's essentially an unwinding primitive, @@ -24,14 +22,14 @@ pub fn define(args: TokenStream) -> TokenStream { continue; } - ret.extend(generate_wrappers(&func, old)); + ret.extend(generate_wrappers(&func)); } } return ret; } -fn generate_wrappers(func: &witx::InterfaceFunc, old: bool) -> TokenStream { +fn generate_wrappers(func: &witx::InterfaceFunc) -> TokenStream { let name = format_ident!("{}", func.name.as_str()); let mut arg_declarations = Vec::new(); let mut arg_names = Vec::new(); @@ -101,33 +99,13 @@ fn generate_wrappers(func: &witx::InterfaceFunc, old: bool) -> TokenStream { } }; - let c_abi_name = if old { - format_ident!("old_wasi_common_{}", name) - } else { - format_ident!("wasi_common_{}", name) - }; - quote! { pub unsafe fn #name( wasi_ctx: &mut super::WasiCtx, memory: &mut [u8], #(#arg_declarations,)* - ) -> #ret { - #body - } - - #[no_mangle] - pub unsafe fn #c_abi_name( - wasi_ctx: *mut super::WasiCtx, - memory: *mut u8, - memory_len: usize, - #(#arg_declarations,)* - ) -> #ret { - #name( - &mut *wasi_ctx, - std::slice::from_raw_parts_mut(memory, memory_len), - #(#arg_names,)* - ) + ) -> Result<#ret, String> { + Ok({#body}) } } } diff --git a/crates/wasi-common/wig/src/wasi.rs b/crates/wasi-common/wig/src/wasi.rs index 60269d28f7..c052ed6609 100644 --- a/crates/wasi-common/wig/src/wasi.rs +++ b/crates/wasi-common/wig/src/wasi.rs @@ -168,7 +168,7 @@ pub fn define_struct(args: TokenStream) -> TokenStream { // The first result is returned bare right now... if let Some(ret) = results.next() { - handle_early_error = quote! { return e.into() }; + handle_early_error = quote! { return Ok(e.into()) }; match &*ret.tref.type_() { // Eventually we'll want to add support for more returned // types, but for now let's just conform to what `*.witx` @@ -200,7 +200,7 @@ pub fn define_struct(args: TokenStream) -> TokenStream { let my_cx = cx.clone(); let #name_ident = wasmtime::Func::wrap( store, - move |caller: wasmtime::Caller<'_> #(,#shim_arg_decls)*| -> #ret_ty { + move |caller: wasmtime::Caller<'_> #(,#shim_arg_decls)*| -> Result<#ret_ty, wasmtime::Trap> { tracing::trace!( #format_str, #(#format_args),* @@ -214,11 +214,15 @@ pub fn define_struct(args: TokenStream) -> TokenStream { #handle_early_error } }; - hostcalls::#name_ident( + let result = hostcalls::#name_ident( &mut my_cx.borrow_mut(), memory.data_unchecked_mut(), #(#hostcall_args),* - ) #cvt_ret + ); + match result { + Ok(r) => { return Ok(r #cvt_ret); }, + Err(err) => { return Err(wasmtime::Trap::new(err)); }, + } } } ); diff --git a/crates/wasi-nn/src/witx.rs b/crates/wasi-nn/src/witx.rs index 6ec48800c5..6f7394e0b2 100644 --- a/crates/wasi-nn/src/witx.rs +++ b/crates/wasi-nn/src/witx.rs @@ -22,7 +22,7 @@ impl types::GuestErrorConversion for WasiNnCtx { } impl<'a> types::UserErrorConversion for WasiNnCtx { - fn errno_from_wasi_nn_error(&self, e: WasiNnError) -> Errno { + fn errno_from_wasi_nn_error(&self, e: WasiNnError) -> Result { eprintln!("Host error: {:?}", e); match e { WasiNnError::OpenvinoError(_) => unimplemented!(), diff --git a/crates/wiggle/generate/src/funcs.rs b/crates/wiggle/generate/src/funcs.rs index 0baa8cd390..e6551b17dd 100644 --- a/crates/wiggle/generate/src/funcs.rs +++ b/crates/wiggle/generate/src/funcs.rs @@ -55,7 +55,7 @@ pub fn define_func( let method = names.user_error_conversion_method(&user_err); quote!(UserErrorConversion::#method(ctx, e)) } else { - quote!(e) + quote!(Ok(e)) }; quote! { let e = #conversion; @@ -63,7 +63,10 @@ pub fn define_func( #rt::tracing::Level::TRACE, #name = #rt::tracing::field::debug(&e), ); - return #abi_ret::from(e); + match e { + Ok(e) => { return Ok(#abi_ret::from(e)); }, + Err(e) => { return Err(e); }, + } } }) .unwrap_or_else(|| quote!(())); @@ -79,7 +82,7 @@ pub fn define_func( quote! { let e = #rt::GuestError::InFunc { funcname: #funcname, location: #location, err: Box::new(e.into()) }; let err: #err_typename = GuestErrorConversion::#err_method(ctx, e); - return #abi_ret::from(err); + return Ok(#abi_ret::from(err)); } } else { quote! { @@ -161,17 +164,17 @@ pub fn define_func( #rt::tracing::Level::TRACE, success=#rt::tracing::field::display(&success) ); - #abi_ret::from(success) + Ok(#abi_ret::from(success)) } } else { - quote!() + quote!(Ok(())) }; let trait_name = names.trait_name(&module.name); let mod_name = &module.name.as_str(); let func_name = &func.name.as_str(); - quote!(pub fn #ident(#abi_args) -> #abi_ret { + quote!(pub fn #ident(#abi_args) -> Result<#abi_ret, String> { let _span = #rt::tracing::span!( #rt::tracing::Level::TRACE, "wiggle abi", diff --git a/crates/wiggle/generate/src/lib.rs b/crates/wiggle/generate/src/lib.rs index f1913163c7..206ded711b 100644 --- a/crates/wiggle/generate/src/lib.rs +++ b/crates/wiggle/generate/src/lib.rs @@ -40,7 +40,7 @@ pub fn generate(doc: &witx::Document, names: &Names, errs: &ErrorTransform) -> T let abi_typename = names.type_ref(&errtype.abi_type(), anon_lifetime()); let user_typename = errtype.typename(); let methodname = names.user_error_conversion_method(&errtype); - quote!(fn #methodname(&self, e: super::#user_typename) -> #abi_typename;) + quote!(fn #methodname(&self, e: super::#user_typename) -> Result<#abi_typename, String>;) }); let user_error_conversion = quote! { pub trait UserErrorConversion { diff --git a/crates/wiggle/test-helpers/examples/tracing.rs b/crates/wiggle/test-helpers/examples/tracing.rs index 5b7eeb8183..3d08ec45e1 100644 --- a/crates/wiggle/test-helpers/examples/tracing.rs +++ b/crates/wiggle/test-helpers/examples/tracing.rs @@ -36,7 +36,7 @@ impl_errno!(types::Errno, types::GuestErrorConversion); /// When the `errors` mapping in witx is non-empty, we need to impl the /// types::UserErrorConversion trait that wiggle generates from that mapping. impl<'a> types::UserErrorConversion for WasiCtx<'a> { - fn errno_from_rich_error(&self, e: RichError) -> types::Errno { + fn errno_from_rich_error(&self, e: RichError) -> Result { wiggle::tracing::debug!( rich_error = wiggle::tracing::field::debug(&e), "error conversion" @@ -46,8 +46,8 @@ impl<'a> types::UserErrorConversion for WasiCtx<'a> { self.log.borrow_mut().push(e.to_string()); // Then do the trivial mapping down to the flat enum. match e { - RichError::InvalidArg { .. } => types::Errno::InvalidArg, - RichError::PicketLine { .. } => types::Errno::PicketLine, + RichError::InvalidArg { .. } => Ok(types::Errno::InvalidArg), + RichError::PicketLine { .. } => Ok(types::Errno::PicketLine), } } } @@ -90,7 +90,7 @@ fn main() { let r0 = one_error_conversion::foo(&ctx, &host_memory, 0, 0, 8); assert_eq!( r0, - i32::from(types::Errno::Ok), + Ok(i32::from(types::Errno::Ok)), "Expected return value for strike=0" ); assert!(ctx.log.borrow().is_empty(), "No error log for strike=0"); @@ -99,7 +99,7 @@ fn main() { let r1 = one_error_conversion::foo(&ctx, &host_memory, 1, 0, 8); assert_eq!( r1, - i32::from(types::Errno::PicketLine), + Ok(i32::from(types::Errno::PicketLine)), "Expected return value for strike=1" ); assert_eq!( @@ -112,7 +112,7 @@ fn main() { let r2 = one_error_conversion::foo(&ctx, &host_memory, 2, 0, 8); assert_eq!( r2, - i32::from(types::Errno::InvalidArg), + Ok(i32::from(types::Errno::InvalidArg)), "Expected return value for strike=2" ); assert_eq!( diff --git a/crates/wiggle/tests/arrays.rs b/crates/wiggle/tests/arrays.rs index 5f660fce69..b796a212d7 100644 --- a/crates/wiggle/tests/arrays.rs +++ b/crates/wiggle/tests/arrays.rs @@ -105,7 +105,7 @@ impl ReduceExcusesExcercise { self.return_ptr_loc.ptr as i32, ); - assert_eq!(res, types::Errno::Ok.into(), "reduce excuses errno"); + assert_eq!(res, Ok(types::Errno::Ok.into()), "reduce excuses errno"); let expected = *self .excuse_values @@ -183,7 +183,7 @@ impl PopulateExcusesExcercise { self.array_ptr_loc.ptr as i32, self.elements.len() as i32, ); - assert_eq!(res, types::Errno::Ok.into(), "populate excuses errno"); + assert_eq!(res, Ok(types::Errno::Ok.into()), "populate excuses errno"); let arr: GuestPtr<'_, [GuestPtr<'_, types::Excuse>]> = host_memory.ptr((self.array_ptr_loc.ptr, self.elements.len() as u32)); @@ -309,7 +309,7 @@ impl SumElementsExercise { self.start_ix as i32, self.return_loc.ptr as i32, ); - assert_eq!(res, types::Errno::Ok.into(), "sum_of_element errno"); + assert_eq!(res, Ok(types::Errno::Ok.into()), "sum_of_element errno"); let result_ptr = host_memory.ptr::(self.return_loc.ptr); let result = result_ptr.read().expect("read result"); @@ -330,7 +330,7 @@ impl SumElementsExercise { ); assert_eq!( res, - types::Errno::InvalidArg.into(), + Ok(types::Errno::InvalidArg.into()), "out of bounds sum_of_element errno" ); @@ -346,7 +346,7 @@ impl SumElementsExercise { if self.start_ix <= self.end_ix { assert_eq!( res, - types::Errno::Ok.into(), + Ok(types::Errno::Ok.into()), "expected ok sum_of_elements errno" ); let result_ptr = host_memory.ptr::(self.return_loc.ptr); @@ -367,7 +367,7 @@ impl SumElementsExercise { } else { assert_eq!( res, - types::Errno::InvalidArg.into(), + Ok(types::Errno::InvalidArg.into()), "expected error out-of-bounds sum_of_elements" ); } @@ -384,7 +384,7 @@ impl SumElementsExercise { ); assert_eq!( res, - types::Errno::InvalidArg.into(), + Ok(types::Errno::InvalidArg.into()), "out of bounds sum_of_elements errno" ); } diff --git a/crates/wiggle/tests/atoms.rs b/crates/wiggle/tests/atoms.rs index b83468678b..f2da4827a8 100644 --- a/crates/wiggle/tests/atoms.rs +++ b/crates/wiggle/tests/atoms.rs @@ -34,7 +34,7 @@ impl IntFloatExercise { let e = atoms::int_float_args(&ctx, &host_memory, self.an_int as i32, self.an_float); - assert_eq!(e, types::Errno::Ok.into(), "int_float_args error"); + assert_eq!(e, Ok(types::Errno::Ok.into()), "int_float_args error"); } pub fn strat() -> BoxedStrategy { @@ -72,7 +72,7 @@ impl DoubleIntExercise { .ptr::(self.return_loc.ptr) .read() .expect("failed to read return"); - assert_eq!(e, types::Errno::Ok.into(), "errno"); + assert_eq!(e, Ok(types::Errno::Ok.into()), "errno"); assert_eq!(return_val, (self.input as f32) * 2.0, "return val"); } diff --git a/crates/wiggle/tests/errors.rs b/crates/wiggle/tests/errors.rs index 522982c845..a550da35bd 100644 --- a/crates/wiggle/tests/errors.rs +++ b/crates/wiggle/tests/errors.rs @@ -34,14 +34,14 @@ mod convert_just_errno { /// When the `errors` mapping in witx is non-empty, we need to impl the /// types::UserErrorConversion trait that wiggle generates from that mapping. impl<'a> types::UserErrorConversion for WasiCtx<'a> { - fn errno_from_rich_error(&self, e: RichError) -> types::Errno { + fn errno_from_rich_error(&self, e: RichError) -> Result { // WasiCtx can collect a Vec log so we can test this. We're // logging the Display impl that `thiserror::Error` provides us. self.log.borrow_mut().push(e.to_string()); // Then do the trivial mapping down to the flat enum. match e { - RichError::InvalidArg { .. } => types::Errno::InvalidArg, - RichError::PicketLine { .. } => types::Errno::PicketLine, + RichError::InvalidArg { .. } => Ok(types::Errno::InvalidArg), + RichError::PicketLine { .. } => Ok(types::Errno::PicketLine), } } } @@ -68,7 +68,7 @@ mod convert_just_errno { let r0 = one_error_conversion::foo(&ctx, &host_memory, 0); assert_eq!( r0, - i32::from(types::Errno::Ok), + Ok(i32::from(types::Errno::Ok)), "Expected return value for strike=0" ); assert!(ctx.log.borrow().is_empty(), "No error log for strike=0"); @@ -77,7 +77,7 @@ mod convert_just_errno { let r1 = one_error_conversion::foo(&ctx, &host_memory, 1); assert_eq!( r1, - i32::from(types::Errno::PicketLine), + Ok(i32::from(types::Errno::PicketLine)), "Expected return value for strike=1" ); assert_eq!( @@ -90,7 +90,7 @@ mod convert_just_errno { let r2 = one_error_conversion::foo(&ctx, &host_memory, 2); assert_eq!( r2, - i32::from(types::Errno::InvalidArg), + Ok(i32::from(types::Errno::InvalidArg)), "Expected return value for strike=2" ); assert_eq!( @@ -159,10 +159,13 @@ mod convert_multiple_error_types { // each member of the `errors` mapping. // Bodies elided. impl<'a> types::UserErrorConversion for WasiCtx<'a> { - fn errno_from_rich_error(&self, _e: RichError) -> types::Errno { + fn errno_from_rich_error(&self, _e: RichError) -> Result { unimplemented!() } - fn errno2_from_another_rich_error(&self, _e: AnotherRichError) -> types::Errno2 { + fn errno2_from_another_rich_error( + &self, + _e: AnotherRichError, + ) -> Result { unimplemented!() } } diff --git a/crates/wiggle/tests/flags.rs b/crates/wiggle/tests/flags.rs index bca0a27bae..e12b64a457 100644 --- a/crates/wiggle/tests/flags.rs +++ b/crates/wiggle/tests/flags.rs @@ -79,7 +79,7 @@ impl ConfigureCarExercise { self.other_config_by_ptr.ptr as i32, self.return_ptr_loc.ptr as i32, ); - assert_eq!(res, types::Errno::Ok.into(), "configure car errno"); + assert_eq!(res, Ok(types::Errno::Ok.into()), "configure car errno"); let res_config = host_memory .ptr::(self.return_ptr_loc.ptr) diff --git a/crates/wiggle/tests/handles.rs b/crates/wiggle/tests/handles.rs index cb441a910c..4ad9085a42 100644 --- a/crates/wiggle/tests/handles.rs +++ b/crates/wiggle/tests/handles.rs @@ -37,7 +37,7 @@ impl HandleExercise { let e = handle_examples::fd_create(&ctx, &host_memory, self.return_loc.ptr as i32); - assert_eq!(e, types::Errno::Ok.into(), "fd_create error"); + assert_eq!(e, Ok(types::Errno::Ok.into()), "fd_create error"); let h_got: u32 = host_memory .ptr(self.return_loc.ptr) @@ -48,13 +48,13 @@ impl HandleExercise { let e = handle_examples::fd_consume(&ctx, &host_memory, h_got as i32); - assert_eq!(e, types::Errno::Ok.into(), "fd_consume error"); + assert_eq!(e, Ok(types::Errno::Ok.into()), "fd_consume error"); let e = handle_examples::fd_consume(&ctx, &host_memory, h_got as i32 + 1); assert_eq!( e, - types::Errno::InvalidArg.into(), + Ok(types::Errno::InvalidArg.into()), "fd_consume invalid error" ); } diff --git a/crates/wiggle/tests/ints.rs b/crates/wiggle/tests/ints.rs index a3d15c79d8..82d04a4a00 100644 --- a/crates/wiggle/tests/ints.rs +++ b/crates/wiggle/tests/ints.rs @@ -53,7 +53,7 @@ impl CookieCutterExercise { self.cookie.into(), self.return_ptr_loc.ptr as i32, ); - assert_eq!(res, types::Errno::Ok.into(), "cookie cutter errno"); + assert_eq!(res, Ok(types::Errno::Ok.into()), "cookie cutter errno"); let is_cookie_start = host_memory .ptr::(self.return_ptr_loc.ptr) diff --git a/crates/wiggle/tests/pointers.rs b/crates/wiggle/tests/pointers.rs index 28ef3d107d..5bc2719480 100644 --- a/crates/wiggle/tests/pointers.rs +++ b/crates/wiggle/tests/pointers.rs @@ -157,7 +157,7 @@ impl PointersAndEnumsExercise { self.input3_loc.ptr as i32, self.input4_ptr_loc.ptr as i32, ); - assert_eq!(e, types::Errno::Ok.into(), "errno"); + assert_eq!(e, Ok(types::Errno::Ok.into()), "errno"); // Implementation of pointers_and_enums writes input3 to the input2_loc: let written_to_input2_loc: i32 = host_memory diff --git a/crates/wiggle/tests/strings.rs b/crates/wiggle/tests/strings.rs index ed176f6f62..a55917e4df 100644 --- a/crates/wiggle/tests/strings.rs +++ b/crates/wiggle/tests/strings.rs @@ -88,7 +88,7 @@ impl HelloStringExercise { self.test_word.len() as i32, self.return_ptr_loc.ptr as i32, ); - assert_eq!(res, types::Errno::Ok.into(), "hello string errno"); + assert_eq!(res, Ok(types::Errno::Ok.into()), "hello string errno"); let given = host_memory .ptr::(self.return_ptr_loc.ptr) @@ -209,7 +209,7 @@ impl MultiStringExercise { self.c.len() as i32, self.return_ptr_loc.ptr as i32, ); - assert_eq!(res, types::Errno::Ok.into(), "multi string errno"); + assert_eq!(res, Ok(types::Errno::Ok.into()), "multi string errno"); let given = host_memory .ptr::(self.return_ptr_loc.ptr) @@ -287,7 +287,7 @@ impl OverlappingStringExercise { a_len - self.offset_c as i32, self.return_ptr_loc.ptr as i32, ); - assert_eq!(res, types::Errno::Ok.into(), "multi string errno"); + assert_eq!(res, Ok(types::Errno::Ok.into()), "multi string errno"); let given = host_memory .ptr::(self.return_ptr_loc.ptr) diff --git a/crates/wiggle/tests/structs.rs b/crates/wiggle/tests/structs.rs index 27b7b865c1..9e92f1b86e 100644 --- a/crates/wiggle/tests/structs.rs +++ b/crates/wiggle/tests/structs.rs @@ -118,7 +118,7 @@ impl SumOfPairExercise { self.return_loc.ptr as i32, ); - assert_eq!(sum_err, types::Errno::Ok.into(), "sum errno"); + assert_eq!(sum_err, Ok(types::Errno::Ok.into()), "sum errno"); let return_val: i64 = host_memory .ptr(self.return_loc.ptr) @@ -216,7 +216,11 @@ impl SumPairPtrsExercise { self.return_loc.ptr as i32, ); - assert_eq!(res, types::Errno::Ok.into(), "sum of pair of ptrs errno"); + assert_eq!( + res, + Ok(types::Errno::Ok.into()), + "sum of pair of ptrs errno" + ); let doubled: i64 = host_memory .ptr(self.return_loc.ptr) @@ -295,7 +299,7 @@ impl SumIntAndPtrExercise { self.return_loc.ptr as i32, ); - assert_eq!(res, types::Errno::Ok.into(), "sum of int and ptr errno"); + assert_eq!(res, Ok(types::Errno::Ok.into()), "sum of int and ptr errno"); let doubled: i64 = host_memory .ptr(self.return_loc.ptr) @@ -334,7 +338,7 @@ impl ReturnPairInts { let err = structs::return_pair_ints(&ctx, &host_memory, self.return_loc.ptr as i32); - assert_eq!(err, types::Errno::Ok.into(), "return struct errno"); + assert_eq!(err, Ok(types::Errno::Ok.into()), "return struct errno"); let return_struct: types::PairInts = host_memory .ptr(self.return_loc.ptr) @@ -414,7 +418,11 @@ impl ReturnPairPtrsExercise { self.return_loc.ptr as i32, ); - assert_eq!(res, types::Errno::Ok.into(), "return pair of ptrs errno"); + assert_eq!( + res, + Ok(types::Errno::Ok.into()), + "return pair of ptrs errno" + ); let ptr_pair_int_ptrs: types::PairIntPtrs<'_> = host_memory .ptr(self.return_loc.ptr) @@ -522,7 +530,7 @@ impl SumArrayExercise { ); // should be no error - if hostcall did a GuestError it should eprintln it. - assert_eq!(res, types::Errno::Ok.into(), "reduce excuses errno"); + assert_eq!(res, Ok(types::Errno::Ok.into()), "reduce excuses errno"); // Sum is inputs upcasted to u16 let expected: u16 = self.inputs.iter().map(|v| *v as u16).sum(); diff --git a/crates/wiggle/tests/union.rs b/crates/wiggle/tests/union.rs index 9763e488dd..22a9f967ec 100644 --- a/crates/wiggle/tests/union.rs +++ b/crates/wiggle/tests/union.rs @@ -133,7 +133,7 @@ impl GetTagExercise { self.return_loc.ptr as i32, ); - assert_eq!(e, types::Errno::Ok.into(), "get_tag errno"); + assert_eq!(e, Ok(types::Errno::Ok.into()), "get_tag errno"); let return_val: types::Excuse = host_memory .ptr(self.return_loc.ptr) @@ -217,7 +217,7 @@ impl ReasonMultExercise { self.multiply_by as i32, ); - assert_eq!(e, types::Errno::Ok.into(), "reason_mult errno"); + assert_eq!(e, Ok(types::Errno::Ok.into()), "reason_mult errno"); match self.input { types::Reason::DogAte(f) => { diff --git a/crates/wiggle/wasmtime/macro/src/lib.rs b/crates/wiggle/wasmtime/macro/src/lib.rs index 4ba1c1b9fb..71b37862c6 100644 --- a/crates/wiggle/wasmtime/macro/src/lib.rs +++ b/crates/wiggle/wasmtime/macro/src/lib.rs @@ -185,7 +185,7 @@ fn generate_func( witx::CoreParamSignifies::Value(atom) => names.atom_type(atom), _ => unreachable!("coretype ret should always be passed by value"), }; - (quote! { #ret_ty }, quote! { return e.into(); }) + (quote! { #ret_ty }, quote! { return Ok(e.into()); }) } else { ( quote! {()}, @@ -199,7 +199,7 @@ fn generate_func( let my_cx = cx.clone(); let #name_ident = wasmtime::Func::wrap( store, - move |caller: wasmtime::Caller<'_> #(,#arg_decls)*| -> #ret_ty { + move |caller: wasmtime::Caller<'_> #(,#arg_decls)*| -> Result<#ret_ty, wasmtime::Trap> { unsafe { let mem = match caller.get_export("memory") { Some(wasmtime::Extern::Memory(m)) => m, @@ -210,11 +210,15 @@ fn generate_func( } }; let mem = #runtime::WasmtimeGuestMemory::new(mem); - #target_module::#name_ident( + let result = #target_module::#name_ident( &mut my_cx.borrow_mut(), &mem, #(#arg_names),* - ) + ); + match result { + Ok(r) => {return Ok(r.into());}, + Err(err) => { return Err(wasmtime::Trap::new(err)); }, + } } } );