Merge branch 'pch/wiggle_trapping' into pch/wasi_common_cap_std

This commit is contained in:
Pat Hickey
2021-01-07 14:10:59 -08:00
25 changed files with 183 additions and 142 deletions

2
Cargo.lock generated
View File

@@ -3073,7 +3073,7 @@ dependencies = [
[[package]] [[package]]
name = "witx" name = "witx"
version = "0.8.7" version = "0.8.8"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"diff", "diff",

View File

@@ -17,6 +17,10 @@ pub enum Error {
#[error("GetRandom: {0}")] #[error("GetRandom: {0}")]
GetRandom(#[from] getrandom::Error), GetRandom(#[from] getrandom::Error),
/// Some corners of the WASI standard are unsupported.
#[error("Unsupported: {0}")]
Unsupported(&'static str),
/// The host OS may return an io error that doesn't match one of the /// The host OS may return an io error that doesn't match one of the
/// wasi errno variants we expect. We do not expose the details of this /// wasi errno variants we expect. We do not expose the details of this
/// error to the user. /// error to the user.

View File

@@ -714,14 +714,17 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx {
Ok(nevents) Ok(nevents)
} }
fn proc_exit(&self, _rval: types::Exitcode) -> std::result::Result<(), ()> { fn proc_exit(&self, status: types::Exitcode) -> wiggle::Trap {
// proc_exit is special in that it's expected to unwind the stack, which // Check that the status is within WASI's range.
// typically requires runtime-specific logic. if status < 126 {
unimplemented!("runtimes are expected to override this implementation") wiggle::Trap::I32Exit(status as i32)
} else {
wiggle::Trap::String("exit with invalid exit status outside of [0..126)".to_owned())
}
} }
fn proc_raise(&self, _sig: types::Signal) -> Result<()> { fn proc_raise(&self, _sig: types::Signal) -> Result<()> {
unimplemented!("proc_raise") Err(Error::Unsupported("proc_raise"))
} }
fn sched_yield(&self) -> Result<()> { fn sched_yield(&self) -> Result<()> {
@@ -741,7 +744,7 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx {
_ri_data: &types::IovecArray<'_>, _ri_data: &types::IovecArray<'_>,
_ri_flags: types::Riflags, _ri_flags: types::Riflags,
) -> Result<(types::Size, types::Roflags)> { ) -> Result<(types::Size, types::Roflags)> {
unimplemented!("sock_recv") Err(Error::Unsupported("sock_recv"))
} }
fn sock_send( fn sock_send(
@@ -750,11 +753,11 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx {
_si_data: &types::CiovecArray<'_>, _si_data: &types::CiovecArray<'_>,
_si_flags: types::Siflags, _si_flags: types::Siflags,
) -> Result<types::Size> { ) -> Result<types::Size> {
unimplemented!("sock_send") Err(Error::Unsupported("sock_send"))
} }
fn sock_shutdown(&self, _fd: types::Fd, _how: types::Sdflags) -> Result<()> { fn sock_shutdown(&self, _fd: types::Fd, _how: types::Sdflags) -> Result<()> {
unimplemented!("sock_shutdown") Err(Error::Unsupported("sock_shutdown"))
} }
} }
@@ -801,7 +804,7 @@ impl WasiCtx {
Err(error) => { Err(error) => {
events.push(types::Event { events.push(types::Event {
userdata: subscription.userdata, userdata: subscription.userdata,
error: error.into(), error: error.try_into().expect("non-trapping error"),
type_: types::Eventtype::FdRead, type_: types::Eventtype::FdRead,
fd_readwrite: types::EventFdReadwrite { fd_readwrite: types::EventFdReadwrite {
nbytes: 0, nbytes: 0,
@@ -827,7 +830,7 @@ impl WasiCtx {
Err(error) => { Err(error) => {
events.push(types::Event { events.push(types::Event {
userdata: subscription.userdata, userdata: subscription.userdata,
error: error.into(), error: error.try_into().expect("non-trapping error"),
type_: types::Eventtype::FdWrite, type_: types::Eventtype::FdWrite,
fd_readwrite: types::EventFdReadwrite { fd_readwrite: types::EventFdReadwrite {
nbytes: 0, nbytes: 0,

View File

@@ -23,15 +23,16 @@ impl types::GuestErrorConversion for WasiCtx {
} }
impl types::UserErrorConversion for WasiCtx { impl types::UserErrorConversion for WasiCtx {
fn errno_from_error(&self, e: Error) -> Result<Errno, String> { fn errno_from_error(&self, e: Error) -> Result<Errno, wiggle::Trap> {
tracing::debug!("Error: {:?}", e); tracing::debug!("Error: {:?}", e);
Ok(e.into()) e.try_into()
} }
} }
impl From<Error> for Errno { impl TryFrom<Error> for Errno {
fn from(e: Error) -> Errno { type Error = wiggle::Trap;
types_new::Errno::from(e).into() fn try_from(e: Error) -> Result<Errno, wiggle::Trap> {
Ok(types_new::Errno::try_from(e)?.into())
} }
} }
@@ -346,7 +347,7 @@ impl wasi_unstable::WasiUnstable for WasiCtx {
Ok(nevents) Ok(nevents)
} }
fn proc_exit(&self, rval: Exitcode) -> Result<(), ()> { fn proc_exit(&self, rval: Exitcode) -> wiggle::Trap {
WasiSnapshotPreview1::proc_exit(self, rval) WasiSnapshotPreview1::proc_exit(self, rval)
} }

View File

@@ -117,7 +117,7 @@ fn handle_fd_event(
let output_event = if revents.contains(PollFlags::POLLNVAL) { let output_event = if revents.contains(PollFlags::POLLNVAL) {
Event { Event {
userdata: fd_event.userdata, userdata: fd_event.userdata,
error: Error::Badf.into(), error: Error::Badf.try_into().unwrap(),
type_: fd_event.r#type, type_: fd_event.r#type,
fd_readwrite: EventFdReadwrite { fd_readwrite: EventFdReadwrite {
nbytes: 0, nbytes: 0,
@@ -127,7 +127,7 @@ fn handle_fd_event(
} else if revents.contains(PollFlags::POLLERR) { } else if revents.contains(PollFlags::POLLERR) {
Event { Event {
userdata: fd_event.userdata, userdata: fd_event.userdata,
error: Error::Io.into(), error: Error::Io.try_into().unwrap(),
type_: fd_event.r#type, type_: fd_event.r#type,
fd_readwrite: EventFdReadwrite { fd_readwrite: EventFdReadwrite {
nbytes: 0, nbytes: 0,

View File

@@ -1,4 +1,5 @@
use crate::{Error, WasiCtx}; use crate::{Error, WasiCtx};
use std::convert::{TryFrom, TryInto};
use tracing::debug; use tracing::debug;
wiggle::from_witx!({ wiggle::from_witx!({
@@ -23,47 +24,51 @@ impl types::GuestErrorConversion for WasiCtx {
} }
impl types::UserErrorConversion for WasiCtx { impl types::UserErrorConversion for WasiCtx {
fn errno_from_error(&self, e: Error) -> Result<Errno, String> { fn errno_from_error(&self, e: Error) -> Result<Errno, wiggle::Trap> {
debug!("Error: {:?}", e); debug!("Error: {:?}", e);
Ok(e.into()) e.try_into()
} }
} }
impl From<Error> for Errno { impl TryFrom<Error> for Errno {
fn from(e: Error) -> Errno { type Error = wiggle::Trap;
fn try_from(e: Error) -> Result<Errno, wiggle::Trap> {
match e { match e {
Error::Guest(e) => e.into(), Error::Guest(e) => Ok(e.into()),
Error::TryFromInt(_) => Errno::Overflow, Error::TryFromInt(_) => Ok(Errno::Overflow),
Error::Utf8(_) => Errno::Ilseq, Error::Utf8(_) => Ok(Errno::Ilseq),
Error::UnexpectedIo(_) => Errno::Io, Error::UnexpectedIo(_) => Ok(Errno::Io),
Error::GetRandom(_) => Errno::Io, Error::GetRandom(_) => Ok(Errno::Io),
Error::TooBig => Errno::TooBig, Error::TooBig => Ok(Errno::TooBig),
Error::Acces => Errno::Acces, Error::Acces => Ok(Errno::Acces),
Error::Badf => Errno::Badf, Error::Badf => Ok(Errno::Badf),
Error::Busy => Errno::Busy, Error::Busy => Ok(Errno::Busy),
Error::Exist => Errno::Exist, Error::Exist => Ok(Errno::Exist),
Error::Fault => Errno::Fault, Error::Fault => Ok(Errno::Fault),
Error::Fbig => Errno::Fbig, Error::Fbig => Ok(Errno::Fbig),
Error::Ilseq => Errno::Ilseq, Error::Ilseq => Ok(Errno::Ilseq),
Error::Inval => Errno::Inval, Error::Inval => Ok(Errno::Inval),
Error::Io => Errno::Io, Error::Io => Ok(Errno::Io),
Error::Isdir => Errno::Isdir, Error::Isdir => Ok(Errno::Isdir),
Error::Loop => Errno::Loop, Error::Loop => Ok(Errno::Loop),
Error::Mfile => Errno::Mfile, Error::Mfile => Ok(Errno::Mfile),
Error::Mlink => Errno::Mlink, Error::Mlink => Ok(Errno::Mlink),
Error::Nametoolong => Errno::Nametoolong, Error::Nametoolong => Ok(Errno::Nametoolong),
Error::Nfile => Errno::Nfile, Error::Nfile => Ok(Errno::Nfile),
Error::Noent => Errno::Noent, Error::Noent => Ok(Errno::Noent),
Error::Nomem => Errno::Nomem, Error::Nomem => Ok(Errno::Nomem),
Error::Nospc => Errno::Nospc, Error::Nospc => Ok(Errno::Nospc),
Error::Notdir => Errno::Notdir, Error::Notdir => Ok(Errno::Notdir),
Error::Notempty => Errno::Notempty, Error::Notempty => Ok(Errno::Notempty),
Error::Notsup => Errno::Notsup, Error::Notsup => Ok(Errno::Notsup),
Error::Overflow => Errno::Overflow, Error::Overflow => Ok(Errno::Overflow),
Error::Pipe => Errno::Pipe, Error::Pipe => Ok(Errno::Pipe),
Error::Perm => Errno::Perm, Error::Perm => Ok(Errno::Perm),
Error::Spipe => Errno::Spipe, Error::Spipe => Ok(Errno::Spipe),
Error::Notcapable => Errno::Notcapable, Error::Notcapable => Ok(Errno::Notcapable),
Error::Unsupported(feature) => {
Err(wiggle::Trap::String(format!("unsupported: {}", feature)))
}
} }
} }
} }
@@ -80,8 +85,8 @@ impl From<wiggle::GuestError> for Errno {
PtrBorrowed { .. } => Self::Fault, PtrBorrowed { .. } => Self::Fault,
InvalidUtf8 { .. } => Self::Ilseq, InvalidUtf8 { .. } => Self::Ilseq,
TryFromIntError { .. } => Self::Overflow, TryFromIntError { .. } => Self::Overflow,
InFunc { .. } => Self::Inval, InFunc { err, .. } => Errno::from(*err),
InDataField { .. } => Self::Inval, InDataField { err, .. } => Errno::from(*err),
SliceLengthsDiffer { .. } => Self::Fault, SliceLengthsDiffer { .. } => Self::Fault,
BorrowCheckerOutOfHandles { .. } => Self::Fault, BorrowCheckerOutOfHandles { .. } => Self::Fault,
} }

View File

@@ -22,7 +22,7 @@ impl types::GuestErrorConversion for WasiNnCtx {
} }
impl<'a> types::UserErrorConversion for WasiNnCtx { impl<'a> types::UserErrorConversion for WasiNnCtx {
fn errno_from_wasi_nn_error(&self, e: WasiNnError) -> Result<Errno, String> { fn errno_from_wasi_nn_error(&self, e: WasiNnError) -> Result<Errno, wiggle::Trap> {
eprintln!("Host error: {:?}", e); eprintln!("Host error: {:?}", e);
match e { match e {
WasiNnError::OpenvinoError(_) => unimplemented!(), WasiNnError::OpenvinoError(_) => unimplemented!(),

View File

@@ -1,5 +1,3 @@
use wasmtime::Trap;
pub mod old; pub mod old;
pub use wasi_common::virtfs; pub use wasi_common::virtfs;
@@ -26,12 +24,7 @@ modules. This structure exports all that various fields of the wasi instance
as fields which can be used to implement your own instantiation logic, if as fields which can be used to implement your own instantiation logic, if
necessary. Additionally [`Wasi::get_export`] can be used to do name-based necessary. Additionally [`Wasi::get_export`] can be used to do name-based
resolution.", resolution.",
// Don't use the wiggle generated code to implement proc_exit, we need }
// to hook directly into the runtime there:
function_override: {
proc_exit => wasi_proc_exit
}
},
}, },
}); });
@@ -41,17 +34,3 @@ pub fn is_wasi_module(name: &str) -> bool {
// trick. // trick.
name.starts_with("wasi") name.starts_with("wasi")
} }
/// Implement the WASI `proc_exit` function. This function is implemented here
/// instead of in wasi-common so that we can use the runtime to perform an
/// unwind rather than exiting the host process.
fn wasi_proc_exit(status: i32) -> Result<(), Trap> {
// Check that the status is within WASI's range.
if status >= 0 && status < 126 {
Err(Trap::i32_exit(status))
} else {
Err(Trap::new(
"exit with invalid exit status outside of [0..126)",
))
}
}

View File

@@ -1,8 +1,6 @@
pub use wasi_common::virtfs; pub use wasi_common::virtfs;
pub use wasi_common::{WasiCtx, WasiCtxBuilder}; pub use wasi_common::{WasiCtx, WasiCtxBuilder};
use crate::wasi_proc_exit;
// Defines a `struct Wasi` with member fields and appropriate APIs for dealing // Defines a `struct Wasi` with member fields and appropriate APIs for dealing
// with all the various WASI exports. // with all the various WASI exports.
wasmtime_wiggle::wasmtime_integration!({ wasmtime_wiggle::wasmtime_integration!({
@@ -25,12 +23,7 @@ modules. This structure exports all that various fields of the wasi instance
as fields which can be used to implement your own instantiation logic, if as fields which can be used to implement your own instantiation logic, if
necessary. Additionally [`Wasi::get_export`] can be used to do name-based necessary. Additionally [`Wasi::get_export`] can be used to do name-based
resolution.", resolution.",
// Don't use the wiggle generated code to implement proc_exit, we need }
// to hook directly into the runtime there:
function_override: {
proc_exit => wasi_proc_exit
}
},
}, },
}); });

View File

@@ -5,3 +5,14 @@ invoked as a Rust procedural macro.
Wiggle is not specialized to any particular WebAssembly runtime. It is usable Wiggle is not specialized to any particular WebAssembly runtime. It is usable
in at least Wasmtime and Lucet. in at least Wasmtime and Lucet.
## Learning more
Read the docs on [docs.rs](https://docs.rs/wiggle/).
There are child crates for [integrating with Wasmtime](https://github.com/bytecodealliance/wasmtime/tree/main/crates/wiggle/wasmtime) and [Lucet](https://github.com/bytecodealliance/lucet/tree/main/lucet-wiggle).
The [wasi-common crate](https://github.com/bytecodealliance/wasmtime/tree/main/crates/wasi-common) is implemented using Wiggle and the [wasmtime-wasi
crate](https://github.com/bytecodealliance/wasmtime/tree/main/crates/wasi) integrates wasi-common with the Wasmtime engine.
Andrew Brown wrote a great [blog post](https://bytecodealliance.org/articles/implementing-wasi-nn-in-wasmtime) on using Wiggle with Wasmtime.

View File

@@ -36,12 +36,6 @@ pub fn define_func(
witx::CoreParamSignifies::Value(atom) => names.atom_type(atom), witx::CoreParamSignifies::Value(atom) => names.atom_type(atom),
_ => unreachable!("ret should always be passed by value"), _ => unreachable!("ret should always be passed by value"),
} }
} else if func.noreturn {
// Ideally we would return `quote!(!)` here, but, we'd have to change
// the error handling logic in all the marshalling code to never return,
// and instead provide some other way to bail to the context...
// noreturn func
unimplemented!("noreturn funcs not supported yet!")
} else { } else {
quote!(()) quote!(())
}; };
@@ -174,25 +168,42 @@ pub fn define_func(
let mod_name = &module.name.as_str(); let mod_name = &module.name.as_str();
let func_name = &func.name.as_str(); let func_name = &func.name.as_str();
quote!(pub fn #ident(#abi_args) -> Result<#abi_ret, String> { if func.noreturn {
let _span = #rt::tracing::span!( quote!(pub fn #ident(#abi_args) -> Result<#abi_ret, wiggle::Trap> {
#rt::tracing::Level::TRACE, let _span = #rt::tracing::span!(
"wiggle abi", #rt::tracing::Level::TRACE,
module = #mod_name, "wiggle abi",
function = #func_name module = #mod_name,
); function = #func_name
let _enter = _span.enter(); );
let _enter = _span.enter();
#(#marshal_args)* #(#marshal_args)*
#(#marshal_rets_pre)* #log_marshalled_args
#log_marshalled_args let trap = #trait_name::#ident(ctx, #(#trait_args),*);
let #trait_bindings = match #trait_name::#ident(ctx, #(#trait_args),*) { Err(trap)
Ok(#trait_bindings) => { #trait_rets }, })
Err(e) => { #ret_err }, } else {
}; quote!(pub fn #ident(#abi_args) -> Result<#abi_ret, wiggle::Trap> {
#(#marshal_rets_post)* let _span = #rt::tracing::span!(
#success #rt::tracing::Level::TRACE,
}) "wiggle abi",
module = #mod_name,
function = #func_name
);
let _enter = _span.enter();
#(#marshal_args)*
#(#marshal_rets_pre)*
#log_marshalled_args
let #trait_bindings = match #trait_name::#ident(ctx, #(#trait_args),*) {
Ok(#trait_bindings) => { #trait_rets },
Err(e) => { #ret_err },
};
#(#marshal_rets_post)*
#success
})
}
} }
fn marshal_arg( fn marshal_arg(

View File

@@ -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 abi_typename = names.type_ref(&errtype.abi_type(), anon_lifetime());
let user_typename = errtype.typename(); let user_typename = errtype.typename();
let methodname = names.user_error_conversion_method(&errtype); let methodname = names.user_error_conversion_method(&errtype);
quote!(fn #methodname(&self, e: super::#user_typename) -> Result<#abi_typename, String>;) quote!(fn #methodname(&self, e: super::#user_typename) -> Result<#abi_typename, wiggle::Trap>;)
}); });
let user_error_conversion = quote! { let user_error_conversion = quote! {
pub trait UserErrorConversion { pub trait UserErrorConversion {

View File

@@ -48,28 +48,34 @@ pub fn define_module_trait(names: &Names, m: &Module, errxform: &ErrorTransform)
}; };
quote!(#arg_name: #arg_type) quote!(#arg_name: #arg_type)
}); });
let rets = f
.results let result = if !f.noreturn {
.iter() let rets = f
.skip(1) .results
.map(|ret| names.type_ref(&ret.tref, lifetime.clone())); .iter()
let err = f .skip(1)
.results .map(|ret| names.type_ref(&ret.tref, lifetime.clone()));
.get(0) let err = f
.map(|err_result| { .results
if let Some(custom_err) = errxform.for_abi_error(&err_result.tref) { .get(0)
let tn = custom_err.typename(); .map(|err_result| {
quote!(super::#tn) if let Some(custom_err) = errxform.for_abi_error(&err_result.tref) {
} else { let tn = custom_err.typename();
names.type_ref(&err_result.tref, lifetime.clone()) quote!(super::#tn)
} } else {
}) names.type_ref(&err_result.tref, lifetime.clone())
.unwrap_or(quote!(())); }
})
.unwrap_or(quote!(()));
quote!( Result<(#(#rets),*), #err> )
} else {
quote!(wiggle::Trap)
};
if is_anonymous { if is_anonymous {
quote!(fn #funcname(&self, #(#args),*) -> Result<(#(#rets),*), #err>;) quote!(fn #funcname(&self, #(#args),*) -> #result; )
} else { } else {
quote!(fn #funcname<#lifetime>(&self, #(#args),*) -> Result<(#(#rets),*), #err>;) quote!(fn #funcname<#lifetime>(&self, #(#args),*) -> #result;)
} }
}); });
quote! { quote! {

View File

@@ -928,3 +928,16 @@ impl Pointee for str {
<[u8]>::debug(pointer, f) <[u8]>::debug(pointer, f)
} }
} }
/// A runtime-independent way for Wiggle to terminate WebAssembly execution.
/// Functions that are marked `(@witx noreturn)` will always return a Trap.
/// Other functions that want to Trap can do so via their `UserErrorConversion`
/// trait, which transforms the user's own error type into a `Result<abierror, Trap>`.
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Trap {
/// A Trap which indicates an i32 (posix-style) exit code. Runtimes may have a
/// special way of dealing with this for WASI embeddings and otherwise.
I32Exit(i32),
/// Any other Trap is just an unstructured String, for reporting and debugging.
String(String),
}

View File

@@ -36,7 +36,7 @@ impl_errno!(types::Errno, types::GuestErrorConversion);
/// When the `errors` mapping in witx is non-empty, we need to impl the /// When the `errors` mapping in witx is non-empty, we need to impl the
/// types::UserErrorConversion trait that wiggle generates from that mapping. /// types::UserErrorConversion trait that wiggle generates from that mapping.
impl<'a> types::UserErrorConversion for WasiCtx<'a> { impl<'a> types::UserErrorConversion for WasiCtx<'a> {
fn errno_from_rich_error(&self, e: RichError) -> Result<types::Errno, String> { fn errno_from_rich_error(&self, e: RichError) -> Result<types::Errno, wiggle::Trap> {
wiggle::tracing::debug!( wiggle::tracing::debug!(
rich_error = wiggle::tracing::field::debug(&e), rich_error = wiggle::tracing::field::debug(&e),
"error conversion" "error conversion"

View File

@@ -34,7 +34,7 @@ mod convert_just_errno {
/// When the `errors` mapping in witx is non-empty, we need to impl the /// When the `errors` mapping in witx is non-empty, we need to impl the
/// types::UserErrorConversion trait that wiggle generates from that mapping. /// types::UserErrorConversion trait that wiggle generates from that mapping.
impl<'a> types::UserErrorConversion for WasiCtx<'a> { impl<'a> types::UserErrorConversion for WasiCtx<'a> {
fn errno_from_rich_error(&self, e: RichError) -> Result<types::Errno, String> { fn errno_from_rich_error(&self, e: RichError) -> Result<types::Errno, wiggle::Trap> {
// WasiCtx can collect a Vec<String> log so we can test this. We're // WasiCtx can collect a Vec<String> log so we can test this. We're
// logging the Display impl that `thiserror::Error` provides us. // logging the Display impl that `thiserror::Error` provides us.
self.log.borrow_mut().push(e.to_string()); self.log.borrow_mut().push(e.to_string());
@@ -115,8 +115,9 @@ mod convert_multiple_error_types {
TooMuchCoffee(usize), TooMuchCoffee(usize),
} }
// Just like the other error, except that we have a second errno type: // Just like the prior test, except that we have a second errno type. This should mean there
// trivial function. // are two functions in UserErrorConversion.
// Additionally, test that the function "baz" marked noreturn always returns a wiggle::Trap.
wiggle::from_witx!({ wiggle::from_witx!({
witx_literal: " witx_literal: "
(typename $errno (enum u8 $ok $invalid_arg $picket_line)) (typename $errno (enum u8 $ok $invalid_arg $picket_line))
@@ -127,7 +128,10 @@ mod convert_multiple_error_types {
(result $err $errno)) (result $err $errno))
(@interface func (export \"bar\") (@interface func (export \"bar\")
(param $drink u32) (param $drink u32)
(result $err $errno2))) (result $err $errno2))
(@interface func (export \"baz\")
(param $drink u32)
(@witx noreturn)))
", ",
ctx: WasiCtx, ctx: WasiCtx,
errors: { errno => RichError, errno2 => AnotherRichError }, errors: { errno => RichError, errno2 => AnotherRichError },
@@ -159,13 +163,13 @@ mod convert_multiple_error_types {
// each member of the `errors` mapping. // each member of the `errors` mapping.
// Bodies elided. // Bodies elided.
impl<'a> types::UserErrorConversion for WasiCtx<'a> { impl<'a> types::UserErrorConversion for WasiCtx<'a> {
fn errno_from_rich_error(&self, _e: RichError) -> Result<types::Errno, String> { fn errno_from_rich_error(&self, _e: RichError) -> Result<types::Errno, wiggle::Trap> {
unimplemented!() unimplemented!()
} }
fn errno2_from_another_rich_error( fn errno2_from_another_rich_error(
&self, &self,
_e: AnotherRichError, _e: AnotherRichError,
) -> Result<types::Errno2, String> { ) -> Result<types::Errno2, wiggle::Trap> {
unimplemented!() unimplemented!()
} }
} }
@@ -178,5 +182,8 @@ mod convert_multiple_error_types {
fn bar(&self, _: u32) -> Result<(), AnotherRichError> { fn bar(&self, _: u32) -> Result<(), AnotherRichError> {
unimplemented!() unimplemented!()
} }
fn baz(&self, _: u32) -> wiggle::Trap {
unimplemented!()
}
} }
} }

View File

@@ -199,8 +199,9 @@ fn generate_func(
#(#arg_names),* #(#arg_names),*
); );
match result { match result {
Ok(r) => {return Ok(r.into());}, Ok(r) => Ok(r.into()),
Err(err) => { return Err(wasmtime::Trap::new(err)); }, Err(wasmtime_wiggle::Trap::String(err)) => Err(wasmtime::Trap::new(err)),
Err(wasmtime_wiggle::Trap::I32Exit(err)) => Err(wasmtime::Trap::i32_exit(err)),
} }
} }
} }

View File

@@ -1,6 +1,7 @@
(module (module
(import "wasi_unstable" "proc_exit" (import "wasi_unstable" "proc_exit"
(func $__wasi_proc_exit (param i32))) (func $__wasi_proc_exit (param i32)))
(memory (export "memory") 0)
(func $_start (func $_start
(call $__wasi_proc_exit (i32.const 125)) (call $__wasi_proc_exit (i32.const 125))
) )

View File

@@ -1,6 +1,7 @@
(module (module
(import "wasi_snapshot_preview1" "proc_exit" (import "wasi_snapshot_preview1" "proc_exit"
(func $__wasi_proc_exit (param i32))) (func $__wasi_proc_exit (param i32)))
(memory (export "memory") 0)
(func $_start (func $_start
(call $__wasi_proc_exit (i32.const 125)) (call $__wasi_proc_exit (i32.const 125))
) )

View File

@@ -1,6 +1,7 @@
(module (module
(import "wasi_unstable" "proc_exit" (import "wasi_unstable" "proc_exit"
(func $__wasi_proc_exit (param i32))) (func $__wasi_proc_exit (param i32)))
(memory (export "memory") 0)
(func $_start (func $_start
(call $__wasi_proc_exit (i32.const 126)) (call $__wasi_proc_exit (i32.const 126))
) )

View File

@@ -1,6 +1,7 @@
(module (module
(import "wasi_snapshot_preview1" "proc_exit" (import "wasi_snapshot_preview1" "proc_exit"
(func $__wasi_proc_exit (param i32))) (func $__wasi_proc_exit (param i32)))
(memory (export "memory") 0)
(func $_start (func $_start
(call $__wasi_proc_exit (i32.const 126)) (call $__wasi_proc_exit (i32.const 126))
) )

View File

@@ -1,6 +1,7 @@
(module (module
(import "wasi_unstable" "proc_exit" (import "wasi_unstable" "proc_exit"
(func $__wasi_proc_exit (param i32))) (func $__wasi_proc_exit (param i32)))
(memory (export "memory") 0)
(func $_start (func $_start
(call $__wasi_proc_exit (i32.const 2)) (call $__wasi_proc_exit (i32.const 2))
) )

View File

@@ -1,6 +1,7 @@
(module (module
(import "wasi_snapshot_preview1" "proc_exit" (import "wasi_snapshot_preview1" "proc_exit"
(func $__wasi_proc_exit (param i32))) (func $__wasi_proc_exit (param i32)))
(memory (export "memory") 0)
(func $_start (func $_start
(call $__wasi_proc_exit (i32.const 2)) (call $__wasi_proc_exit (i32.const 2))
) )

View File

@@ -3,6 +3,7 @@
(type (func (param i32))) (type (func (param i32)))
(import "wasi_snapshot_preview1" "proc_exit" (func (type 0))) (import "wasi_snapshot_preview1" "proc_exit" (func (type 0)))
(memory (export "memory") 0)
(func $exit (param i32) (func $exit (param i32)
local.get 0 local.get 0