mirror of
https://github.com/fluencelabs/wasmer
synced 2024-12-13 06:15:33 +00:00
Add wasi_try macro
This commit is contained in:
parent
23b1d1dd6a
commit
92ec71974b
@ -1,6 +1,8 @@
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
|
||||
#[macro_use]
|
||||
mod macros;
|
||||
mod ptr;
|
||||
mod state;
|
||||
mod syscalls;
|
||||
|
13
lib/wasi/src/macros.rs
Normal file
13
lib/wasi/src/macros.rs
Normal file
@ -0,0 +1,13 @@
|
||||
macro_rules! wasi_try {
|
||||
($expr:expr) => {{
|
||||
let res: Result<_, crate::syscalls::types::__wasi_errno_t> = $expr;
|
||||
match res {
|
||||
Ok(val) => val,
|
||||
Err(err) => return err,
|
||||
}
|
||||
}};
|
||||
($expr:expr; $e:expr) => {{
|
||||
let opt: Option<_> = $expr;
|
||||
wasi_try!(opt.ok_or($e))
|
||||
}};
|
||||
}
|
@ -1,3 +1,4 @@
|
||||
use crate::syscalls::types::{__wasi_errno_t, __WASI_EFAULT};
|
||||
use std::{cell::Cell, fmt, marker::PhantomData, mem};
|
||||
use wasmer_runtime_core::{
|
||||
memory::Memory,
|
||||
@ -30,27 +31,32 @@ impl<T: Copy, Ty> WasmPtr<T, Ty> {
|
||||
|
||||
impl<T: Copy + ValueType> WasmPtr<T, Item> {
|
||||
#[inline]
|
||||
pub fn deref<'a>(self, memory: &'a Memory) -> Option<&'a Cell<T>> {
|
||||
pub fn deref<'a>(self, memory: &'a Memory) -> Result<&'a Cell<T>, __wasi_errno_t> {
|
||||
if (self.offset as usize) + mem::size_of::<T>() >= memory.size().bytes().0 {
|
||||
return None;
|
||||
return Err(__WASI_EFAULT);
|
||||
}
|
||||
unsafe {
|
||||
let cell_ptr = memory
|
||||
.view::<T>()
|
||||
.get_unchecked((self.offset() as usize) / mem::size_of::<T>())
|
||||
as *const _;
|
||||
Some(&*cell_ptr)
|
||||
Ok(&*cell_ptr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy + ValueType> WasmPtr<T, Array> {
|
||||
#[inline]
|
||||
pub fn deref<'a>(self, memory: &'a Memory, index: u32, length: u32) -> Option<&'a [Cell<T>]> {
|
||||
pub fn deref<'a>(
|
||||
self,
|
||||
memory: &'a Memory,
|
||||
index: u32,
|
||||
length: u32,
|
||||
) -> Result<&'a [Cell<T>], __wasi_errno_t> {
|
||||
if (self.offset as usize) + (mem::size_of::<T>() * ((index + length) as usize))
|
||||
>= memory.size().bytes().0
|
||||
{
|
||||
return None;
|
||||
return Err(__WASI_EFAULT);
|
||||
}
|
||||
|
||||
unsafe {
|
||||
@ -59,7 +65,7 @@ impl<T: Copy + ValueType> WasmPtr<T, Array> {
|
||||
..((self.offset() as usize) / mem::size_of::<T>())
|
||||
+ ((index + length) as usize),
|
||||
) as *const _;
|
||||
Some(&*cell_ptrs)
|
||||
Ok(&*cell_ptrs)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -166,31 +166,19 @@ impl WasiFs {
|
||||
path: &str,
|
||||
) -> Result<__wasi_filestat_t, __wasi_errno_t> {
|
||||
warn!("Should use preopned_fd: {}", preopened_fd);
|
||||
let inode = if let Some(inode) = self.get_inode(path) {
|
||||
inode
|
||||
} else {
|
||||
return Err(__WASI_EINVAL);
|
||||
};
|
||||
let inode = self.get_inode(path).ok_or(__WASI_EINVAL)?;
|
||||
|
||||
self.filestat_inode(inode, flags)
|
||||
}
|
||||
|
||||
pub fn filestat_fd(&self, fd: __wasi_fd_t) -> Result<__wasi_filestat_t, __wasi_errno_t> {
|
||||
let fd = if let Some(fd) = self.fd_map.get(&fd) {
|
||||
fd
|
||||
} else {
|
||||
return Err(__WASI_EBADF);
|
||||
};
|
||||
let fd = self.fd_map.get(&fd).ok_or(__WASI_EBADF)?;
|
||||
|
||||
Ok(self.inodes[fd.inode].stat)
|
||||
}
|
||||
|
||||
pub fn fdstat(&self, fd: __wasi_fd_t) -> Result<__wasi_fdstat_t, __wasi_errno_t> {
|
||||
let fd = if let Some(fd) = self.fd_map.get(&fd) {
|
||||
fd
|
||||
} else {
|
||||
return Err(__WASI_EBADF);
|
||||
};
|
||||
let fd = self.fd_map.get(&fd).ok_or(__WASI_EBADF)?;
|
||||
|
||||
Ok(__wasi_fdstat_t {
|
||||
fs_filetype: match self.inodes[fd.inode].kind {
|
||||
|
@ -31,23 +31,13 @@ fn write_buffer_array(
|
||||
ptr_buffer: WasmPtr<WasmPtr<u8, Array>, Array>,
|
||||
buffer: WasmPtr<u8, Array>,
|
||||
) -> __wasi_errno_t {
|
||||
let ptrs = if let Some(cells) = ptr_buffer.deref(memory, 0, from.len() as u32) {
|
||||
cells
|
||||
} else {
|
||||
return __WASI_EOVERFLOW;
|
||||
};
|
||||
let ptrs = wasi_try!(ptr_buffer.deref(memory, 0, from.len() as u32));
|
||||
|
||||
let mut current_buffer_offset = 0;
|
||||
for ((i, sub_buffer), ptr) in from.iter().enumerate().zip(ptrs.iter()) {
|
||||
ptr.set(WasmPtr::new(buffer.offset() + current_buffer_offset));
|
||||
|
||||
let cells = if let Some(cells) =
|
||||
buffer.deref(memory, current_buffer_offset, sub_buffer.len() as u32)
|
||||
{
|
||||
cells
|
||||
} else {
|
||||
return __WASI_EOVERFLOW;
|
||||
};
|
||||
let cells = wasi_try!(buffer.deref(memory, current_buffer_offset, sub_buffer.len() as u32));
|
||||
|
||||
for (cell, &byte) in cells.iter().zip(sub_buffer.iter()) {
|
||||
cell.set(byte);
|
||||
@ -92,16 +82,15 @@ pub fn args_sizes_get(
|
||||
) -> __wasi_errno_t {
|
||||
let memory = ctx.memory(0);
|
||||
|
||||
if let (Some(argc), Some(argv_buf_size)) = (argc.deref(memory), argv_buf_size.deref(memory)) {
|
||||
let state = get_wasi_state(ctx);
|
||||
let argc = wasi_try!(argc.deref(memory));
|
||||
let argv_buf_size = wasi_try!(argv_buf_size.deref(memory));
|
||||
|
||||
argc.set(state.args.len() as u32);
|
||||
argv_buf_size.set(state.args.iter().map(|v| v.len() as u32).sum());
|
||||
let state = get_wasi_state(ctx);
|
||||
|
||||
__WASI_ESUCCESS
|
||||
} else {
|
||||
__WASI_EOVERFLOW
|
||||
}
|
||||
argc.set(state.args.len() as u32);
|
||||
argv_buf_size.set(state.args.iter().map(|v| v.len() as u32).sum());
|
||||
|
||||
__WASI_ESUCCESS
|
||||
}
|
||||
|
||||
/// ### `clock_res_get()`
|
||||
@ -119,11 +108,8 @@ pub fn clock_res_get(
|
||||
) -> __wasi_errno_t {
|
||||
let memory = ctx.memory(0);
|
||||
|
||||
if let Some(out_addr) = resolution.deref(memory) {
|
||||
platform_clock_res_get(clock_id, out_addr)
|
||||
} else {
|
||||
__WASI_EFAULT
|
||||
}
|
||||
let out_addr = wasi_try!(resolution.deref(memory));
|
||||
platform_clock_res_get(clock_id, out_addr)
|
||||
}
|
||||
|
||||
/// ### `clock_time_get()`
|
||||
@ -144,11 +130,8 @@ pub fn clock_time_get(
|
||||
) -> __wasi_errno_t {
|
||||
let memory = ctx.memory(0);
|
||||
|
||||
if let Some(out_addr) = time.deref(memory) {
|
||||
platform_clock_time_get(clock_id, precision, out_addr)
|
||||
} else {
|
||||
__WASI_EFAULT
|
||||
}
|
||||
let out_addr = wasi_try!(time.deref(memory));
|
||||
platform_clock_time_get(clock_id, precision, out_addr)
|
||||
}
|
||||
|
||||
/// ### `environ_get()`
|
||||
@ -184,18 +167,15 @@ pub fn environ_sizes_get(
|
||||
) -> __wasi_errno_t {
|
||||
let memory = ctx.memory(0);
|
||||
|
||||
if let (Some(environ_count), Some(environ_buf_size)) =
|
||||
(environ_count.deref(memory), environ_buf_size.deref(memory))
|
||||
{
|
||||
let state = get_wasi_state(ctx);
|
||||
let environ_count = wasi_try!(environ_count.deref(memory));
|
||||
let environ_buf_size = wasi_try!(environ_buf_size.deref(memory));
|
||||
|
||||
environ_count.set(state.envs.len() as u32);
|
||||
environ_buf_size.set(state.envs.iter().map(|v| v.len() as u32).sum());
|
||||
let state = get_wasi_state(ctx);
|
||||
|
||||
__WASI_ESUCCESS
|
||||
} else {
|
||||
__WASI_EOVERFLOW
|
||||
}
|
||||
environ_count.set(state.envs.len() as u32);
|
||||
environ_buf_size.set(state.envs.iter().map(|v| v.len() as u32).sum());
|
||||
|
||||
__WASI_EOVERFLOW
|
||||
}
|
||||
|
||||
/// ### `fd_advise()`
|
||||
@ -282,17 +262,12 @@ pub fn fd_fdstat_get(
|
||||
let mut state = get_wasi_state(ctx);
|
||||
let memory = ctx.memory(0);
|
||||
|
||||
let stat = match state.fs.fdstat(fd) {
|
||||
Ok(stat) => stat,
|
||||
Err(errno) => return errno,
|
||||
};
|
||||
let stat = wasi_try!(state.fs.fdstat(fd));
|
||||
|
||||
if let Some(buf) = buf.deref(memory) {
|
||||
buf.set(stat);
|
||||
__WASI_ESUCCESS
|
||||
} else {
|
||||
__WASI_EFAULT
|
||||
}
|
||||
let buf = wasi_try!(buf.deref(memory));
|
||||
buf.set(stat);
|
||||
|
||||
__WASI_EFAULT
|
||||
}
|
||||
|
||||
/// ### `fd_fdstat_set_flags()`
|
||||
@ -344,17 +319,12 @@ pub fn fd_filestat_get(
|
||||
let mut state = get_wasi_state(ctx);
|
||||
let memory = ctx.memory(0);
|
||||
|
||||
let stat = match state.fs.filestat_fd(fd) {
|
||||
Ok(stat) => stat,
|
||||
Err(errno) => return errno,
|
||||
};
|
||||
let stat = wasi_try!(state.fs.filestat_fd(fd));
|
||||
|
||||
if let Some(buf) = buf.deref(memory) {
|
||||
buf.set(stat);
|
||||
__WASI_ESUCCESS
|
||||
} else {
|
||||
__WASI_EFAULT
|
||||
}
|
||||
let buf = wasi_try!(buf.deref(memory));
|
||||
buf.set(stat);
|
||||
|
||||
__WASI_ESUCCESS
|
||||
}
|
||||
|
||||
pub fn fd_filestat_set_size(
|
||||
@ -384,7 +354,7 @@ pub fn fd_pread(
|
||||
) -> __wasi_errno_t {
|
||||
let memory = ctx.memory(0);
|
||||
|
||||
if let ((Some(iov_cells), Some(nread_cell))) =
|
||||
if let ((Ok(iov_cells), Ok(nread_cell))) =
|
||||
(iovs.deref(memory, 0, iovs_len), nread.deref(memory))
|
||||
{
|
||||
platform_fd_pread(fd, iov_cells, iovs_len, offset, nread_cell)
|
||||
@ -400,7 +370,7 @@ pub fn fd_prestat_get(
|
||||
) -> __wasi_errno_t {
|
||||
let memory = ctx.memory(0);
|
||||
|
||||
if let Some(prestat_ptr) = buf.deref(memory) {
|
||||
if let Ok(prestat_ptr) = buf.deref(memory) {
|
||||
// open fd
|
||||
// write info to prestat_ptr
|
||||
__WASI_ESUCCESS
|
||||
@ -417,7 +387,7 @@ pub fn fd_prestat_dir_name(
|
||||
) -> __wasi_errno_t {
|
||||
let memory = ctx.memory(0);
|
||||
|
||||
if let Some(path_chars) = path.deref(memory, 0, path_len) {
|
||||
if let Ok(path_chars) = path.deref(memory, 0, path_len) {
|
||||
if true
|
||||
/* check if dir */
|
||||
{
|
||||
@ -467,7 +437,7 @@ pub fn fd_read(
|
||||
|
||||
// check __WASI_RIGHT_FD_READ
|
||||
|
||||
if let (Some(iovs_arr_cell), Some(nwritten_cell)) =
|
||||
if let (Ok(iovs_arr_cell), Ok(nwritten_cell)) =
|
||||
(iovs.deref(memory, 0, iovs_len), nread.deref(memory))
|
||||
{
|
||||
unimplemented!()
|
||||
@ -501,7 +471,7 @@ pub fn fd_readdir(
|
||||
) -> __wasi_errno_t {
|
||||
let memory = ctx.memory(0);
|
||||
|
||||
if let (Some(buf_arr_cell), Some(bufused_cell)) =
|
||||
if let (Ok(buf_arr_cell), Ok(bufused_cell)) =
|
||||
(buf.deref(memory, 0, buf_len), bufused.deref(memory))
|
||||
{
|
||||
unimplemented!()
|
||||
@ -543,7 +513,7 @@ pub fn fd_seek(
|
||||
let memory = ctx.memory(0);
|
||||
// TODO: check __WASI_RIGHT_FD_SEEK
|
||||
// TODO: handle directory input
|
||||
if let Some(new_offset_cell) = newoffset.deref(memory) {
|
||||
if let Ok(new_offset_cell) = newoffset.deref(memory) {
|
||||
unimplemented!()
|
||||
} else {
|
||||
__WASI_EFAULT
|
||||
@ -605,7 +575,7 @@ pub fn fd_write(
|
||||
let memory = ctx.memory(0);
|
||||
// TODO: check __WASI_RIGHT_FD_WRITE
|
||||
// return __WASI_EISDIR if dir (probably)
|
||||
if let (Some(iovs_arr_cell), Some(nwritten_cell)) =
|
||||
if let (Ok(iovs_arr_cell), Ok(nwritten_cell)) =
|
||||
(iovs.deref(memory, 0, iovs_len), nwritten.deref(memory))
|
||||
{
|
||||
unimplemented!()
|
||||
@ -659,6 +629,9 @@ pub fn path_filestat_get(
|
||||
path_len: u32,
|
||||
buf: WasmPtr<__wasi_filestat_t>,
|
||||
) -> __wasi_errno_t {
|
||||
let mut state = get_wasi_state(ctx);
|
||||
let memory = ctx.memory(0);
|
||||
|
||||
// check __WASI_RIGHT_PATH_FILESTAT_GET
|
||||
unimplemented!()
|
||||
}
|
||||
@ -768,7 +741,7 @@ pub fn path_open(
|
||||
|
||||
// check for __WASI_RIGHT_PATH_OPEN somewhere, probably via dirfd
|
||||
|
||||
if let (Some(fd_cell), Some(path_cell)) = (fd.deref(memory), path.deref(memory, 0, path_len)) {
|
||||
if let (Ok(fd_cell), Ok(path_cell)) = (fd.deref(memory), path.deref(memory, 0, path_len)) {
|
||||
// o_flags:
|
||||
// - __WASI_O_FLAG_CREAT (create if it does not exist)
|
||||
// - __WASI_O_DIRECTORY (fail if not dir)
|
||||
@ -860,7 +833,7 @@ pub fn random_get(ctx: &mut Ctx, buf: WasmPtr<u8, Array>, buf_len: u32) -> __was
|
||||
let mut rng = thread_rng();
|
||||
let memory = ctx.memory(0);
|
||||
|
||||
if let Some(buf) = buf.deref(memory, 0, buf_len) {
|
||||
if let Ok(buf) = buf.deref(memory, 0, buf_len) {
|
||||
for i in 0..(buf_len as usize) {
|
||||
let random_byte = rng.gen::<u8>();
|
||||
buf[i].set(random_byte);
|
||||
|
Loading…
Reference in New Issue
Block a user