Merge remote-tracking branch 'origin/master' into fix/aarch64-cleanup

This commit is contained in:
losfair
2019-12-17 23:27:53 +08:00
8 changed files with 191 additions and 1100 deletions

View File

@ -3,6 +3,7 @@
## **[Unreleased]**
- [#1060](https://github.com/wasmerio/wasmer/pull/1060) Test the capi with all the backends
- [#1069](https://github.com/wasmerio/wasmer/pull/1069) Add function `get_memory_and_data` to `Ctx` to help prevent undefined behavior and mutable aliasing. It allows accessing memory while borrowing data mutably for the `Ctx` lifetime. This new function is now being used in `wasmer-wasi`.
- [#1058](https://github.com/wasmerio/wasmer/pull/1058) Fix minor panic issue when `wasmer::compile_with` called with llvm backend.
- [#858](https://github.com/wasmerio/wasmer/pull/858) Minor panic fix when wasmer binary with `loader` option run a module without exported `_start` function.
- [#1056](https://github.com/wasmerio/wasmer/pull/1056) Improved `--invoke` args parsing (supporting `i32`, `i64`, `f32` and `f32`) in Wasmer CLI

1046
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -32,6 +32,7 @@ pub fn ___cxa_rethrow_primary_exception(_ctx: &mut Ctx, _a: u32) {
/// TODO: We don't have support for exceptions yet
pub fn ___cxa_throw(ctx: &mut Ctx, _ptr: u32, _ty: u32, _destructor: u32) {
debug!("emscripten::___cxa_throw");
eprintln!("Throwing exceptions not yet implemented: aborting!");
_abort(ctx);
}

View File

@ -731,7 +731,7 @@ pub fn generate_emscripten_env(globals: &mut EmscriptenGlobals) -> ImportObject
"___syscall345" => func!(crate::syscalls::___syscall345),
// Process
"abort" => func!(crate::process::_abort),
"abort" => func!(crate::process::em_abort),
"_abort" => func!(crate::process::_abort),
"_prctl" => func!(crate::process::_prctl),
"abortStackOverflow" => func!(crate::process::abort_stack_overflow),

View File

@ -13,6 +13,13 @@ pub fn abort_with_message(ctx: &mut Ctx, message: &str) {
_abort(ctx);
}
/// The name of this call is `abort` but we want to avoid conflicts with libc::abort
pub fn em_abort(ctx: &mut Ctx, arg: u32) {
debug!("emscripten::abort");
eprintln!("Program aborted with value {}", arg);
_abort(ctx);
}
pub fn _abort(_ctx: &mut Ctx) {
debug!("emscripten::_abort");
unsafe {

View File

@ -19,13 +19,13 @@ byteorder = "1"
[target.'cfg(target_arch = "x86_64")'.dependencies.inkwell]
git = "https://github.com/TheDan64/inkwell"
rev = "781620e9fa30e51a6e03bd0d49b5f5bb7a782520"
rev = "0a864ebf68b33d4d514b67796264b03898aa0944"
default-features = false
features = ["llvm8-0", "target-x86"]
[target.'cfg(target_arch = "aarch64")'.dependencies.inkwell]
git = "https://github.com/TheDan64/inkwell"
rev = "781620e9fa30e51a6e03bd0d49b5f5bb7a782520"
rev = "0a864ebf68b33d4d514b67796264b03898aa0944"
default-features = false
features = ["llvm8-0", "target-aarch64"]

View File

@ -195,13 +195,13 @@ unsafe impl Send for Intrinsics {}
unsafe impl Sync for Intrinsics {}
impl Intrinsics {
/// Memory grow offset
/// Offset of the `memory_grow` field.
#[allow(clippy::erasing_op)]
pub fn offset_memory_grow() -> u8 {
pub const fn offset_memory_grow() -> u8 {
(0 * ::std::mem::size_of::<usize>()) as u8
}
/// Memory size offset
pub fn offset_memory_size() -> u8 {
/// Offset of the `memory_size` field.
pub const fn offset_memory_size() -> u8 {
(1 * ::std::mem::size_of::<usize>()) as u8
}
}
@ -401,6 +401,21 @@ impl Ctx {
}
}
/// Get access to [`Memory`] and mutable access to the user defined data
/// field as the type, `T`.
///
/// This method is required to access both at the same time.
/// This is useful for updating a data type that stores information about
/// locations in Wasm memory.
///
/// # Safety
///
/// This function must be called with the same type, `T`, that the `data`
/// was initialized with.
pub unsafe fn memory_and_data_mut<T>(&mut self, mem_index: u32) -> (&Memory, &mut T) {
(self.memory(mem_index), &mut *(self.data as *mut T))
}
/// Gives access to the emscripten symbol map, used for debugging
pub unsafe fn borrow_symbol_map(&self) -> &Option<HashMap<u32, String>> {
&(*self.module).info.em_symbol_map
@ -462,63 +477,63 @@ impl Ctx {
#[doc(hidden)]
impl Ctx {
#[allow(clippy::erasing_op)] // TODO
pub fn offset_memories() -> u8 {
pub const fn offset_memories() -> u8 {
0 * (mem::size_of::<usize>() as u8)
}
pub fn offset_tables() -> u8 {
pub const fn offset_tables() -> u8 {
1 * (mem::size_of::<usize>() as u8)
}
pub fn offset_globals() -> u8 {
pub const fn offset_globals() -> u8 {
2 * (mem::size_of::<usize>() as u8)
}
pub fn offset_imported_memories() -> u8 {
pub const fn offset_imported_memories() -> u8 {
3 * (mem::size_of::<usize>() as u8)
}
pub fn offset_imported_tables() -> u8 {
pub const fn offset_imported_tables() -> u8 {
4 * (mem::size_of::<usize>() as u8)
}
pub fn offset_imported_globals() -> u8 {
pub const fn offset_imported_globals() -> u8 {
5 * (mem::size_of::<usize>() as u8)
}
pub fn offset_imported_funcs() -> u8 {
pub const fn offset_imported_funcs() -> u8 {
6 * (mem::size_of::<usize>() as u8)
}
pub fn offset_signatures() -> u8 {
pub const fn offset_signatures() -> u8 {
7 * (mem::size_of::<usize>() as u8)
}
pub fn offset_intrinsics() -> u8 {
pub const fn offset_intrinsics() -> u8 {
8 * (mem::size_of::<usize>() as u8)
}
pub fn offset_stack_lower_bound() -> u8 {
pub const fn offset_stack_lower_bound() -> u8 {
9 * (mem::size_of::<usize>() as u8)
}
pub fn offset_memory_base() -> u8 {
pub const fn offset_memory_base() -> u8 {
10 * (mem::size_of::<usize>() as u8)
}
pub fn offset_memory_bound() -> u8 {
pub const fn offset_memory_bound() -> u8 {
11 * (mem::size_of::<usize>() as u8)
}
pub fn offset_internals() -> u8 {
pub const fn offset_internals() -> u8 {
12 * (mem::size_of::<usize>() as u8)
}
pub fn offset_interrupt_signal_mem() -> u8 {
pub const fn offset_interrupt_signal_mem() -> u8 {
13 * (mem::size_of::<usize>() as u8)
}
pub fn offset_local_functions() -> u8 {
pub const fn offset_local_functions() -> u8 {
14 * (mem::size_of::<usize>() as u8)
}
}
@ -551,18 +566,18 @@ pub struct FuncCtx {
}
impl FuncCtx {
/// Offset to `vmctx`.
pub fn offset_vmctx() -> u8 {
/// Offset to the `vmctx` field.
pub const fn offset_vmctx() -> u8 {
0 * (mem::size_of::<usize>() as u8)
}
/// Offset to `func_env`.
pub fn offset_func_env() -> u8 {
/// Offset to the `func_env` field.
pub const fn offset_func_env() -> u8 {
1 * (mem::size_of::<usize>() as u8)
}
/// Size of a `FuncCtx`.
pub fn size() -> u8 {
pub const fn size() -> u8 {
mem::size_of::<Self>() as u8
}
}
@ -572,10 +587,10 @@ impl FuncCtx {
#[derive(Debug, Clone)]
#[repr(C)]
pub struct ImportedFunc {
/// Const pointer to `Func`.
/// Pointer to the function itself.
pub(crate) func: *const Func,
/// Mutable non-null pointer to `FuncCtx`.
/// Mutable non-null pointer to [`FuncCtx`].
pub(crate) func_ctx: NonNull<FuncCtx>,
}
@ -585,19 +600,19 @@ pub struct ImportedFunc {
unsafe impl Send for ImportedFunc {}
impl ImportedFunc {
/// Offset to func.
/// Offset to the `func` field.
#[allow(clippy::erasing_op)] // TODO
pub fn offset_func() -> u8 {
pub const fn offset_func() -> u8 {
0 * (mem::size_of::<usize>() as u8)
}
/// Offset to func_ctx.
pub fn offset_func_ctx() -> u8 {
/// Offset to the `func_ctx` field.
pub const fn offset_func_ctx() -> u8 {
1 * (mem::size_of::<usize>() as u8)
}
/// Size of an `ImportedFunc`.
pub fn size() -> u8 {
pub const fn size() -> u8 {
mem::size_of::<Self>() as u8
}
}
@ -618,19 +633,19 @@ pub struct LocalTable {
unsafe impl Send for LocalTable {}
impl LocalTable {
/// Offset to base.
/// Offset to the `base` field.
#[allow(clippy::erasing_op)] // TODO
pub fn offset_base() -> u8 {
pub const fn offset_base() -> u8 {
0 * (mem::size_of::<usize>() as u8)
}
/// Offset count.
pub fn offset_count() -> u8 {
/// Offset to the `count` field.
pub const fn offset_count() -> u8 {
1 * (mem::size_of::<usize>() as u8)
}
/// Size of a `LocalTable`.
pub fn size() -> u8 {
pub const fn size() -> u8 {
mem::size_of::<Self>() as u8
}
}
@ -653,19 +668,19 @@ pub struct LocalMemory {
unsafe impl Send for LocalMemory {}
impl LocalMemory {
/// Offset base.
/// Offset to the `base` field.
#[allow(clippy::erasing_op)] // TODO
pub fn offset_base() -> u8 {
pub const fn offset_base() -> u8 {
0 * (mem::size_of::<usize>() as u8)
}
/// Offset bound.
pub fn offset_bound() -> u8 {
/// Offset to the `bound` field.
pub const fn offset_bound() -> u8 {
1 * (mem::size_of::<usize>() as u8)
}
/// Size of a `LocalMemory`.
pub fn size() -> u8 {
pub const fn size() -> u8 {
mem::size_of::<Self>() as u8
}
}
@ -679,19 +694,19 @@ pub struct LocalGlobal {
}
impl LocalGlobal {
/// Offset data.
/// Offset to the `data` field.
#[allow(clippy::erasing_op)] // TODO
pub fn offset_data() -> u8 {
pub const fn offset_data() -> u8 {
0 * (mem::size_of::<usize>() as u8)
}
/// A null `LocalGlobal`.
pub fn null() -> Self {
pub const fn null() -> Self {
Self { data: 0 }
}
/// Size of a `LocalGlobal`.
pub fn size() -> u8 {
pub const fn size() -> u8 {
mem::size_of::<Self>() as u8
}
}
@ -718,7 +733,7 @@ unsafe impl Send for Anyfunc {}
impl Anyfunc {
/// A null `Anyfunc` value.
pub fn null() -> Self {
pub const fn null() -> Self {
Self {
func: ptr::null(),
ctx: ptr::null_mut(),
@ -726,24 +741,24 @@ impl Anyfunc {
}
}
/// The offset for this func.
/// Offset to the `func` field.
#[allow(clippy::erasing_op)] // TODO
pub fn offset_func() -> u8 {
pub const fn offset_func() -> u8 {
0 * (mem::size_of::<usize>() as u8)
}
/// The offset of the vmctx.
pub fn offset_vmctx() -> u8 {
/// Offset to the `vmctx` field..
pub const fn offset_vmctx() -> u8 {
1 * (mem::size_of::<usize>() as u8)
}
/// The offset of the sig id.
pub fn offset_sig_id() -> u8 {
/// Offset to the `sig_id` field.
pub const fn offset_sig_id() -> u8 {
2 * (mem::size_of::<usize>() as u8)
}
/// The size of `Anyfunc`.
pub fn size() -> u8 {
pub const fn size() -> u8 {
mem::size_of::<Self>() as u8
}
}

View File

@ -31,8 +31,11 @@ pub use windows::*;
/// This function is not safe
#[allow(clippy::mut_from_ref)]
pub(crate) fn get_wasi_state(ctx: &Ctx) -> &mut WasiState {
unsafe { state::get_wasi_state(&mut *(ctx as *const Ctx as *mut Ctx)) }
pub(crate) fn get_memory_and_wasi_state(
ctx: &mut Ctx,
mem_index: u32,
) -> (&Memory, &mut WasiState) {
unsafe { ctx.memory_and_data_mut(mem_index) }
}
fn write_bytes_inner<T: Write>(
@ -134,8 +137,7 @@ pub fn args_get(
argv_buf: WasmPtr<u8, Array>,
) -> __wasi_errno_t {
debug!("wasi::args_get");
let state = get_wasi_state(ctx);
let memory = ctx.memory(0);
let (memory, state) = get_memory_and_wasi_state(ctx, 0);
let result = write_buffer_array(memory, &*state.args, argv, argv_buf);
@ -170,13 +172,11 @@ pub fn args_sizes_get(
argv_buf_size: WasmPtr<u32>,
) -> __wasi_errno_t {
debug!("wasi::args_sizes_get");
let memory = ctx.memory(0);
let (memory, state) = get_memory_and_wasi_state(ctx, 0);
let argc = wasi_try!(argc.deref(memory));
let argv_buf_size = wasi_try!(argv_buf_size.deref(memory));
let state = get_wasi_state(ctx);
let argc_val = state.args.len() as u32;
let argv_buf_size_val = state.args.iter().map(|v| v.len() as u32 + 1).sum();
argc.set(argc_val);
@ -253,8 +253,7 @@ pub fn environ_get(
environ_buf: WasmPtr<u8, Array>,
) -> __wasi_errno_t {
debug!("wasi::environ_get");
let state = get_wasi_state(ctx);
let memory = ctx.memory(0);
let (memory, state) = get_memory_and_wasi_state(ctx, 0);
write_buffer_array(memory, &*state.envs, environ, environ_buf)
}
@ -272,13 +271,11 @@ pub fn environ_sizes_get(
environ_buf_size: WasmPtr<u32>,
) -> __wasi_errno_t {
debug!("wasi::environ_sizes_get");
let memory = ctx.memory(0);
let (memory, state) = get_memory_and_wasi_state(ctx, 0);
let environ_count = wasi_try!(environ_count.deref(memory));
let environ_buf_size = wasi_try!(environ_buf_size.deref(memory));
let state = get_wasi_state(ctx);
let env_var_count = state.envs.len() as u32;
let env_buf_size = state.envs.iter().map(|v| v.len() as u32 + 1).sum();
environ_count.set(env_var_count);
@ -333,8 +330,7 @@ pub fn fd_allocate(
len: __wasi_filesize_t,
) -> __wasi_errno_t {
debug!("wasi::fd_allocate");
let memory = ctx.memory(0);
let state = get_wasi_state(ctx);
let (memory, state) = get_memory_and_wasi_state(ctx, 0);
let fd_entry = wasi_try!(state.fs.get_fd(fd)).clone();
let inode = fd_entry.inode;
@ -376,7 +372,7 @@ pub fn fd_allocate(
pub fn fd_close(ctx: &mut Ctx, fd: __wasi_fd_t) -> __wasi_errno_t {
debug!("wasi::fd_close");
debug!("=> fd={}", fd);
let state = get_wasi_state(ctx);
let (memory, state) = get_memory_and_wasi_state(ctx, 0);
let fd_entry = wasi_try!(state.fs.get_fd(fd)).clone();
@ -392,7 +388,7 @@ pub fn fd_close(ctx: &mut Ctx, fd: __wasi_fd_t) -> __wasi_errno_t {
/// The file descriptor to sync
pub fn fd_datasync(ctx: &mut Ctx, fd: __wasi_fd_t) -> __wasi_errno_t {
debug!("wasi::fd_datasync");
let state = get_wasi_state(ctx);
let (memory, state) = get_memory_and_wasi_state(ctx, 0);
let fd_entry = wasi_try!(state.fs.get_fd(fd)).clone();
if !has_rights(fd_entry.rights, __WASI_RIGHT_FD_DATASYNC) {
return __WASI_EACCES;
@ -423,8 +419,7 @@ pub fn fd_fdstat_get(
fd,
buf_ptr.offset()
);
let mut state = get_wasi_state(ctx);
let memory = ctx.memory(0);
let (memory, state) = get_memory_and_wasi_state(ctx, 0);
let fd_entry = wasi_try!(state.fs.get_fd(fd)).clone();
let stat = wasi_try!(state.fs.fdstat(fd));
@ -448,7 +443,7 @@ pub fn fd_fdstat_set_flags(
flags: __wasi_fdflags_t,
) -> __wasi_errno_t {
debug!("wasi::fd_fdstat_set_flags");
let state = get_wasi_state(ctx);
let (memory, state) = get_memory_and_wasi_state(ctx, 0);
let fd_entry = wasi_try!(state.fs.fd_map.get_mut(&fd).ok_or(__WASI_EBADF));
if !has_rights(fd_entry.rights, __WASI_RIGHT_FD_FDSTAT_SET_FLAGS) {
@ -475,7 +470,7 @@ pub fn fd_fdstat_set_rights(
fs_rights_inheriting: __wasi_rights_t,
) -> __wasi_errno_t {
debug!("wasi::fd_fdstat_set_rights");
let state = get_wasi_state(ctx);
let (memory, state) = get_memory_and_wasi_state(ctx, 0);
let fd_entry = wasi_try!(state.fs.fd_map.get_mut(&fd).ok_or(__WASI_EBADF));
// ensure new rights are a subset of current rights
@ -505,8 +500,7 @@ pub fn fd_filestat_get(
buf: WasmPtr<__wasi_filestat_t>,
) -> __wasi_errno_t {
debug!("wasi::fd_filestat_get");
let mut state = get_wasi_state(ctx);
let memory = ctx.memory(0);
let (memory, state) = get_memory_and_wasi_state(ctx, 0);
let fd_entry = wasi_try!(state.fs.get_fd(fd));
if !has_rights(fd_entry.rights, __WASI_RIGHT_FD_FILESTAT_GET) {
return __WASI_EACCES;
@ -533,8 +527,7 @@ pub fn fd_filestat_set_size(
st_size: __wasi_filesize_t,
) -> __wasi_errno_t {
debug!("wasi::fd_filestat_set_size");
let memory = ctx.memory(0);
let state = get_wasi_state(ctx);
let (memory, state) = get_memory_and_wasi_state(ctx, 0);
let fd_entry = wasi_try!(state.fs.get_fd(fd)).clone();
let inode = fd_entry.inode;
@ -578,7 +571,7 @@ pub fn fd_filestat_set_times(
fst_flags: __wasi_fstflags_t,
) -> __wasi_errno_t {
debug!("wasi::fd_filestat_set_times");
let state = get_wasi_state(ctx);
let (memory, state) = get_memory_and_wasi_state(ctx, 0);
let fd_entry = wasi_try!(state.fs.fd_map.get_mut(&fd).ok_or(__WASI_EBADF));
if !has_rights(fd_entry.rights, __WASI_RIGHT_FD_FILESTAT_SET_TIMES) {
@ -657,11 +650,10 @@ pub fn fd_pread(
nread: WasmPtr<u32>,
) -> __wasi_errno_t {
debug!("wasi::fd_pread");
let memory = ctx.memory(0);
let (memory, state) = get_memory_and_wasi_state(ctx, 0);
let iov_cells = wasi_try!(iovs.deref(memory, 0, iovs_len));
let nread_cell = wasi_try!(nread.deref(memory));
let state = get_wasi_state(ctx);
let bytes_read = match fd {
__WASI_STDIN_FILENO => {
@ -724,11 +716,10 @@ pub fn fd_prestat_get(
buf: WasmPtr<__wasi_prestat_t>,
) -> __wasi_errno_t {
debug!("wasi::fd_prestat_get: fd={}", fd);
let memory = ctx.memory(0);
let (memory, state) = get_memory_and_wasi_state(ctx, 0);
let prestat_ptr = wasi_try!(buf.deref(memory));
let state = get_wasi_state(ctx);
prestat_ptr.set(wasi_try!(state.fs.prestat_fd(fd)));
__WASI_ESUCCESS
@ -744,10 +735,9 @@ pub fn fd_prestat_dir_name(
"wasi::fd_prestat_dir_name: fd={}, path_len={}",
fd, path_len
);
let memory = ctx.memory(0);
let (memory, state) = get_memory_and_wasi_state(ctx, 0);
let path_chars = wasi_try!(path.deref(memory, 0, path_len));
let state = get_wasi_state(ctx);
let real_fd = wasi_try!(state.fs.fd_map.get(&fd).ok_or(__WASI_EBADF));
let inode_val = &state.fs.inodes[real_fd.inode];
@ -805,10 +795,9 @@ pub fn fd_pwrite(
) -> __wasi_errno_t {
debug!("wasi::fd_pwrite");
// TODO: refactor, this is just copied from `fd_write`...
let memory = ctx.memory(0);
let (memory, state) = get_memory_and_wasi_state(ctx, 0);
let iovs_arr_cell = wasi_try!(iovs.deref(memory, 0, iovs_len));
let nwritten_cell = wasi_try!(nwritten.deref(memory));
let state = get_wasi_state(ctx);
let bytes_written = match fd {
__WASI_STDIN_FILENO => return __WASI_EINVAL,
@ -891,11 +880,10 @@ pub fn fd_read(
nread: WasmPtr<u32>,
) -> __wasi_errno_t {
debug!("wasi::fd_read: fd={}", fd);
let memory = ctx.memory(0);
let (memory, state) = get_memory_and_wasi_state(ctx, 0);
let iovs_arr_cell = wasi_try!(iovs.deref(memory, 0, iovs_len));
let nread_cell = wasi_try!(nread.deref(memory));
let state = get_wasi_state(ctx);
let bytes_read = match fd {
__WASI_STDIN_FILENO => {
@ -973,8 +961,7 @@ pub fn fd_readdir(
bufused: WasmPtr<u32>,
) -> __wasi_errno_t {
debug!("wasi::fd_readdir");
let memory = ctx.memory(0);
let state = get_wasi_state(ctx);
let (memory, state) = get_memory_and_wasi_state(ctx, 0);
// TODO: figure out how this is supposed to work;
// is it supposed to pack the buffer full every time until it can't? or do one at a time?
@ -1070,7 +1057,7 @@ pub fn fd_readdir(
/// Location to copy file descriptor to
pub fn fd_renumber(ctx: &mut Ctx, from: __wasi_fd_t, to: __wasi_fd_t) -> __wasi_errno_t {
debug!("wasi::fd_renumber: from={}, to={}", from, to);
let state = get_wasi_state(ctx);
let (memory, state) = get_memory_and_wasi_state(ctx, 0);
let fd_entry = wasi_try!(state.fs.fd_map.get(&from).ok_or(__WASI_EBADF));
let new_fd_entry = Fd {
// TODO: verify this is correct
@ -1103,8 +1090,7 @@ pub fn fd_seek(
newoffset: WasmPtr<__wasi_filesize_t>,
) -> __wasi_errno_t {
debug!("wasi::fd_seek: fd={}, offset={}", fd, offset);
let memory = ctx.memory(0);
let state = get_wasi_state(ctx);
let (memory, state) = get_memory_and_wasi_state(ctx, 0);
let new_offset_cell = wasi_try!(newoffset.deref(memory));
let fd_entry = wasi_try!(state.fs.fd_map.get_mut(&fd).ok_or(__WASI_EBADF));
@ -1163,8 +1149,7 @@ pub fn fd_seek(
pub fn fd_sync(ctx: &mut Ctx, fd: __wasi_fd_t) -> __wasi_errno_t {
debug!("wasi::fd_sync");
debug!("=> fd={}", fd);
let memory = ctx.memory(0);
let state = get_wasi_state(ctx);
let (memory, state) = get_memory_and_wasi_state(ctx, 0);
let fd_entry = wasi_try!(state.fs.get_fd(fd));
if !has_rights(fd_entry.rights, __WASI_RIGHT_FD_SYNC) {
return __WASI_EACCES;
@ -1201,8 +1186,7 @@ pub fn fd_tell(
offset: WasmPtr<__wasi_filesize_t>,
) -> __wasi_errno_t {
debug!("wasi::fd_tell");
let memory = ctx.memory(0);
let state = get_wasi_state(ctx);
let (memory, state) = get_memory_and_wasi_state(ctx, 0);
let offset_cell = wasi_try!(offset.deref(memory));
let fd_entry = wasi_try!(state.fs.fd_map.get_mut(&fd).ok_or(__WASI_EBADF));
@ -1238,10 +1222,9 @@ pub fn fd_write(
nwritten: WasmPtr<u32>,
) -> __wasi_errno_t {
debug!("wasi::fd_write: fd={}", fd);
let memory = ctx.memory(0);
let (memory, state) = get_memory_and_wasi_state(ctx, 0);
let iovs_arr_cell = wasi_try!(iovs.deref(memory, 0, iovs_len));
let nwritten_cell = wasi_try!(nwritten.deref(memory));
let state = get_wasi_state(ctx);
let bytes_written = match fd {
__WASI_STDIN_FILENO => return __WASI_EINVAL,
@ -1264,7 +1247,6 @@ pub fn fd_write(
}
}
_ => {
let state = get_wasi_state(ctx);
let fd_entry = wasi_try!(state.fs.fd_map.get_mut(&fd).ok_or(__WASI_EBADF));
if !has_rights(fd_entry.rights, __WASI_RIGHT_FD_WRITE) {
@ -1325,8 +1307,7 @@ pub fn path_create_directory(
path_len: u32,
) -> __wasi_errno_t {
debug!("wasi::path_create_directory");
let memory = ctx.memory(0);
let state = get_wasi_state(ctx);
let (memory, state) = get_memory_and_wasi_state(ctx, 0);
let working_dir = wasi_try!(state.fs.get_fd(fd)).clone();
if let Kind::Root { .. } = &state.fs.inodes[working_dir.inode].kind {
@ -1431,8 +1412,7 @@ pub fn path_filestat_get(
buf: WasmPtr<__wasi_filestat_t>,
) -> __wasi_errno_t {
debug!("wasi::path_filestat_get");
let state = get_wasi_state(ctx);
let memory = ctx.memory(0);
let (memory, state) = get_memory_and_wasi_state(ctx, 0);
let root_dir = wasi_try!(state.fs.get_fd(fd));
@ -1487,8 +1467,7 @@ pub fn path_filestat_set_times(
fst_flags: __wasi_fstflags_t,
) -> __wasi_errno_t {
debug!("wasi::path_filestat_set_times");
let memory = ctx.memory(0);
let state = get_wasi_state(ctx);
let (memory, state) = get_memory_and_wasi_state(ctx, 0);
let fd_entry = wasi_try!(state.fs.get_fd(fd)).clone();
let fd_inode = fd_entry.inode;
if !has_rights(fd_entry.rights, __WASI_RIGHT_PATH_FILESTAT_SET_TIMES) {
@ -1585,8 +1564,7 @@ pub fn path_link(
if old_flags & __WASI_LOOKUP_SYMLINK_FOLLOW != 0 {
debug!(" - will follow symlinks when opening path");
}
let memory = ctx.memory(0);
let state = get_wasi_state(ctx);
let (memory, state) = get_memory_and_wasi_state(ctx, 0);
let old_path_str = get_input_str!(memory, old_path, old_path_len);
let new_path_str = get_input_str!(memory, new_path, new_path_len);
let source_fd = wasi_try!(state.fs.get_fd(old_fd));
@ -1671,14 +1649,13 @@ pub fn path_open(
if dirflags & __WASI_LOOKUP_SYMLINK_FOLLOW != 0 {
debug!(" - will follow symlinks when opening path");
}
let memory = ctx.memory(0);
let (memory, state) = get_memory_and_wasi_state(ctx, 0);
/* TODO: find actual upper bound on name size (also this is a path, not a name :think-fish:) */
if path_len > 1024 * 1024 {
return __WASI_ENAMETOOLONG;
}
let fd_cell = wasi_try!(fd.deref(memory));
let state = get_wasi_state(ctx);
// o_flags:
// - __WASI_O_CREAT (create if it does not exist)
@ -1900,8 +1877,7 @@ pub fn path_readlink(
buf_used: WasmPtr<u32>,
) -> __wasi_errno_t {
debug!("wasi::path_readlink");
let state = get_wasi_state(ctx);
let memory = ctx.memory(0);
let (memory, state) = get_memory_and_wasi_state(ctx, 0);
let base_dir = wasi_try!(state.fs.fd_map.get(&dir_fd).ok_or(__WASI_EBADF));
if !has_rights(base_dir.rights, __WASI_RIGHT_PATH_READLINK) {
@ -1944,8 +1920,7 @@ pub fn path_remove_directory(
) -> __wasi_errno_t {
// TODO check if fd is a dir, ensure it's within sandbox, etc.
debug!("wasi::path_remove_directory");
let state = get_wasi_state(ctx);
let memory = ctx.memory(0);
let (memory, state) = get_memory_and_wasi_state(ctx, 0);
let base_dir = wasi_try!(state.fs.fd_map.get(&fd), __WASI_EBADF);
let path_str = get_input_str!(memory, path, path_len);
@ -2025,8 +2000,7 @@ pub fn path_rename(
new_path_len: u32,
) -> __wasi_errno_t {
debug!("wasi::path_rename");
let memory = ctx.memory(0);
let state = get_wasi_state(ctx);
let (memory, state) = get_memory_and_wasi_state(ctx, 0);
let source_str = get_input_str!(memory, old_path, old_path_len);
let source_path = std::path::Path::new(source_str);
let target_str = get_input_str!(memory, new_path, new_path_len);
@ -2133,8 +2107,7 @@ pub fn path_symlink(
new_path_len: u32,
) -> __wasi_errno_t {
debug!("wasi::path_symlink");
let state = get_wasi_state(ctx);
let memory = ctx.memory(0);
let (memory, state) = get_memory_and_wasi_state(ctx, 0);
let old_path_str = get_input_str!(memory, old_path, old_path_len);
let new_path_str = get_input_str!(memory, new_path, new_path_len);
let base_fd = wasi_try!(state.fs.get_fd(fd));
@ -2211,8 +2184,7 @@ pub fn path_unlink_file(
path_len: u32,
) -> __wasi_errno_t {
debug!("wasi::path_unlink_file");
let state = get_wasi_state(ctx);
let memory = ctx.memory(0);
let (memory, state) = get_memory_and_wasi_state(ctx, 0);
let base_dir = wasi_try!(state.fs.fd_map.get(&fd).ok_or(__WASI_EBADF));
if !has_rights(base_dir.rights, __WASI_RIGHT_PATH_UNLINK_FILE) {
@ -2308,8 +2280,7 @@ pub fn poll_oneoff(
) -> __wasi_errno_t {
debug!("wasi::poll_oneoff");
debug!(" => nsubscriptions = {}", nsubscriptions);
let memory = ctx.memory(0);
let state = get_wasi_state(ctx);
let (memory, state) = get_memory_and_wasi_state(ctx, 0);
let subscription_array = wasi_try!(in_.deref(memory, 0, nsubscriptions));
let event_array = wasi_try!(out_.deref(memory, 0, nsubscriptions));