Change proc_exit to unwind the stack rather than exiting the host process. (#1646)

* Remove Cranelift's OutOfBounds trap, which is no longer used.

* Change proc_exit to unwind instead of exit the host process.

This implements the semantics in https://github.com/WebAssembly/WASI/pull/235.

Fixes #783.
Fixes #993.

* Fix exit-status tests on Windows.

* Revert the wiggle changes and re-introduce the wasi-common implementations.

* Move `wasi_proc_exit` into the wasmtime-wasi crate.

* Revert the spec_testsuite change.

* Remove the old proc_exit implementations.

* Make `TrapReason` an implementation detail.

* Allow exit status 2 on Windows too.

* Fix a documentation link.

* Really fix a documentation link.
This commit is contained in:
Dan Gohman
2020-05-13 15:59:43 -07:00
committed by GitHub
parent 08983bf39c
commit fb0b9e3ae6
27 changed files with 268 additions and 64 deletions

View File

@@ -342,13 +342,6 @@ pub(crate) struct FdEventData<'a> {
pub(crate) userdata: wasi::__wasi_userdata_t,
}
pub(crate) fn proc_exit(_wasi_ctx: &WasiCtx, _memory: &mut [u8], rval: wasi::__wasi_exitcode_t) {
trace!("proc_exit(rval={:?})", rval);
// TODO: Rather than call std::process::exit here, we should trigger a
// stack unwind similar to a trap.
std::process::exit(rval as i32);
}
pub(crate) fn proc_raise(
_wasi_ctx: &WasiCtx,
_memory: &mut [u8],

View File

@@ -813,13 +813,10 @@ impl<'a> WasiSnapshotPreview1 for WasiCtx {
Ok(nevents)
}
// This is just a temporary to ignore the warning which becomes a hard error
// in the CI. Once we figure out non-returns in `wiggle`, this should be gone.
#[allow(unreachable_code)]
fn proc_exit(&self, rval: types::Exitcode) -> std::result::Result<(), ()> {
// TODO: Rather than call std::process::exit here, we should trigger a
// stack unwind similar to a trap.
std::process::exit(rval as i32);
fn proc_exit(&self, _rval: types::Exitcode) -> std::result::Result<(), ()> {
// proc_exit is special in that it's expected to unwind the stack, which
// typically requires runtime-specific logic.
unimplemented!("runtimes are expected to override this implementation")
}
fn proc_raise(&self, _sig: types::Signal) -> Result<()> {

View File

@@ -17,6 +17,13 @@ pub fn define(args: TokenStream) -> TokenStream {
for module in doc.modules() {
for func in module.funcs() {
// `proc_exit` is special; it's essentially an unwinding primitive,
// so we implement it in the runtime rather than use the implementation
// in wasi-common.
if func.name.as_str() == "proc_exit" {
continue;
}
ret.extend(generate_wrappers(&func, old));
}
}

View File

@@ -46,6 +46,15 @@ pub fn define_struct(args: TokenStream) -> TokenStream {
linker_add.push(quote! {
linker.define(#module_name, #name, self.#name_ident.clone())?;
});
// `proc_exit` is special; it's essentially an unwinding primitive,
// so we implement it in the runtime rather than use the implementation
// in wasi-common.
if name == "proc_exit" {
ctor_externs.push(quote! {
let #name_ident = wasmtime::Func::wrap(store, crate::wasi_proc_exit);
});
continue;
}
let mut shim_arg_decls = Vec::new();
let mut params = Vec::new();
@@ -291,6 +300,15 @@ pub fn define_struct_for_wiggle(args: TokenStream) -> TokenStream {
linker_add.push(quote! {
linker.define(#module_name, #name, self.#name_ident.clone())?;
});
// `proc_exit` is special; it's essentially an unwinding primitive,
// so we implement it in the runtime rather than use the implementation
// in wasi-common.
if name == "proc_exit" {
ctor_externs.push(quote! {
let #name_ident = wasmtime::Func::wrap(store, crate::wasi_proc_exit);
});
continue;
}
let mut shim_arg_decls = Vec::new();
let mut params = Vec::new();