Auto-generate the hostcalls module of wasi-common (#846)

* Auto-generate shims for old `wasi_unstable` module

This commit is effectively just doing what #707 already did, but
applying it to the `snapshot_0` module as well. The end result is the
same, where we cut down on all the boilerplate in `snapshot_0` and bring
it in line with the main `wasi_snapshot_preview1` implementation. The
goal here is to make it easier to change the two in tandem since they're
both doing the same thing.

* Migrate `wasi_common::hostcalls` to a macro

This commit migrates the `hostcalls` module to being auto-generated by a
macro rather than duplicating a handwritten signature for each wasi
syscall.

* Auto-generate snapshot_0's `hostcalls` module

Similar to the previous commit, but for `snapshot_0`

* Delete the `wasi-common-cbindgen` crate

This is no longer needed with the hostcalls macro now, we can easily
fold the definition of the cbindgen macro into the same crate.

* Rustfmt

* Fix windows build errors

* Rustfmt

* Remove now no-longer-necessary code

* rustfmt
This commit is contained in:
Alex Crichton
2020-01-22 14:54:39 -06:00
committed by GitHub
parent 5d7635c351
commit 5953215bac
44 changed files with 391 additions and 2742 deletions

View File

@@ -1,4 +1,3 @@
use super::syscalls;
use cranelift_codegen::ir::types;
use cranelift_codegen::{ir, isa};
use cranelift_entity::PrimaryMap;
@@ -6,9 +5,11 @@ use cranelift_wasm::DefinedFuncIndex;
use std::fs::File;
use std::rc::Rc;
use target_lexicon::HOST;
use wasi_common::old::snapshot_0::hostcalls;
use wasi_common::old::snapshot_0::{WasiCtx, WasiCtxBuilder};
use wasi_common::wasi;
use wasmtime_environ::{translate_signature, Export, Module};
use wasmtime_runtime::{Imports, InstanceHandle, InstantiationError, VMFunctionBody};
use wasmtime_runtime::{Imports, InstanceHandle, InstantiationError, VMContext};
/// Creates `wasmtime::Instance` object implementing the "wasi" interface.
pub fn create_wasi_instance(
@@ -59,79 +60,19 @@ pub fn instantiate_wasi_with_context(
) -> Result<InstanceHandle, InstantiationError> {
let pointer_type = types::Type::triple_pointer_type(&HOST);
let mut module = Module::new();
let mut finished_functions: PrimaryMap<DefinedFuncIndex, *const VMFunctionBody> =
PrimaryMap::new();
let mut finished_functions = PrimaryMap::new();
let call_conv = isa::CallConv::triple_default(&HOST);
macro_rules! signature {
($name:ident) => {{
let sig = module.signatures.push(translate_signature(
ir::Signature {
params: syscalls::$name::params()
.into_iter()
.map(ir::AbiParam::new)
.collect(),
returns: syscalls::$name::results()
.into_iter()
.map(ir::AbiParam::new)
.collect(),
call_conv,
},
pointer_type,
));
let func = module.functions.push(sig);
module
.exports
.insert(stringify!($name).to_owned(), Export::Function(func));
finished_functions.push(syscalls::$name::SHIM as *const VMFunctionBody);
}};
}
signature!(args_get);
signature!(args_sizes_get);
signature!(clock_res_get);
signature!(clock_time_get);
signature!(environ_get);
signature!(environ_sizes_get);
signature!(fd_prestat_get);
signature!(fd_prestat_dir_name);
signature!(fd_close);
signature!(fd_datasync);
signature!(fd_pread);
signature!(fd_pwrite);
signature!(fd_read);
signature!(fd_renumber);
signature!(fd_seek);
signature!(fd_tell);
signature!(fd_fdstat_get);
signature!(fd_fdstat_set_flags);
signature!(fd_fdstat_set_rights);
signature!(fd_sync);
signature!(fd_write);
signature!(fd_advise);
signature!(fd_allocate);
signature!(path_create_directory);
signature!(path_link);
signature!(path_open);
signature!(fd_readdir);
signature!(path_readlink);
signature!(path_rename);
signature!(fd_filestat_get);
signature!(fd_filestat_set_times);
signature!(fd_filestat_set_size);
signature!(path_filestat_get);
signature!(path_filestat_set_times);
signature!(path_symlink);
signature!(path_unlink_file);
signature!(path_remove_directory);
signature!(poll_oneoff);
signature!(proc_exit);
signature!(proc_raise);
signature!(random_get);
signature!(sched_yield);
signature!(sock_recv);
signature!(sock_send);
signature!(sock_shutdown);
// This function is defined in the macro invocation of
// `define_add_wrappers_to_module` below. For more information about how
// this works it'd recommended to read the source in
// `crates/wasi-common/wig/src/wasi.rs`.
add_wrappers_to_module(
&mut module,
&mut finished_functions,
call_conv,
pointer_type,
);
let imports = Imports::none();
let data_initializers = Vec::new();
@@ -147,3 +88,41 @@ pub fn instantiate_wasi_with_context(
Box::new(wasi_ctx),
)
}
// Used by `add_wrappers_to_module` defined in the macro above
fn get_wasi_ctx(vmctx: &mut VMContext) -> Result<&mut WasiCtx, wasi::__wasi_errno_t> {
unsafe {
vmctx
.host_state()
.downcast_mut::<WasiCtx>()
.ok_or_else(|| panic!("no host state named WasiCtx available"))
}
}
// Used by `add_wrappers_to_module` defined in the macro above
fn get_memory(caller_vmctx: &mut VMContext) -> Result<&mut [u8], wasi::__wasi_errno_t> {
match unsafe { InstanceHandle::from_vmctx(caller_vmctx) }.lookup("memory") {
Some(wasmtime_runtime::Export::Memory {
definition,
vmctx: _,
memory: _,
}) => unsafe {
let definition = &*definition;
let ptr = definition.base;
let len = definition.current_length;
Ok(std::slice::from_raw_parts_mut(ptr, len))
},
Some(export) => {
log::error!("export named \"memory\" isn't a memory: {:?}", export);
Err(wasi::__WASI_ERRNO_INVAL)
}
None => {
log::error!("no export named \"memory\" available from caller");
Err(wasi::__WASI_ERRNO_INVAL)
}
}
}
wig::define_add_wrappers_to_module!(
"old/snapshot_0" "wasi_unstable"
);

View File

@@ -1,7 +1,6 @@
extern crate alloc;
mod instantiate;
mod syscalls;
pub use instantiate::{create_wasi_instance, instantiate_wasi, instantiate_wasi_with_context};

File diff suppressed because it is too large Load Diff