diff --git a/lib/runtime-core/src/types.rs b/lib/runtime-core/src/types.rs index 9ee5270dd..d9e983f34 100644 --- a/lib/runtime-core/src/types.rs +++ b/lib/runtime-core/src/types.rs @@ -77,6 +77,19 @@ where { const TYPE: Type; } + +unsafe impl WasmExternType for i8 { + const TYPE: Type = Type::I32; +} +unsafe impl WasmExternType for u8 { + const TYPE: Type = Type::I32; +} +unsafe impl WasmExternType for i16 { + const TYPE: Type = Type::I32; +} +unsafe impl WasmExternType for u16 { + const TYPE: Type = Type::I32; +} unsafe impl WasmExternType for i32 { const TYPE: Type = Type::I32; } diff --git a/lib/wasi/src/lib.rs b/lib/wasi/src/lib.rs index b62f84dfb..3dcb2f7cb 100644 --- a/lib/wasi/src/lib.rs +++ b/lib/wasi/src/lib.rs @@ -1,3 +1,4 @@ +mod ptr; mod state; mod syscalls; mod utils; diff --git a/lib/wasi/src/ptr.rs b/lib/wasi/src/ptr.rs new file mode 100644 index 000000000..efc851858 --- /dev/null +++ b/lib/wasi/src/ptr.rs @@ -0,0 +1,89 @@ +use std::{cell::Cell, fmt, marker::PhantomData, mem}; +use wasmer_runtime_core::{ + memory::Memory, + types::{Type, ValueType, WasmExternType}, +}; + +pub struct Array; +pub struct Item; + +#[repr(transparent)] +pub struct WasmPtr { + offset: u32, + _phantom: PhantomData<(T, Ty)>, +} + +impl WasmPtr { + pub fn new(offset: u32) -> Self { + Self { + offset, + _phantom: PhantomData, + } + } + + pub fn offset(self) -> u32 { + self.offset + } +} + +impl WasmPtr { + pub fn deref<'a>(self, memory: &'a Memory) -> Option<&'a Cell> { + if (self.offset as usize) + mem::size_of::() >= memory.size().bytes().0 { + return None; + } + unsafe { + let cell_ptr = memory + .view::() + .get_unchecked((self.offset() as usize) / mem::size_of::()) + as *const _; + Some(&*cell_ptr) + } + } +} + +impl WasmPtr { + pub fn deref<'a>(self, memory: &'a Memory, length: u32) -> Option<&'a [Cell]> { + if (self.offset as usize) + (mem::size_of::() * (length as usize)) + >= memory.size().bytes().0 + { + return None; + } + + unsafe { + let cell_ptrs = memory.view::().get_unchecked( + ((self.offset() as usize) / mem::size_of::()) + ..((self.offset() as usize) / mem::size_of::()) + (length as usize), + ) as *const _; + Some(&*cell_ptrs) + } + } +} + +unsafe impl WasmExternType for WasmPtr { + const TYPE: Type = Type::I32; +} + +impl Clone for WasmPtr { + fn clone(&self) -> Self { + Self { + offset: self.offset, + _phantom: PhantomData, + } + } +} + +impl Copy for WasmPtr {} + +impl PartialEq for WasmPtr { + fn eq(&self, other: &Self) -> bool { + self.offset == other.offset + } +} + +impl Eq for WasmPtr {} + +impl fmt::Debug for WasmPtr { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "WasmPtr({:#x})", self.offset) + } +} diff --git a/lib/wasi/src/syscalls/mod.rs b/lib/wasi/src/syscalls/mod.rs index 0c5f2f9b0..606c877a2 100644 --- a/lib/wasi/src/syscalls/mod.rs +++ b/lib/wasi/src/syscalls/mod.rs @@ -1,4 +1,12 @@ -use crate::state::WasiState; +#![allow(unused)] + +mod types; + +use self::types::*; +use crate::{ + ptr::{Array, WasmPtr}, + state::WasiState, +}; use wasmer_runtime_core::{memory::Memory, vm::Ctx}; #[allow(clippy::mut_from_ref)] @@ -34,11 +42,13 @@ fn write_buffer_array( /// - `char *argv_buf` /// A pointer to a buffer to write the argument string data. /// -pub fn args_get(ctx: &mut Ctx, ptr_buffer_offset: u32, buffer_offset: u32) { +pub fn args_get(ctx: &mut Ctx, ptr_buffer_offset: u32, buffer_offset: u32) -> __wasi_errno_t { let state = get_wasi_state(ctx); let memory = ctx.memory(0); write_buffer_array(memory, &*state.args, ptr_buffer_offset, buffer_offset); + + __WASI_ESUCCESS } /// ### `args_sizes_get()` @@ -48,7 +58,7 @@ pub fn args_get(ctx: &mut Ctx, ptr_buffer_offset: u32, buffer_offset: u32) { /// The number of arguments. /// - `size_t *argv_buf_size` /// The size of the argument string data. -pub fn args_sizes_get(ctx: &mut Ctx, argc_out: u32, argv_buf_size_out: u32) { +pub fn args_sizes_get(ctx: &mut Ctx, argc_out: u32, argv_buf_size_out: u32) -> __wasi_errno_t { let state = get_wasi_state(ctx); let memory = ctx.memory(0); @@ -57,12 +67,23 @@ pub fn args_sizes_get(ctx: &mut Ctx, argc_out: u32, argv_buf_size_out: u32) { memory.view::()[(argc_out / 4) as usize].set(arg_count as u32); memory.view::()[(argv_buf_size_out / 4) as usize].set(total_arg_size as u32); + + __WASI_ESUCCESS } -pub fn clock_res_get(ctx: &mut Ctx) { +pub fn clock_res_get( + ctx: &mut Ctx, + clock_id: __wasi_clockid_t, + resolution: WasmPtr<__wasi_timestamp_t>, +) -> __wasi_errno_t { unimplemented!() } -pub fn clock_time_get(ctx: &mut Ctx) { +pub fn clock_time_get( + ctx: &mut Ctx, + clock_id: __wasi_clockid_t, + precision: __wasi_timestamp_t, + time: WasmPtr<__wasi_timestamp_t>, +) -> __wasi_errno_t { unimplemented!() } @@ -74,11 +95,13 @@ pub fn clock_time_get(ctx: &mut Ctx) { /// A pointer to a buffer to write the environment variable pointers. /// - `char *environ_buf` /// A pointer to a buffer to write the environment variable string data. -pub fn environ_get(ctx: &mut Ctx, environ: u32, environ_buf: u32) { +pub fn environ_get(ctx: &mut Ctx, environ: u32, environ_buf: u32) -> __wasi_errno_t { let state = get_wasi_state(ctx); let memory = ctx.memory(0); write_buffer_array(memory, &*state.args, environ, environ_buf); + + __WASI_ESUCCESS } /// ### `environ_sizes_get()` @@ -88,7 +111,11 @@ pub fn environ_get(ctx: &mut Ctx, environ: u32, environ_buf: u32) { /// The number of environment variables. /// - `size_t *environ_buf_size` /// The size of the environment variable string data. -pub fn environ_sizes_get(ctx: &mut Ctx, environ_count_out: u32, environ_buf_size_out: u32) { +pub fn environ_sizes_get( + ctx: &mut Ctx, + environ_count_out: u32, + environ_buf_size_out: u32, +) -> __wasi_errno_t { let state = get_wasi_state(ctx); let memory = ctx.memory(0); @@ -97,122 +124,185 @@ pub fn environ_sizes_get(ctx: &mut Ctx, environ_count_out: u32, environ_buf_size memory.view::()[(environ_count_out / 4) as usize].set(env_count as u32); memory.view::()[(environ_buf_size_out / 4) as usize].set(total_env_size as u32); + + __WASI_ESUCCESS } -pub fn fd_advise(ctx: &mut Ctx) { +pub fn fd_advise( + ctx: &mut Ctx, + fd: __wasi_fd_t, + offset: __wasi_filesize_t, + len: __wasi_filesize_t, + advice: __wasi_advice_t, +) -> __wasi_errno_t { unimplemented!() } -pub fn fd_allocate(ctx: &mut Ctx) { +pub fn fd_allocate( + ctx: &mut Ctx, + fd: __wasi_fd_t, + offset: __wasi_filesize_t, + len: __wasi_filesize_t, +) -> __wasi_errno_t { unimplemented!() } -pub fn fd_close(ctx: &mut Ctx) { +pub fn fd_close(ctx: &mut Ctx, fd: __wasi_fd_t) -> __wasi_errno_t { unimplemented!() } -pub fn fd_datasync(ctx: &mut Ctx) { +pub fn fd_datasync(ctx: &mut Ctx, fd: __wasi_fd_t) -> __wasi_errno_t { unimplemented!() } -pub fn fd_fdstat_get(ctx: &mut Ctx) { +pub fn fd_fdstat_get( + ctx: &mut Ctx, + fd: __wasi_fd_t, + buf: WasmPtr<__wasi_fdstat_t>, +) -> __wasi_errno_t { unimplemented!() } -pub fn fd_fdstat_set_flags(ctx: &mut Ctx) { +pub fn fd_fdstat_set_flags( + ctx: &mut Ctx, + fd: __wasi_fd_t, + flags: __wasi_fdflags_t, +) -> __wasi_errno_t { unimplemented!() } -pub fn fd_fdstat_set_rights(ctx: &mut Ctx) { +pub fn fd_fdstat_set_rights( + ctx: &mut Ctx, + fd: __wasi_fd_t, + fs_rights_base: __wasi_rights_t, + fs_rights_inheriting: __wasi_rights_t, +) -> __wasi_errno_t { unimplemented!() } -pub fn fd_filestat_get(ctx: &mut Ctx) { +pub fn fd_filestat_get( + ctx: &mut Ctx, + fd: __wasi_fd_t, + buf: WasmPtr<__wasi_filestat_t>, +) -> __wasi_errno_t { unimplemented!() } -pub fn fd_filestat_set_size(ctx: &mut Ctx) { +pub fn fd_filestat_set_size( + ctx: &mut Ctx, + fd: __wasi_fd_t, + st_size: __wasi_filesize_t, +) -> __wasi_errno_t { unimplemented!() } -pub fn fd_filestat_set_times(ctx: &mut Ctx) { +pub fn fd_filestat_set_times( + ctx: &mut Ctx, + fd: __wasi_fd_t, + st_atim: __wasi_timestamp_t, + st_mtim: __wasi_timestamp_t, + fst_flags: __wasi_fstflags_t, +) -> __wasi_errno_t { unimplemented!() } -pub fn fd_pread(ctx: &mut Ctx) { +pub fn fd_pread( + ctx: &mut Ctx, + fd: __wasi_fd_t, + iovs: WasmPtr<__wasi_iovec_t, Array>, + iovs_len: u32, + offset: __wasi_filesize_t, + nread: WasmPtr, +) -> __wasi_errno_t { unimplemented!() } -pub fn fd_prestat_get(ctx: &mut Ctx) { +pub fn fd_prestat_get( + ctx: &mut Ctx, + fd: __wasi_fd_t, + buf: WasmPtr<__wasi_fdstat_t>, +) -> __wasi_errno_t { unimplemented!() } -pub fn fd_prestat_dir_name(ctx: &mut Ctx) { +pub fn fd_prestat_dir_name( + ctx: &mut Ctx, + fd: __wasi_fd_t, + path: WasmPtr, + path_len: u32, +) -> __wasi_errno_t { unimplemented!() } -pub fn fd_pwrite(ctx: &mut Ctx) { +pub fn fd_pwrite( + ctx: &mut Ctx, + fd: __wasi_fd_t, + iovs: WasmPtr<__wasi_ciovec_t, Array>, + iovs_len: u32, + offset: __wasi_filesize_t, + nwritten: WasmPtr, +) -> __wasi_errno_t { unimplemented!() } -pub fn fd_read(ctx: &mut Ctx) { +pub fn fd_read(ctx: &mut Ctx) -> __wasi_errno_t { unimplemented!() } -pub fn fd_readdir(ctx: &mut Ctx) { +pub fn fd_readdir(ctx: &mut Ctx) -> __wasi_errno_t { unimplemented!() } -pub fn fd_renumber(ctx: &mut Ctx) { +pub fn fd_renumber(ctx: &mut Ctx) -> __wasi_errno_t { unimplemented!() } -pub fn fd_seek(ctx: &mut Ctx) { +pub fn fd_seek(ctx: &mut Ctx) -> __wasi_errno_t { unimplemented!() } -pub fn fd_sync(ctx: &mut Ctx) { +pub fn fd_sync(ctx: &mut Ctx) -> __wasi_errno_t { unimplemented!() } -pub fn fd_tell(ctx: &mut Ctx) { +pub fn fd_tell(ctx: &mut Ctx) -> __wasi_errno_t { unimplemented!() } -pub fn fd_write(ctx: &mut Ctx) { +pub fn fd_write(ctx: &mut Ctx) -> __wasi_errno_t { unimplemented!() } -pub fn path_create_directory(ctx: &mut Ctx) { +pub fn path_create_directory(ctx: &mut Ctx) -> __wasi_errno_t { unimplemented!() } -pub fn path_filestat_get(ctx: &mut Ctx) { +pub fn path_filestat_get(ctx: &mut Ctx) -> __wasi_errno_t { unimplemented!() } -pub fn path_filestat_set_times(ctx: &mut Ctx) { +pub fn path_filestat_set_times(ctx: &mut Ctx) -> __wasi_errno_t { unimplemented!() } -pub fn path_link(ctx: &mut Ctx) { +pub fn path_link(ctx: &mut Ctx) -> __wasi_errno_t { unimplemented!() } -pub fn path_open(ctx: &mut Ctx) { +pub fn path_open(ctx: &mut Ctx) -> __wasi_errno_t { unimplemented!() } -pub fn path_readlink(ctx: &mut Ctx) { +pub fn path_readlink(ctx: &mut Ctx) -> __wasi_errno_t { unimplemented!() } -pub fn path_remove_directory(ctx: &mut Ctx) { +pub fn path_remove_directory(ctx: &mut Ctx) -> __wasi_errno_t { unimplemented!() } -pub fn path_rename(ctx: &mut Ctx) { +pub fn path_rename(ctx: &mut Ctx) -> __wasi_errno_t { unimplemented!() } -pub fn path_symlink(ctx: &mut Ctx) { +pub fn path_symlink(ctx: &mut Ctx) -> __wasi_errno_t { unimplemented!() } -pub fn path_unlink_file(ctx: &mut Ctx) { +pub fn path_unlink_file(ctx: &mut Ctx) -> __wasi_errno_t { unimplemented!() } -pub fn poll_oneoff(ctx: &mut Ctx) { +pub fn poll_oneoff(ctx: &mut Ctx) -> __wasi_errno_t { unimplemented!() } pub fn proc_exit(ctx: &mut Ctx) { unimplemented!() } -pub fn proc_raise(ctx: &mut Ctx) { +pub fn proc_raise(ctx: &mut Ctx) -> __wasi_errno_t { unimplemented!() } -pub fn random_get(ctx: &mut Ctx) { +pub fn random_get(ctx: &mut Ctx) -> __wasi_errno_t { unimplemented!() } -pub fn sched_yield(ctx: &mut Ctx) { +pub fn sched_yield(ctx: &mut Ctx) -> __wasi_errno_t { unimplemented!() } -pub fn sock_recv(ctx: &mut Ctx) { +pub fn sock_recv(ctx: &mut Ctx) -> __wasi_errno_t { unimplemented!() } -pub fn sock_send(ctx: &mut Ctx) { +pub fn sock_send(ctx: &mut Ctx) -> __wasi_errno_t { unimplemented!() } -pub fn sock_shutdown(ctx: &mut Ctx) { +pub fn sock_shutdown(ctx: &mut Ctx) -> __wasi_errno_t { unimplemented!() } diff --git a/lib/wasi/src/syscalls/types.rs b/lib/wasi/src/syscalls/types.rs index 6a927a301..bda4bd1b5 100644 --- a/lib/wasi/src/syscalls/types.rs +++ b/lib/wasi/src/syscalls/types.rs @@ -1,5 +1,8 @@ #![allow(non_camel_case_types)] +use crate::ptr::{Array, WasmPtr}; +use wasmer_runtime_core::types::{ValueError, ValueType}; + pub type __wasi_advice_t = u8; pub const __WASI_ADVICE_DONTNEED: u8 = 0; pub const __WASI_ADVICE_NOREUSE: u8 = 1; @@ -11,7 +14,7 @@ pub const __WASI_ADVICE_WILLNEED: u8 = 5; #[derive(Debug, Copy, Clone, PartialEq, Eq)] #[repr(C)] pub struct __wasi_ciovec_t { - pub buf: u32, + pub buf: WasmPtr, pub buf_len: u32, } @@ -205,7 +208,7 @@ pub type __wasi_inode_t = u64; #[derive(Debug, Copy, Clone, PartialEq, Eq)] #[repr(C)] pub struct __wasi_iovec_t { - pub buf: u32, + pub buf: WasmPtr, pub buf_len: u32, }