diff --git a/Cargo.toml b/Cargo.toml index 8a2c7f17dd..1f1b39fae5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,12 +27,16 @@ winapi = { version = "0.3", features=["std", "handleapi", "processthreadsapi", " wasmtime-runtime = { git = "https://github.com/cranestation/wasmtime" } wasmtime-environ = { git = "https://github.com/cranestation/wasmtime" } wasmtime-jit = { git = "https://github.com/cranestation/wasmtime" } +wasmtime-wasi = { git = "https://github.com/cranestation/wasmtime" } cranelift-codegen = "0.30.0" cranelift-entity = "0.30.0" cranelift-wasm = "0.30.0" cranelift-native = "0.30.0" target-lexicon = "0.3.0" +[patch."https://github.com/CraneStation/wasi-common"] +wasi-common = { path = "." } + [lib] name = "wasi_common" crate-type = ["rlib", "staticlib", "cdylib"] diff --git a/tests/runtime/mod.rs b/tests/runtime.rs similarity index 96% rename from tests/runtime/mod.rs rename to tests/runtime.rs index 221203de41..6f0db720d9 100644 --- a/tests/runtime/mod.rs +++ b/tests/runtime.rs @@ -1,7 +1,4 @@ -mod wasi; - use cranelift_codegen::settings; -use cranelift_native; use wasmtime_jit::Context; pub fn instantiate>( @@ -35,7 +32,7 @@ pub fn instantiate>( context.name_instance( "wasi_unstable".to_owned(), - wasi::instantiate_wasi( + wasmtime_wasi::instantiate_wasi( "", global_exports, &get_preopens(workspace)?, diff --git a/tests/runtime/wasi.rs b/tests/runtime/wasi.rs deleted file mode 100644 index e4345d95e3..0000000000 --- a/tests/runtime/wasi.rs +++ /dev/null @@ -1,1157 +0,0 @@ -use cranelift_codegen::ir::types; -use cranelift_codegen::ir::types::{Type, I32, I64}; -use cranelift_codegen::{ir, isa}; -use cranelift_entity::PrimaryMap; -use cranelift_wasm::DefinedFuncIndex; -use std::cell::RefCell; -use std::collections::HashMap; -use std::fs::File; -use std::rc::Rc; -use target_lexicon::HOST; -use wasi_common::memory::enc_errno; -use wasi_common::{host, hostcalls, wasm32, WasiCtx, WasiCtxBuilder}; -use wasmtime_environ::{translate_signature, Module}; -use wasmtime_runtime::VMContext; -use wasmtime_runtime::{Imports, InstanceHandle, InstantiationError, VMFunctionBody}; - -fn get_wasi_ctx(vmctx: &mut VMContext) -> Result<&mut WasiCtx, host::__wasi_errno_t> { - unsafe { - vmctx.host_state().downcast_mut::().ok_or_else(|| { - println!("!!! no host state named WasiCtx available"); - host::__WASI_EINVAL - }) - } -} - -fn get_memory(vmctx: &mut VMContext) -> Result<&mut [u8], host::__wasi_errno_t> { - unsafe { - match vmctx.lookup_global_export("memory") { - Some(wasmtime_runtime::Export::Memory { - definition, - vmctx: _, - memory: _, - }) => Ok(std::slice::from_raw_parts_mut( - (*definition).base, - (*definition).current_length, - )), - x => { - println!( - "!!! no export named __wasi_memory, or the export isn't a mem: {:?}", - x - ); - Err(host::__WASI_EINVAL) - } - } - } -} - -pub trait AbiRet { - type Abi; - fn convert(self) -> Self::Abi; - fn codegen_tys() -> Vec; -} - -pub trait AbiParam { - type Abi; - fn convert(arg: Self::Abi) -> Self; - fn codegen_ty() -> Type; -} - -macro_rules! cast32 { - ($($i:ident)*) => ($( - impl AbiRet for $i { - type Abi = i32; - - fn convert(self) -> Self::Abi { - self as i32 - } - - fn codegen_tys() -> Vec { vec![I32] } - } - - impl AbiParam for $i { - type Abi = i32; - - fn convert(param: i32) -> Self { - param as $i - } - - fn codegen_ty() -> Type { I32 } - } - )*) -} - -macro_rules! cast64 { - ($($i:ident)*) => ($( - impl AbiRet for $i { - type Abi = i64; - - fn convert(self) -> Self::Abi { - self as i64 - } - - fn codegen_tys() -> Vec { vec![I64] } - } - - impl AbiParam for $i { - type Abi = i64; - - fn convert(param: i64) -> Self { - param as $i - } - - fn codegen_ty() -> Type { I64 } - } - )*) -} - -cast32!(i8 i16 i32 u8 u16 u32); -cast64!(i64 u64); - -impl AbiRet for () { - type Abi = (); - fn convert(self) {} - fn codegen_tys() -> Vec { - Vec::new() - } -} - -macro_rules! syscalls { - ($(pub unsafe extern "C" fn $name:ident($ctx:ident: *mut VMContext $(, $arg:ident: $ty:ty)*,) -> $ret:ty { - $($body:tt)* - })*) => ($( - pub mod $name { - use super::*; - - /// Returns the codegen types of all the parameters to the shim - /// generated - pub fn params() -> Vec { - vec![$(<$ty as AbiParam>::codegen_ty()),*] - } - - /// Returns the codegen types of all the results of the shim - /// generated - pub fn results() -> Vec { - <$ret as AbiRet>::codegen_tys() - } - - /// The actual function pointer to the shim for a syscall. - pub static SHIM: unsafe extern "C" fn( - *mut VMContext, - $(<$ty as AbiParam>::Abi),* - ) -> <$ret as AbiRet>::Abi = shim; - - unsafe extern "C" fn shim( - $ctx: *mut VMContext, - $($arg: <$ty as AbiParam>::Abi,)* - ) -> <$ret as AbiRet>::Abi { - let r = super::$name($ctx, $(<$ty as AbiParam>::convert($arg),)*); - <$ret as AbiRet>::convert(r) - } - } - - pub unsafe extern "C" fn $name($ctx: *mut VMContext, $($arg: $ty,)*) -> $ret { - $($body)* - } - )*) -} - -syscalls! { - pub unsafe extern "C" fn args_get( - vmctx: *mut VMContext, - argv: wasm32::uintptr_t, - argv_buf: wasm32::uintptr_t, - ) -> wasm32::__wasi_errno_t { - let wasi_ctx = match get_wasi_ctx(&mut *vmctx) { - Ok(ctx) => ctx, - Err(e) => return enc_errno(e), - }; - - let memory = match get_memory(&mut *vmctx) { - Ok(memory) => memory, - Err(e) => return enc_errno(e), - }; - - hostcalls::args_get(wasi_ctx, memory, argv, argv_buf) - } - - pub unsafe extern "C" fn args_sizes_get( - vmctx: *mut VMContext, - argc: wasm32::uintptr_t, - argv_buf_size: wasm32::uintptr_t, - ) -> wasm32::__wasi_errno_t { - let wasi_ctx = match get_wasi_ctx(&mut *vmctx) { - Ok(ctx) => ctx, - Err(e) => return enc_errno(e), - }; - - let memory = match get_memory(&mut *vmctx) { - Ok(memory) => memory, - Err(e) => return enc_errno(e), - }; - - hostcalls::args_sizes_get(wasi_ctx, memory, argc, argv_buf_size) - } - - pub unsafe extern "C" fn clock_res_get( - vmctx: *mut VMContext, - clock_id: wasm32::__wasi_clockid_t, - resolution: wasm32::uintptr_t, - ) -> wasm32::__wasi_errno_t { - let memory = match get_memory(&mut *vmctx) { - Ok(memory) => memory, - Err(e) => return enc_errno(e), - }; - - hostcalls::clock_res_get(memory, clock_id, resolution) - } - - pub unsafe extern "C" fn clock_time_get( - vmctx: *mut VMContext, - clock_id: wasm32::__wasi_clockid_t, - precision: wasm32::__wasi_timestamp_t, - time: wasm32::uintptr_t, - ) -> wasm32::__wasi_errno_t { - let memory = match get_memory(&mut *vmctx) { - Ok(memory) => memory, - Err(e) => return enc_errno(e), - }; - - hostcalls::clock_time_get(memory, clock_id, precision, time) - } - - pub unsafe extern "C" fn environ_get( - vmctx: *mut VMContext, - environ: wasm32::uintptr_t, - environ_buf: wasm32::uintptr_t, - ) -> wasm32::__wasi_errno_t { - let wasi_ctx = match get_wasi_ctx(&mut *vmctx) { - Ok(ctx) => ctx, - Err(e) => return enc_errno(e), - }; - - let memory = match get_memory(&mut *vmctx) { - Ok(memory) => memory, - Err(e) => return enc_errno(e), - }; - - hostcalls::environ_get(wasi_ctx, memory, environ, environ_buf) - } - - pub unsafe extern "C" fn environ_sizes_get( - vmctx: *mut VMContext, - environ_count: wasm32::uintptr_t, - environ_buf_size: wasm32::uintptr_t, - ) -> wasm32::__wasi_errno_t { - let wasi_ctx = match get_wasi_ctx(&mut *vmctx) { - Ok(ctx) => ctx, - Err(e) => return enc_errno(e), - }; - - let memory = match get_memory(&mut *vmctx) { - Ok(memory) => memory, - Err(e) => return enc_errno(e), - }; - - hostcalls::environ_sizes_get(wasi_ctx, memory, environ_count, environ_buf_size) - } - - pub unsafe extern "C" fn fd_prestat_get( - vmctx: *mut VMContext, - fd: wasm32::__wasi_fd_t, - buf: wasm32::uintptr_t, - ) -> wasm32::__wasi_errno_t { - let wasi_ctx = match get_wasi_ctx(&mut *vmctx) { - Ok(ctx) => ctx, - Err(e) => return enc_errno(e), - }; - - let memory = match get_memory(&mut *vmctx) { - Ok(memory) => memory, - Err(e) => return enc_errno(e), - }; - - hostcalls::fd_prestat_get(wasi_ctx, memory, fd, buf) - } - - pub unsafe extern "C" fn fd_prestat_dir_name( - vmctx: *mut VMContext, - fd: wasm32::__wasi_fd_t, - path: wasm32::uintptr_t, - path_len: wasm32::size_t, - ) -> wasm32::__wasi_errno_t { - let wasi_ctx = match get_wasi_ctx(&mut *vmctx) { - Ok(ctx) => ctx, - Err(e) => return enc_errno(e), - }; - - let memory = match get_memory(&mut *vmctx) { - Ok(memory) => memory, - Err(e) => return enc_errno(e), - }; - - hostcalls::fd_prestat_dir_name(wasi_ctx, memory, fd, path, path_len) - } - - pub unsafe extern "C" fn fd_close( - vmctx: *mut VMContext, - fd: wasm32::__wasi_fd_t, - ) -> wasm32::__wasi_errno_t { - let wasi_ctx = match get_wasi_ctx(&mut *vmctx) { - Ok(ctx) => ctx, - Err(e) => return enc_errno(e), - }; - - hostcalls::fd_close(wasi_ctx, fd) - } - - pub unsafe extern "C" fn fd_datasync( - vmctx: *mut VMContext, - fd: wasm32::__wasi_fd_t, - ) -> wasm32::__wasi_errno_t { - let wasi_ctx = match get_wasi_ctx(&mut *vmctx) { - Ok(ctx) => ctx, - Err(e) => return enc_errno(e), - }; - - hostcalls::fd_datasync(wasi_ctx, fd) - } - - pub unsafe extern "C" fn fd_pread( - vmctx: *mut VMContext, - fd: wasm32::__wasi_fd_t, - iovs: wasm32::uintptr_t, - iovs_len: wasm32::size_t, - offset: wasm32::__wasi_filesize_t, - nread: wasm32::uintptr_t, - ) -> wasm32::__wasi_errno_t { - let wasi_ctx = match get_wasi_ctx(&mut *vmctx) { - Ok(ctx) => ctx, - Err(e) => return enc_errno(e), - }; - - let memory = match get_memory(&mut *vmctx) { - Ok(memory) => memory, - Err(e) => return enc_errno(e), - }; - - hostcalls::fd_pread( - wasi_ctx, - memory, - fd, - iovs, - iovs_len, - offset, - nread - ) - } - - pub unsafe extern "C" fn fd_pwrite( - vmctx: *mut VMContext, - fd: wasm32::__wasi_fd_t, - iovs: wasm32::uintptr_t, - iovs_len: wasm32::size_t, - offset: wasm32::__wasi_filesize_t, - nwritten: wasm32::uintptr_t, - ) -> wasm32::__wasi_errno_t { - let wasi_ctx = match get_wasi_ctx(&mut *vmctx) { - Ok(ctx) => ctx, - Err(e) => return enc_errno(e), - }; - - let memory = match get_memory(&mut *vmctx) { - Ok(memory) => memory, - Err(e) => return enc_errno(e), - }; - - hostcalls::fd_pwrite( - wasi_ctx, - memory, - fd, - iovs, - iovs_len, - offset, - nwritten - ) - } - - pub unsafe extern "C" fn fd_read( - vmctx: *mut VMContext, - fd: wasm32::__wasi_fd_t, - iovs: wasm32::uintptr_t, - iovs_len: wasm32::size_t, - nread: wasm32::uintptr_t, - ) -> wasm32::__wasi_errno_t { - let wasi_ctx = match get_wasi_ctx(&mut *vmctx) { - Ok(ctx) => ctx, - Err(e) => return enc_errno(e), - }; - - let memory = match get_memory(&mut *vmctx) { - Ok(memory) => memory, - Err(e) => return enc_errno(e), - }; - - hostcalls::fd_read(wasi_ctx, memory, fd, iovs, iovs_len, nread) - } - - pub unsafe extern "C" fn fd_renumber( - vmctx: *mut VMContext, - from: wasm32::__wasi_fd_t, - to: wasm32::__wasi_fd_t, - ) -> wasm32::__wasi_errno_t { - let wasi_ctx = match get_wasi_ctx(&mut *vmctx) { - Ok(ctx) => ctx, - Err(e) => return enc_errno(e), - }; - - hostcalls::fd_renumber(wasi_ctx, from, to) - } - - pub unsafe extern "C" fn fd_seek( - vmctx: *mut VMContext, - fd: wasm32::__wasi_fd_t, - offset: wasm32::__wasi_filedelta_t, - whence: wasm32::__wasi_whence_t, - newoffset: wasm32::uintptr_t, - ) -> wasm32::__wasi_errno_t { - let wasi_ctx = match get_wasi_ctx(&mut *vmctx) { - Ok(ctx) => ctx, - Err(e) => return enc_errno(e), - }; - - let memory = match get_memory(&mut *vmctx) { - Ok(memory) => memory, - Err(e) => return enc_errno(e), - }; - - hostcalls::fd_seek(wasi_ctx, memory, fd, offset, whence, newoffset) - } - - pub unsafe extern "C" fn fd_tell( - vmctx: *mut VMContext, - fd: wasm32::__wasi_fd_t, - newoffset: wasm32::uintptr_t, - ) -> wasm32::__wasi_errno_t { - let wasi_ctx = match get_wasi_ctx(&mut *vmctx) { - Ok(ctx) => ctx, - Err(e) => return enc_errno(e), - }; - - let memory = match get_memory(&mut *vmctx) { - Ok(memory) => memory, - Err(e) => return enc_errno(e), - }; - - hostcalls::fd_tell(wasi_ctx, memory, fd, newoffset) - } - - pub unsafe extern "C" fn fd_fdstat_get( - vmctx: *mut VMContext, - fd: wasm32::__wasi_fd_t, - buf: wasm32::uintptr_t, - ) -> wasm32::__wasi_errno_t { - let wasi_ctx = match get_wasi_ctx(&mut *vmctx) { - Ok(ctx) => ctx, - Err(e) => return enc_errno(e), - }; - - let memory = match get_memory(&mut *vmctx) { - Ok(memory) => memory, - Err(e) => return enc_errno(e), - }; - - hostcalls::fd_fdstat_get(wasi_ctx, memory, fd, buf) - } - - pub unsafe extern "C" fn fd_fdstat_set_flags( - vmctx: *mut VMContext, - fd: wasm32::__wasi_fd_t, - flags: wasm32::__wasi_fdflags_t, - ) -> wasm32::__wasi_errno_t { - let wasi_ctx = match get_wasi_ctx(&mut *vmctx) { - Ok(ctx) => ctx, - Err(e) => return enc_errno(e), - }; - - hostcalls::fd_fdstat_set_flags(wasi_ctx, fd, flags) - } - - pub unsafe extern "C" fn fd_fdstat_set_rights( - vmctx: *mut VMContext, - fd: wasm32::__wasi_fd_t, - fs_rights_base: wasm32::__wasi_rights_t, - fs_rights_inheriting: wasm32::__wasi_rights_t, - ) -> wasm32::__wasi_errno_t { - let wasi_ctx = match get_wasi_ctx(&mut *vmctx) { - Ok(ctx) => ctx, - Err(e) => return enc_errno(e), - }; - - hostcalls::fd_fdstat_set_rights( - wasi_ctx, - fd, - fs_rights_base, - fs_rights_inheriting - ) - } - - pub unsafe extern "C" fn fd_sync( - vmctx: *mut VMContext, - fd: wasm32::__wasi_fd_t, - ) -> wasm32::__wasi_errno_t { - let wasi_ctx = match get_wasi_ctx(&mut *vmctx) { - Ok(ctx) => ctx, - Err(e) => return enc_errno(e), - }; - - hostcalls::fd_sync(wasi_ctx, fd) - } - - pub unsafe extern "C" fn fd_write( - vmctx: *mut VMContext, - fd: wasm32::__wasi_fd_t, - iovs: wasm32::uintptr_t, - iovs_len: wasm32::size_t, - nwritten: wasm32::uintptr_t, - ) -> wasm32::__wasi_errno_t { - let wasi_ctx = match get_wasi_ctx(&mut *vmctx) { - Ok(ctx) => ctx, - Err(e) => return enc_errno(e), - }; - - let memory = match get_memory(&mut *vmctx) { - Ok(memory) => memory, - Err(e) => return enc_errno(e), - }; - - hostcalls::fd_write(wasi_ctx, memory, fd, iovs, iovs_len, nwritten) - } - - pub unsafe extern "C" fn fd_advise( - vmctx: *mut VMContext, - fd: wasm32::__wasi_fd_t, - offset: wasm32::__wasi_filesize_t, - len: wasm32::__wasi_filesize_t, - advice: wasm32::__wasi_advice_t, - ) -> wasm32::__wasi_errno_t { - let wasi_ctx = match get_wasi_ctx(&mut *vmctx) { - Ok(ctx) => ctx, - Err(e) => return enc_errno(e), - }; - - hostcalls::fd_advise(wasi_ctx, fd, offset, len, advice) - } - - pub unsafe extern "C" fn fd_allocate( - vmctx: *mut VMContext, - fd: wasm32::__wasi_fd_t, - offset: wasm32::__wasi_filesize_t, - len: wasm32::__wasi_filesize_t, - ) -> wasm32::__wasi_errno_t { - let wasi_ctx = match get_wasi_ctx(&mut *vmctx) { - Ok(ctx) => ctx, - Err(e) => return enc_errno(e), - }; - - hostcalls::fd_allocate(wasi_ctx, fd, offset, len) - } - - pub unsafe extern "C" fn path_create_directory( - vmctx: *mut VMContext, - fd: wasm32::__wasi_fd_t, - path: wasm32::uintptr_t, - path_len: wasm32::size_t, - ) -> wasm32::__wasi_errno_t { - let wasi_ctx = match get_wasi_ctx(&mut *vmctx) { - Ok(ctx) => ctx, - Err(e) => return enc_errno(e), - }; - - let memory = match get_memory(&mut *vmctx) { - Ok(memory) => memory, - Err(e) => return enc_errno(e), - }; - - hostcalls::path_create_directory(wasi_ctx, memory, fd, path, path_len) - } - - pub unsafe extern "C" fn path_link( - vmctx: *mut VMContext, - fd0: wasm32::__wasi_fd_t, - flags0: wasm32::__wasi_lookupflags_t, - path0: wasm32::uintptr_t, - path_len0: wasm32::size_t, - fd1: wasm32::__wasi_fd_t, - path1: wasm32::uintptr_t, - path_len1: wasm32::size_t, - ) -> wasm32::__wasi_errno_t { - let wasi_ctx = match get_wasi_ctx(&mut *vmctx) { - Ok(ctx) => ctx, - Err(e) => return enc_errno(e), - }; - - let memory = match get_memory(&mut *vmctx) { - Ok(memory) => memory, - Err(e) => return enc_errno(e), - }; - - hostcalls::path_link( - wasi_ctx, - memory, - fd0, - flags0, - path0, - path_len0, - fd1, - path1, - path_len1 - ) - } - - pub unsafe extern "C" fn path_open( - vmctx: *mut VMContext, - dirfd: wasm32::__wasi_fd_t, - dirflags: wasm32::__wasi_lookupflags_t, - path: wasm32::uintptr_t, - path_len: wasm32::size_t, - oflags: wasm32::__wasi_oflags_t, - fs_rights_base: wasm32::__wasi_rights_t, - fs_rights_inheriting: wasm32::__wasi_rights_t, - fs_flags: wasm32::__wasi_fdflags_t, - fd: wasm32::uintptr_t, - ) -> wasm32::__wasi_errno_t { - let wasi_ctx = match get_wasi_ctx(&mut *vmctx) { - Ok(ctx) => ctx, - Err(e) => return enc_errno(e), - }; - - let memory = match get_memory(&mut *vmctx) { - Ok(memory) => memory, - Err(e) => return enc_errno(e), - }; - - hostcalls::path_open( - wasi_ctx, - memory, - dirfd, - dirflags, - path, - path_len, - oflags, - fs_rights_base, - fs_rights_inheriting, - fs_flags, - fd - ) - } - - pub unsafe extern "C" fn fd_readdir( - vmctx: *mut VMContext, - fd: wasm32::__wasi_fd_t, - buf: wasm32::uintptr_t, - buf_len: wasm32::size_t, - cookie: wasm32::__wasi_dircookie_t, - buf_used: wasm32::uintptr_t, - ) -> wasm32::__wasi_errno_t { - let wasi_ctx = match get_wasi_ctx(&mut *vmctx) { - Ok(ctx) => ctx, - Err(e) => return enc_errno(e), - }; - - let memory = match get_memory(&mut *vmctx) { - Ok(memory) => memory, - Err(e) => return enc_errno(e), - }; - - hostcalls::fd_readdir( - wasi_ctx, - memory, - fd, - buf, - buf_len, - cookie, - buf_used - ) - } - - pub unsafe extern "C" fn path_readlink( - vmctx: *mut VMContext, - fd: wasm32::__wasi_fd_t, - path: wasm32::uintptr_t, - path_len: wasm32::size_t, - buf: wasm32::uintptr_t, - buf_len: wasm32::size_t, - buf_used: wasm32::uintptr_t, - ) -> wasm32::__wasi_errno_t { - let wasi_ctx = match get_wasi_ctx(&mut *vmctx) { - Ok(ctx) => ctx, - Err(e) => return enc_errno(e), - }; - - let memory = match get_memory(&mut *vmctx) { - Ok(memory) => memory, - Err(e) => return enc_errno(e), - }; - - hostcalls::path_readlink( - wasi_ctx, - memory, - fd, - path, - path_len, - buf, - buf_len, - buf_used - ) - } - - pub unsafe extern "C" fn path_rename( - vmctx: *mut VMContext, - fd0: wasm32::__wasi_fd_t, - path0: wasm32::uintptr_t, - path_len0: wasm32::size_t, - fd1: wasm32::__wasi_fd_t, - path1: wasm32::uintptr_t, - path_len1: wasm32::size_t, - ) -> wasm32::__wasi_errno_t { - let wasi_ctx = match get_wasi_ctx(&mut *vmctx) { - Ok(ctx) => ctx, - Err(e) => return enc_errno(e), - }; - - let memory = match get_memory(&mut *vmctx) { - Ok(memory) => memory, - Err(e) => return enc_errno(e), - }; - - hostcalls::path_rename( - wasi_ctx, - memory, - fd0, - path0, - path_len0, - fd1, - path1, - path_len1 - ) - } - - pub unsafe extern "C" fn fd_filestat_get( - vmctx: *mut VMContext, - fd: wasm32::__wasi_fd_t, - buf: wasm32::uintptr_t, - ) -> wasm32::__wasi_errno_t { - let wasi_ctx = match get_wasi_ctx(&mut *vmctx) { - Ok(ctx) => ctx, - Err(e) => return enc_errno(e), - }; - - let memory = match get_memory(&mut *vmctx) { - Ok(memory) => memory, - Err(e) => return enc_errno(e), - }; - - hostcalls::fd_filestat_get(wasi_ctx, memory, fd, buf) - } - - pub unsafe extern "C" fn fd_filestat_set_times( - vmctx: *mut VMContext, - fd: wasm32::__wasi_fd_t, - st_atim: wasm32::__wasi_timestamp_t, - st_mtim: wasm32::__wasi_timestamp_t, - fstflags: wasm32::__wasi_fstflags_t, - ) -> wasm32::__wasi_errno_t { - let wasi_ctx = match get_wasi_ctx(&mut *vmctx) { - Ok(ctx) => ctx, - Err(e) => return enc_errno(e), - }; - - hostcalls::fd_filestat_set_times(wasi_ctx, fd, st_atim, st_mtim, fstflags) - } - - pub unsafe extern "C" fn fd_filestat_set_size( - vmctx: *mut VMContext, - fd: wasm32::__wasi_fd_t, - size: wasm32::__wasi_filesize_t, - ) -> wasm32::__wasi_errno_t { - let wasi_ctx = match get_wasi_ctx(&mut *vmctx) { - Ok(ctx) => ctx, - Err(e) => return enc_errno(e), - }; - - hostcalls::fd_filestat_set_size(wasi_ctx, fd, size) - } - - pub unsafe extern "C" fn path_filestat_get( - vmctx: *mut VMContext, - fd: wasm32::__wasi_fd_t, - flags: wasm32::__wasi_lookupflags_t, - path: wasm32::uintptr_t, - path_len: wasm32::size_t, - buf: wasm32::uintptr_t, - ) -> wasm32::__wasi_errno_t { - let wasi_ctx = match get_wasi_ctx(&mut *vmctx) { - Ok(ctx) => ctx, - Err(e) => return enc_errno(e), - }; - - let memory = match get_memory(&mut *vmctx) { - Ok(memory) => memory, - Err(e) => return enc_errno(e), - }; - - hostcalls::path_filestat_get(wasi_ctx, memory, fd, flags, path, path_len, buf) - } - - pub unsafe extern "C" fn path_filestat_set_times( - vmctx: *mut VMContext, - fd: wasm32::__wasi_fd_t, - flags: wasm32::__wasi_lookupflags_t, - path: wasm32::uintptr_t, - path_len: wasm32::size_t, - st_atim: wasm32::__wasi_timestamp_t, - st_mtim: wasm32::__wasi_timestamp_t, - fstflags: wasm32::__wasi_fstflags_t, - ) -> wasm32::__wasi_errno_t { - let wasi_ctx = match get_wasi_ctx(&mut *vmctx) { - Ok(ctx) => ctx, - Err(e) => return enc_errno(e), - }; - - let memory = match get_memory(&mut *vmctx) { - Ok(memory) => memory, - Err(e) => return enc_errno(e), - }; - - hostcalls::path_filestat_set_times( - wasi_ctx, - memory, - fd, - flags, - path, - path_len, - st_atim, - st_mtim, - fstflags - ) - } - - pub unsafe extern "C" fn path_symlink( - vmctx: *mut VMContext, - path0: wasm32::uintptr_t, - path_len0: wasm32::size_t, - fd: wasm32::__wasi_fd_t, - path1: wasm32::uintptr_t, - path_len1: wasm32::size_t, - ) -> wasm32::__wasi_errno_t { - let wasi_ctx = match get_wasi_ctx(&mut *vmctx) { - Ok(ctx) => ctx, - Err(e) => return enc_errno(e), - }; - - let memory = match get_memory(&mut *vmctx) { - Ok(memory) => memory, - Err(e) => return enc_errno(e), - }; - - hostcalls::path_symlink( - wasi_ctx, - memory, - path0, - path_len0, - fd, - path1, - path_len1 - ) - } - - pub unsafe extern "C" fn path_unlink_file( - vmctx: *mut VMContext, - fd: wasm32::__wasi_fd_t, - path: wasm32::uintptr_t, - path_len: wasm32::size_t, - ) -> wasm32::__wasi_errno_t { - let wasi_ctx = match get_wasi_ctx(&mut *vmctx) { - Ok(ctx) => ctx, - Err(e) => return enc_errno(e), - }; - - let memory = match get_memory(&mut *vmctx) { - Ok(memory) => memory, - Err(e) => return enc_errno(e), - }; - - hostcalls::path_unlink_file(wasi_ctx, memory, fd, path, path_len) - } - - pub unsafe extern "C" fn path_remove_directory( - vmctx: *mut VMContext, - fd: wasm32::__wasi_fd_t, - path: wasm32::uintptr_t, - path_len: wasm32::size_t, - ) -> wasm32::__wasi_errno_t { - let wasi_ctx = match get_wasi_ctx(&mut *vmctx) { - Ok(ctx) => ctx, - Err(e) => return enc_errno(e), - }; - - let memory = match get_memory(&mut *vmctx) { - Ok(memory) => memory, - Err(e) => return enc_errno(e), - }; - - hostcalls::path_remove_directory(wasi_ctx, memory, fd, path, path_len) - } - - pub unsafe extern "C" fn poll_oneoff( - vmctx: *mut VMContext, - in_: wasm32::uintptr_t, - out: wasm32::uintptr_t, - nsubscriptions: wasm32::size_t, - nevents: wasm32::uintptr_t, - ) -> wasm32::__wasi_errno_t { - let memory = match get_memory(&mut *vmctx) { - Ok(memory) => memory, - Err(e) => return enc_errno(e), - }; - - hostcalls::poll_oneoff(memory, in_, out, nsubscriptions, nevents) - } - - pub unsafe extern "C" fn proc_exit(_vmctx: *mut VMContext, rval: u32,) -> () { - hostcalls::proc_exit(rval) - } - - pub unsafe extern "C" fn proc_raise( - vmctx: *mut VMContext, - sig: wasm32::__wasi_signal_t, - ) -> wasm32::__wasi_errno_t { - let wasi_ctx = match get_wasi_ctx(&mut *vmctx) { - Ok(ctx) => ctx, - Err(e) => return enc_errno(e), - }; - - let memory = match get_memory(&mut *vmctx) { - Ok(memory) => memory, - Err(e) => return enc_errno(e), - }; - - hostcalls::proc_raise(wasi_ctx, memory, sig) - } - - pub unsafe extern "C" fn random_get( - vmctx: *mut VMContext, - buf: wasm32::uintptr_t, - buf_len: wasm32::size_t, - ) -> wasm32::__wasi_errno_t { - let memory = match get_memory(&mut *vmctx) { - Ok(memory) => memory, - Err(e) => return enc_errno(e), - }; - - hostcalls::random_get(memory, buf, buf_len) - } - - pub unsafe extern "C" fn sched_yield(_vmctx: *mut VMContext,) -> wasm32::__wasi_errno_t { - hostcalls::sched_yield() - } - - pub unsafe extern "C" fn sock_recv( - vmctx: *mut VMContext, - sock: wasm32::__wasi_fd_t, - ri_data: wasm32::uintptr_t, - ri_data_len: wasm32::size_t, - ri_flags: wasm32::__wasi_riflags_t, - ro_datalen: wasm32::uintptr_t, - ro_flags: wasm32::uintptr_t, - ) -> wasm32::__wasi_errno_t { - let wasi_ctx = match get_wasi_ctx(&mut *vmctx) { - Ok(ctx) => ctx, - Err(e) => return enc_errno(e), - }; - - let memory = match get_memory(&mut *vmctx) { - Ok(memory) => memory, - Err(e) => return enc_errno(e), - }; - - hostcalls::sock_recv( - wasi_ctx, - memory, - sock, - ri_data, - ri_data_len, - ri_flags, - ro_datalen, - ro_flags - ) - } - - pub unsafe extern "C" fn sock_send( - vmctx: *mut VMContext, - sock: wasm32::__wasi_fd_t, - si_data: wasm32::uintptr_t, - si_data_len: wasm32::size_t, - si_flags: wasm32::__wasi_siflags_t, - so_datalen: wasm32::uintptr_t, - ) -> wasm32::__wasi_errno_t { - let wasi_ctx = match get_wasi_ctx(&mut *vmctx) { - Ok(ctx) => ctx, - Err(e) => return enc_errno(e), - }; - - let memory = match get_memory(&mut *vmctx) { - Ok(memory) => memory, - Err(e) => return enc_errno(e), - }; - - hostcalls::sock_send( - wasi_ctx, - memory, - sock, - si_data, - si_data_len, - si_flags, - so_datalen - ) - } - - pub unsafe extern "C" fn sock_shutdown( - vmctx: *mut VMContext, - sock: wasm32::__wasi_fd_t, - how: wasm32::__wasi_sdflags_t, - ) -> wasm32::__wasi_errno_t { - let wasi_ctx = match get_wasi_ctx(&mut *vmctx) { - Ok(ctx) => ctx, - Err(e) => return enc_errno(e), - }; - - let memory = match get_memory(&mut *vmctx) { - Ok(memory) => memory, - Err(e) => return enc_errno(e), - }; - - hostcalls::sock_shutdown(wasi_ctx, memory, sock, how) - } -} - -pub fn instantiate_wasi( - prefix: &str, - global_exports: Rc>>>, - preopened_dirs: &[(String, File)], - argv: &[String], - environ: &[(String, String)], -) -> Result { - let pointer_type = types::Type::triple_pointer_type(&HOST); - let mut module = Module::new(); - let mut finished_functions: PrimaryMap = - 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: $name::params().into_iter().map(ir::AbiParam::new).collect(), - returns: $name::results() - .into_iter() - .map(ir::AbiParam::new) - .collect(), - call_conv, - }, - pointer_type, - )); - let func = module.functions.push(sig); - module.exports.insert( - prefix.to_owned() + stringify!($name), - wasmtime_environ::Export::Function(func), - ); - finished_functions.push($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); - - let imports = Imports::none(); - let data_initializers = Vec::new(); - let signatures = PrimaryMap::new(); - - let args: Vec<&str> = argv.iter().map(AsRef::as_ref).collect(); - let mut wasi_ctx_builder = WasiCtxBuilder::new().args(&args).inherit_stdio(); - - for (k, v) in environ { - wasi_ctx_builder = wasi_ctx_builder.env(k, v); - } - - for (dir, f) in preopened_dirs { - wasi_ctx_builder = wasi_ctx_builder.preopened_dir( - f.try_clone().map_err(|err| { - InstantiationError::Resource(format!( - "couldn't clone an instance handle to pre-opened dir: {}", - err - )) - })?, - dir, - ); - } - - let wasi_ctx = wasi_ctx_builder.build().map_err(|err| { - InstantiationError::Resource(format!("couldn't assemble WASI context object: {}", err)) - })?; - - InstanceHandle::new( - Rc::new(module), - global_exports, - finished_functions.into_boxed_slice(), - imports, - &data_initializers, - signatures.into_boxed_slice(), - None, - Box::new(wasi_ctx), - ) -}