Make memory fns safe wherever possible

This commit is contained in:
Jakub Konka
2019-05-12 18:13:43 +02:00
committed by Dan Gohman
parent 251504e8a7
commit 8b09f321ac
2 changed files with 108 additions and 141 deletions

View File

@@ -42,7 +42,7 @@ pub fn args_get(
let arg_bytes = arg.as_bytes_with_nul(); let arg_bytes = arg.as_bytes_with_nul();
let arg_ptr = argv_buf + argv_buf_offset; let arg_ptr = argv_buf + argv_buf_offset;
if let Err(e) = unsafe { enc_slice_of(memory, arg_bytes, arg_ptr) } { if let Err(e) = enc_slice_of(memory, arg_bytes, arg_ptr) {
return enc_errno(e); return enc_errno(e);
} }
@@ -58,11 +58,9 @@ pub fn args_get(
} }
} }
unsafe { enc_slice_of(memory, argv.as_slice(), argv_ptr)
enc_slice_of(memory, argv.as_slice(), argv_ptr) .map(|_| wasm32::__WASI_ESUCCESS)
.map(|_| wasm32::__WASI_ESUCCESS) .unwrap_or_else(|e| e)
.unwrap_or_else(|e| e)
}
} }
pub fn args_sizes_get( pub fn args_sizes_get(
@@ -78,13 +76,11 @@ pub fn args_sizes_get(
.map(|arg| arg.as_bytes_with_nul().len()) .map(|arg| arg.as_bytes_with_nul().len())
.sum(); .sum();
unsafe { if let Err(e) = enc_usize_byref(memory, argc_ptr, argc) {
if let Err(e) = enc_usize_byref(memory, argc_ptr, argc) { return enc_errno(e);
return enc_errno(e); }
} if let Err(e) = enc_usize_byref(memory, argv_buf_size_ptr, argv_size) {
if let Err(e) = enc_usize_byref(memory, argv_buf_size_ptr, argv_size) { return enc_errno(e);
return enc_errno(e);
}
} }
wasm32::__WASI_ESUCCESS wasm32::__WASI_ESUCCESS
} }
@@ -115,20 +111,17 @@ pub fn clock_res_get(
(timespec.tv_sec as host::__wasi_timestamp_t) (timespec.tv_sec as host::__wasi_timestamp_t)
.checked_mul(1_000_000_000) .checked_mul(1_000_000_000)
.and_then(|sec_ns| sec_ns.checked_add(timespec.tv_nsec as host::__wasi_timestamp_t)) .and_then(|sec_ns| sec_ns.checked_add(timespec.tv_nsec as host::__wasi_timestamp_t))
.map(|resolution| { .map_or(wasm32::__WASI_EOVERFLOW, |resolution| {
// a supported clock can never return zero; this case will probably never get hit, but // a supported clock can never return zero; this case will probably never get hit, but
// make sure we follow the spec // make sure we follow the spec
if resolution == 0 { if resolution == 0 {
wasm32::__WASI_EINVAL wasm32::__WASI_EINVAL
} else { } else {
unsafe { enc_timestamp_byref(memory, resolution_ptr, resolution)
enc_timestamp_byref(memory, resolution_ptr, resolution) .map(|_| wasm32::__WASI_ESUCCESS)
.map(|_| wasm32::__WASI_ESUCCESS) .unwrap_or_else(|e| e)
.unwrap_or_else(|e| e)
}
} }
}) })
.unwrap_or(wasm32::__WASI_EOVERFLOW)
} }
pub fn clock_time_get( pub fn clock_time_get(
@@ -160,12 +153,11 @@ pub fn clock_time_get(
(timespec.tv_sec as host::__wasi_timestamp_t) (timespec.tv_sec as host::__wasi_timestamp_t)
.checked_mul(1_000_000_000) .checked_mul(1_000_000_000)
.and_then(|sec_ns| sec_ns.checked_add(timespec.tv_nsec as host::__wasi_timestamp_t)) .and_then(|sec_ns| sec_ns.checked_add(timespec.tv_nsec as host::__wasi_timestamp_t))
.map(|time| unsafe { .map_or(wasm32::__WASI_EOVERFLOW, |time| {
enc_timestamp_byref(memory, time_ptr, time) enc_timestamp_byref(memory, time_ptr, time)
.map(|_| wasm32::__WASI_ESUCCESS) .map(|_| wasm32::__WASI_ESUCCESS)
.unwrap_or_else(|e| e) .unwrap_or_else(|e| e)
}) })
.unwrap_or(wasm32::__WASI_EOVERFLOW)
} }
pub fn environ_get( pub fn environ_get(
@@ -181,7 +173,7 @@ pub fn environ_get(
let env_bytes = pair.as_bytes_with_nul(); let env_bytes = pair.as_bytes_with_nul();
let env_ptr = environ_buf + environ_buf_offset; let env_ptr = environ_buf + environ_buf_offset;
if let Err(e) = unsafe { enc_slice_of(memory, env_bytes, env_ptr) } { if let Err(e) = enc_slice_of(memory, env_bytes, env_ptr) {
return enc_errno(e); return enc_errno(e);
} }
@@ -197,11 +189,9 @@ pub fn environ_get(
} }
} }
unsafe { enc_slice_of(memory, environ.as_slice(), environ_ptr)
enc_slice_of(memory, environ.as_slice(), environ_ptr) .map(|_| wasm32::__WASI_ESUCCESS)
.map(|_| wasm32::__WASI_ESUCCESS) .unwrap_or_else(|e| e)
.unwrap_or_else(|e| e)
}
} }
pub fn environ_sizes_get( pub fn environ_sizes_get(
@@ -214,13 +204,11 @@ pub fn environ_sizes_get(
if let Some(environ_size) = wasi_ctx.env.iter().try_fold(0, |acc: u32, pair| { if let Some(environ_size) = wasi_ctx.env.iter().try_fold(0, |acc: u32, pair| {
acc.checked_add(pair.as_bytes_with_nul().len() as u32) acc.checked_add(pair.as_bytes_with_nul().len() as u32)
}) { }) {
unsafe { if let Err(e) = enc_usize_byref(memory, environ_count_ptr, environ_count) {
if let Err(e) = enc_usize_byref(memory, environ_count_ptr, environ_count) { return enc_errno(e);
return enc_errno(e); }
} if let Err(e) = enc_usize_byref(memory, environ_size_ptr, environ_size as usize) {
if let Err(e) = enc_usize_byref(memory, environ_size_ptr, environ_size as usize) { return enc_errno(e);
return enc_errno(e);
}
} }
wasm32::__WASI_ESUCCESS wasm32::__WASI_ESUCCESS
} else { } else {
@@ -254,7 +242,7 @@ pub fn fd_fdstat_get(
fdstat_ptr: wasm32::uintptr_t, // *mut wasm32::__wasi_fdstat_t fdstat_ptr: wasm32::uintptr_t, // *mut wasm32::__wasi_fdstat_t
) -> wasm32::__wasi_errno_t { ) -> wasm32::__wasi_errno_t {
let host_fd = dec_fd(fd); let host_fd = dec_fd(fd);
let mut host_fdstat = match unsafe { dec_fdstat_byref(memory, fdstat_ptr) } { let mut host_fdstat = match dec_fdstat_byref(memory, fdstat_ptr) {
Ok(host_fdstat) => host_fdstat, Ok(host_fdstat) => host_fdstat,
Err(e) => return enc_errno(e), Err(e) => return enc_errno(e),
}; };
@@ -275,10 +263,8 @@ pub fn fd_fdstat_get(
wasm32::__WASI_EBADF wasm32::__WASI_EBADF
}; };
unsafe { enc_fdstat_byref(memory, fdstat_ptr, host_fdstat)
enc_fdstat_byref(memory, fdstat_ptr, host_fdstat) .expect("can write back into the pointer we read from");
.expect("can write back into the pointer we read from");
}
errno errno
} }
@@ -337,11 +323,9 @@ pub fn fd_seek(
} }
}; };
unsafe { enc_filesize_byref(memory, newoffset, host_newoffset as u64)
enc_filesize_byref(memory, newoffset, host_newoffset as u64) .map(|_| wasm32::__WASI_ESUCCESS)
.map(|_| wasm32::__WASI_ESUCCESS) .unwrap_or_else(|e| e)
.unwrap_or_else(|e| e)
}
} }
pub fn fd_prestat_get( pub fn fd_prestat_get(
@@ -358,23 +342,20 @@ pub fn fd_prestat_get(
if fe.fd_object.ty != host::__WASI_FILETYPE_DIRECTORY { if fe.fd_object.ty != host::__WASI_FILETYPE_DIRECTORY {
return wasm32::__WASI_ENOTDIR; return wasm32::__WASI_ENOTDIR;
} }
unsafe { enc_prestat_byref(
enc_prestat_byref( memory,
memory, prestat_ptr,
prestat_ptr, host::__wasi_prestat_t {
host::__wasi_prestat_t { pr_type: host::__WASI_PREOPENTYPE_DIR,
pr_type: host::__WASI_PREOPENTYPE_DIR, u: host::__wasi_prestat_t___wasi_prestat_u {
u: host::__wasi_prestat_t___wasi_prestat_u { dir: host::__wasi_prestat_t___wasi_prestat_u___wasi_prestat_u_dir_t {
dir: pr_name_len: po_path.as_os_str().as_bytes().len(),
host::__wasi_prestat_t___wasi_prestat_u___wasi_prestat_u_dir_t {
pr_name_len: po_path.as_os_str().as_bytes().len(),
},
}, },
}, },
) },
.map(|_| wasm32::__WASI_ESUCCESS) )
.unwrap_or_else(|e| e) .map(|_| wasm32::__WASI_ESUCCESS)
} .unwrap_or_else(|e| e)
} else { } else {
wasm32::__WASI_ENOTSUP wasm32::__WASI_ENOTSUP
} }
@@ -402,11 +383,9 @@ pub fn fd_prestat_dir_name(
if path_bytes.len() > dec_usize(path_len) { if path_bytes.len() > dec_usize(path_len) {
return wasm32::__WASI_ENAMETOOLONG; return wasm32::__WASI_ENAMETOOLONG;
} }
unsafe { enc_slice_of(memory, path_bytes, path_ptr)
enc_slice_of(memory, path_bytes, path_ptr) .map(|_| wasm32::__WASI_ESUCCESS)
.map(|_| wasm32::__WASI_ESUCCESS) .unwrap_or_else(|e| e)
.unwrap_or_else(|e| e)
}
} else { } else {
wasm32::__WASI_ENOTSUP wasm32::__WASI_ENOTSUP
} }
@@ -426,7 +405,7 @@ pub fn fd_read(
use nix::sys::uio::{readv, IoVec}; use nix::sys::uio::{readv, IoVec};
let fd = dec_fd(fd); let fd = dec_fd(fd);
let mut iovs = match unsafe { dec_ciovec_slice(memory, iovs_ptr, iovs_len) } { let mut iovs = match dec_ciovec_slice(memory, iovs_ptr, iovs_len) {
Ok(iovs) => iovs, Ok(iovs) => iovs,
Err(e) => return enc_errno(e), Err(e) => return enc_errno(e),
}; };
@@ -452,11 +431,9 @@ pub fn fd_read(
fe.fd_object.needs_close = false; fe.fd_object.needs_close = false;
} }
unsafe { enc_usize_byref(memory, nread, host_nread)
enc_usize_byref(memory, nread, host_nread) .map(|_| wasm32::__WASI_ESUCCESS)
.map(|_| wasm32::__WASI_ESUCCESS) .unwrap_or_else(|e| e)
.unwrap_or_else(|e| e)
}
} }
pub fn fd_write( pub fn fd_write(
@@ -470,7 +447,7 @@ pub fn fd_write(
use nix::sys::uio::{writev, IoVec}; use nix::sys::uio::{writev, IoVec};
let fd = dec_fd(fd); let fd = dec_fd(fd);
let iovs = match unsafe { dec_ciovec_slice(memory, iovs_ptr, iovs_len) } { let iovs = match dec_ciovec_slice(memory, iovs_ptr, iovs_len) {
Ok(iovs) => iovs, Ok(iovs) => iovs,
Err(e) => return enc_errno(e), Err(e) => return enc_errno(e),
}; };
@@ -490,11 +467,9 @@ pub fn fd_write(
Err(e) => return wasm32::errno_from_nix(e.as_errno().unwrap()), Err(e) => return wasm32::errno_from_nix(e.as_errno().unwrap()),
}; };
unsafe { enc_usize_byref(memory, nwritten, host_nwritten)
enc_usize_byref(memory, nwritten, host_nwritten) .map(|_| wasm32::__WASI_ESUCCESS)
.map(|_| wasm32::__WASI_ESUCCESS) .unwrap_or_else(|e| e)
.unwrap_or_else(|e| e)
}
} }
pub fn path_open( pub fn path_open(
@@ -564,7 +539,7 @@ pub fn path_open(
needed_inheriting |= host::__WASI_RIGHT_FD_SYNC; needed_inheriting |= host::__WASI_RIGHT_FD_SYNC;
} }
let path = match unsafe { dec_slice_of::<u8>(memory, path_ptr, path_len) } { let path = match dec_slice_of::<u8>(memory, path_ptr, path_len) {
Ok((ptr, len)) => OsStr::from_bytes(unsafe { std::slice::from_raw_parts(ptr, len) }), Ok((ptr, len)) => OsStr::from_bytes(unsafe { std::slice::from_raw_parts(ptr, len) }),
Err(e) => return enc_errno(e), Err(e) => return enc_errno(e),
}; };
@@ -630,11 +605,9 @@ pub fn path_open(
} }
}; };
unsafe { enc_fd_byref(memory, fd_out_ptr, guest_fd)
enc_fd_byref(memory, fd_out_ptr, guest_fd) .map(|_| wasm32::__WASI_ESUCCESS)
.map(|_| wasm32::__WASI_ESUCCESS) .unwrap_or_else(|e| e)
.unwrap_or_else(|e| e)
}
} }
pub fn random_get( pub fn random_get(
@@ -645,7 +618,7 @@ pub fn random_get(
use rand::{thread_rng, RngCore}; use rand::{thread_rng, RngCore};
let buf_len = dec_usize(buf_len); let buf_len = dec_usize(buf_len);
let buf_ptr = match unsafe { dec_ptr(memory, buf_ptr, buf_len) } { let buf_ptr = match dec_ptr(memory, buf_ptr, buf_len) {
Ok(ptr) => ptr, Ok(ptr) => ptr,
Err(e) => return enc_errno(e), Err(e) => return enc_errno(e),
}; };
@@ -667,14 +640,13 @@ pub fn poll_oneoff(
if nsubscriptions as u64 > wasm32::__wasi_filesize_t::max_value() { if nsubscriptions as u64 > wasm32::__wasi_filesize_t::max_value() {
return wasm32::__WASI_EINVAL; return wasm32::__WASI_EINVAL;
} }
unsafe { enc_pointee(memory, nevents, 0) }.unwrap(); enc_pointee(memory, nevents, 0).unwrap();
let input_slice_ = let input_slice_ =
unsafe { dec_slice_of::<wasm32::__wasi_subscription_t>(memory, input, nsubscriptions) } dec_slice_of::<wasm32::__wasi_subscription_t>(memory, input, nsubscriptions).unwrap();
.unwrap();
let input_slice = unsafe { slice::from_raw_parts(input_slice_.0, input_slice_.1) }; let input_slice = unsafe { slice::from_raw_parts(input_slice_.0, input_slice_.1) };
let output_slice_ = let output_slice_ =
unsafe { dec_slice_of::<wasm32::__wasi_event_t>(memory, output, nsubscriptions) }.unwrap(); dec_slice_of::<wasm32::__wasi_event_t>(memory, output, nsubscriptions).unwrap();
let output_slice = unsafe { slice::from_raw_parts_mut(output_slice_.0, output_slice_.1) }; let output_slice = unsafe { slice::from_raw_parts_mut(output_slice_.0, output_slice_.1) };
let input: Vec<_> = input_slice.iter().map(|x| dec_subscription(x)).collect(); let input: Vec<_> = input_slice.iter().map(|x| dec_subscription(x)).collect();
@@ -727,7 +699,7 @@ pub fn poll_oneoff(
delay: cmp::min(delay, c_int::max_value() as u128), delay: cmp::min(delay, c_int::max_value() as u128),
userdata, userdata,
}); });
let poll_timeout = timeout.map(|timeout| timeout.delay as c_int).unwrap_or(-1); let poll_timeout = timeout.map_or(-1, |timeout| timeout.delay as c_int);
let ready = loop { let ready = loop {
match nix::poll::poll(&mut poll_fds, poll_timeout) { match nix::poll::poll(&mut poll_fds, poll_timeout) {
Err(_) => { Err(_) => {
@@ -761,10 +733,8 @@ pub fn fd_filestat_get(
Err(e) => wasm32::errno_from_nix(e.as_errno().unwrap()), Err(e) => wasm32::errno_from_nix(e.as_errno().unwrap()),
Ok(filestat) => { Ok(filestat) => {
let host_filestat = host::filestat_from_nix(filestat); let host_filestat = host::filestat_from_nix(filestat);
unsafe { enc_filestat_byref(memory, filestat_ptr, host_filestat)
enc_filestat_byref(memory, filestat_ptr, host_filestat) .expect("can write into the pointer");
.expect("can write into the pointer");
}
wasm32::__WASI_ESUCCESS wasm32::__WASI_ESUCCESS
} }
} }
@@ -788,7 +758,7 @@ pub fn path_filestat_get(
let dirfd = dec_fd(dirfd); let dirfd = dec_fd(dirfd);
let dirflags = dec_lookupflags(dirflags); let dirflags = dec_lookupflags(dirflags);
let path = match unsafe { dec_slice_of::<u8>(memory, path_ptr, path_len) } { let path = match dec_slice_of::<u8>(memory, path_ptr, path_len) {
Ok((ptr, len)) => OsStr::from_bytes(unsafe { std::slice::from_raw_parts(ptr, len) }), Ok((ptr, len)) => OsStr::from_bytes(unsafe { std::slice::from_raw_parts(ptr, len) }),
Err(e) => return enc_errno(e), Err(e) => return enc_errno(e),
}; };
@@ -813,10 +783,8 @@ pub fn path_filestat_get(
Err(e) => wasm32::errno_from_nix(e.as_errno().unwrap()), Err(e) => wasm32::errno_from_nix(e.as_errno().unwrap()),
Ok(filestat) => { Ok(filestat) => {
let host_filestat = host::filestat_from_nix(filestat); let host_filestat = host::filestat_from_nix(filestat);
unsafe { enc_filestat_byref(memory, filestat_ptr, host_filestat)
enc_filestat_byref(memory, filestat_ptr, host_filestat) .expect("can write into the pointer");
.expect("can write into the pointer");
}
wasm32::__WASI_ESUCCESS wasm32::__WASI_ESUCCESS
} }
} }
@@ -833,7 +801,7 @@ pub fn path_create_directory(
use nix::libc::mkdirat; use nix::libc::mkdirat;
let dirfd = dec_fd(dirfd); let dirfd = dec_fd(dirfd);
let path = match unsafe { dec_slice_of::<u8>(memory, path_ptr, path_len) } { let path = match dec_slice_of::<u8>(memory, path_ptr, path_len) {
Ok((ptr, len)) => OsStr::from_bytes(unsafe { std::slice::from_raw_parts(ptr, len) }), Ok((ptr, len)) => OsStr::from_bytes(unsafe { std::slice::from_raw_parts(ptr, len) }),
Err(e) => return enc_errno(e), Err(e) => return enc_errno(e),
}; };
@@ -872,7 +840,7 @@ pub fn path_unlink_file(
use nix::libc::unlinkat; use nix::libc::unlinkat;
let dirfd = dec_fd(dirfd); let dirfd = dec_fd(dirfd);
let path = match unsafe { dec_slice_of::<u8>(memory, path_ptr, path_len) } { let path = match dec_slice_of::<u8>(memory, path_ptr, path_len) {
Ok((ptr, len)) => OsStr::from_bytes(unsafe { std::slice::from_raw_parts(ptr, len) }), Ok((ptr, len)) => OsStr::from_bytes(unsafe { std::slice::from_raw_parts(ptr, len) }),
Err(e) => return enc_errno(e), Err(e) => return enc_errno(e),
}; };
@@ -1191,12 +1159,12 @@ fn poll_oneoff_handle_timeout_event(
}, },
}; };
output_slice[0] = enc_event(output_event); output_slice[0] = enc_event(output_event);
if let Err(e) = unsafe { enc_pointee(memory, nevents, 1) } { if let Err(e) = enc_pointee(memory, nevents, 1) {
return enc_errno(e); return enc_errno(e);
} }
} else { } else {
// shouldn't happen // shouldn't happen
if let Err(e) = unsafe { enc_pointee(memory, nevents, 0) } { if let Err(e) = enc_pointee(memory, nevents, 0) {
return enc_errno(e); return enc_errno(e);
} }
} }
@@ -1280,7 +1248,7 @@ fn poll_oneoff_handle_fd_event<'t>(
*output_slice_cur.next().unwrap() = enc_event(output_event); *output_slice_cur.next().unwrap() = enc_event(output_event);
revents_count += 1; revents_count += 1;
} }
if let Err(e) = unsafe { enc_pointee(memory, nevents, revents_count) } { if let Err(e) = enc_pointee(memory, nevents, revents_count) {
return enc_errno(e); return enc_errno(e);
} }
wasm32::__WASI_ESUCCESS wasm32::__WASI_ESUCCESS

View File

@@ -14,6 +14,7 @@ use crate::{host, wasm32};
use cast; use cast;
use cast::From as _0; use cast::From as _0;
use std::mem::{align_of, size_of}; use std::mem::{align_of, size_of};
use std::ptr;
use std::slice; use std::slice;
macro_rules! bail_errno { macro_rules! bail_errno {
@@ -22,56 +23,53 @@ macro_rules! bail_errno {
}; };
} }
pub unsafe fn dec_ptr( pub fn dec_ptr(
memory: &mut [u8], memory: &mut [u8],
ptr: wasm32::uintptr_t, ptr: wasm32::uintptr_t,
len: usize, len: usize,
) -> Result<*mut u8, host::__wasi_errno_t> { ) -> Result<*mut u8, host::__wasi_errno_t> {
// check that `len` fits in the wasm32 address space // check for overflow
if len > wasm32::UINTPTR_MAX as usize { let checked_len = (ptr as usize).checked_add(len).ok_or(host::__WASI_EFAULT)?;
bail_errno!(__WASI_EOVERFLOW);
}
// check that `ptr` and `ptr + len` are both within the guest heap
if ptr as usize > memory.len() || ptr as usize + len > memory.len() {
bail_errno!(__WASI_EFAULT);
}
// translate the pointer // translate the pointer
Ok(memory.as_mut_ptr().offset(ptr as isize)) memory
.get_mut(ptr as usize..checked_len)
.ok_or(host::__WASI_EFAULT)
.map(|mem| mem.as_mut_ptr())
} }
pub unsafe fn dec_ptr_to<T>( pub fn dec_ptr_to<'memory, T>(
memory: &mut [u8], memory: &'memory mut [u8],
ptr: wasm32::uintptr_t, ptr: wasm32::uintptr_t,
) -> Result<*mut T, host::__wasi_errno_t> { ) -> Result<&'memory mut T, host::__wasi_errno_t> {
// check that the ptr is aligned // check that the ptr is aligned
if ptr as usize % align_of::<T>() != 0 { if ptr as usize % align_of::<T>() != 0 {
bail_errno!(__WASI_EINVAL); bail_errno!(__WASI_EINVAL);
} }
dec_ptr(memory, ptr, size_of::<T>()).map(|p| p as *mut T)
dec_ptr(memory, ptr, size_of::<T>()).map(|p| unsafe { &mut *(p as *mut T) })
} }
pub unsafe fn dec_pointee<T>( pub fn dec_pointee<T>(
memory: &mut [u8], memory: &mut [u8],
ptr: wasm32::uintptr_t, ptr: wasm32::uintptr_t,
) -> Result<T, host::__wasi_errno_t> { ) -> Result<T, host::__wasi_errno_t> {
dec_ptr_to::<T>(memory, ptr).map(|p| p.read()) dec_ptr_to::<T>(memory, ptr).map(|p| unsafe { ptr::read(p) })
} }
pub unsafe fn enc_pointee<T>( pub fn enc_pointee<T>(
memory: &mut [u8], memory: &mut [u8],
ptr: wasm32::uintptr_t, ptr: wasm32::uintptr_t,
t: T, t: T,
) -> Result<(), host::__wasi_errno_t> { ) -> Result<(), host::__wasi_errno_t> {
dec_ptr_to::<T>(memory, ptr).map(|p| p.write(t)) dec_ptr_to::<T>(memory, ptr).map(|p| unsafe { ptr::write(p, t) })
} }
pub unsafe fn dec_slice_of<T>( pub fn dec_slice_of<'memory, T>(
memory: &mut [u8], memory: &'memory mut [u8],
ptr: wasm32::uintptr_t, ptr: wasm32::uintptr_t,
len: wasm32::size_t, len: wasm32::size_t,
) -> Result<(*mut T, usize), host::__wasi_errno_t> { ) -> Result<(&'memory mut T, usize), host::__wasi_errno_t> {
// check alignment, and that length doesn't overflow // check alignment, and that length doesn't overflow
if ptr as usize % align_of::<T>() != 0 { if ptr as usize % align_of::<T>() != 0 {
return Err(host::__WASI_EINVAL); return Err(host::__WASI_EINVAL);
@@ -84,11 +82,10 @@ pub unsafe fn dec_slice_of<T>(
}; };
let ptr = dec_ptr(memory, ptr, len_bytes)? as *mut T; let ptr = dec_ptr(memory, ptr, len_bytes)? as *mut T;
Ok((unsafe { &mut *ptr }, len))
Ok((ptr, len))
} }
pub unsafe fn enc_slice_of<T>( pub fn enc_slice_of<T>(
memory: &mut [u8], memory: &mut [u8],
slice: &[T], slice: &[T],
ptr: wasm32::uintptr_t, ptr: wasm32::uintptr_t,
@@ -106,7 +103,9 @@ pub unsafe fn enc_slice_of<T>(
// get the pointer into guest memory, and copy the bytes // get the pointer into guest memory, and copy the bytes
let ptr = dec_ptr(memory, ptr, len_bytes)? as *mut libc::c_void; let ptr = dec_ptr(memory, ptr, len_bytes)? as *mut libc::c_void;
libc::memcpy(ptr, slice.as_ptr() as *const libc::c_void, len_bytes); unsafe {
libc::memcpy(ptr, slice.as_ptr() as *const libc::c_void, len_bytes);
}
Ok(()) Ok(())
} }
@@ -117,7 +116,7 @@ macro_rules! dec_enc_scalar {
host::$ty::from_le(x) host::$ty::from_le(x)
} }
pub unsafe fn $dec_byref( pub fn $dec_byref(
memory: &mut [u8], memory: &mut [u8],
ptr: wasm32::uintptr_t, ptr: wasm32::uintptr_t,
) -> Result<host::$ty, host::__wasi_errno_t> { ) -> Result<host::$ty, host::__wasi_errno_t> {
@@ -128,7 +127,7 @@ macro_rules! dec_enc_scalar {
x.to_le() x.to_le()
} }
pub unsafe fn $enc_byref( pub fn $enc_byref(
memory: &mut [u8], memory: &mut [u8],
ptr: wasm32::uintptr_t, ptr: wasm32::uintptr_t,
x: host::$ty, x: host::$ty,
@@ -138,7 +137,7 @@ macro_rules! dec_enc_scalar {
}; };
} }
pub unsafe fn dec_ciovec( pub fn dec_ciovec(
memory: &mut [u8], memory: &mut [u8],
ciovec: &wasm32::__wasi_ciovec_t, ciovec: &wasm32::__wasi_ciovec_t,
) -> Result<host::__wasi_ciovec_t, host::__wasi_errno_t> { ) -> Result<host::__wasi_ciovec_t, host::__wasi_errno_t> {
@@ -149,13 +148,13 @@ pub unsafe fn dec_ciovec(
}) })
} }
pub unsafe fn dec_ciovec_slice( pub fn dec_ciovec_slice(
memory: &mut [u8], memory: &mut [u8],
ptr: wasm32::uintptr_t, ptr: wasm32::uintptr_t,
len: wasm32::size_t, len: wasm32::size_t,
) -> Result<Vec<host::__wasi_ciovec_t>, host::__wasi_errno_t> { ) -> Result<Vec<host::__wasi_ciovec_t>, host::__wasi_errno_t> {
let slice = dec_slice_of::<wasm32::__wasi_ciovec_t>(memory, ptr, len)?; let slice = dec_slice_of::<wasm32::__wasi_ciovec_t>(memory, ptr, len)?;
let slice = slice::from_raw_parts(slice.0, slice.1); let slice = unsafe { slice::from_raw_parts(slice.0, slice.1) };
slice.iter().map(|iov| dec_ciovec(memory, iov)).collect() slice.iter().map(|iov| dec_ciovec(memory, iov)).collect()
} }
@@ -223,7 +222,7 @@ pub fn dec_filestat(filestat: wasm32::__wasi_filestat_t) -> host::__wasi_filesta
} }
} }
pub unsafe fn dec_filestat_byref( pub fn dec_filestat_byref(
memory: &mut [u8], memory: &mut [u8],
filestat_ptr: wasm32::uintptr_t, filestat_ptr: wasm32::uintptr_t,
) -> Result<host::__wasi_filestat_t, host::__wasi_errno_t> { ) -> Result<host::__wasi_filestat_t, host::__wasi_errno_t> {
@@ -243,7 +242,7 @@ pub fn enc_filestat(filestat: host::__wasi_filestat_t) -> wasm32::__wasi_filesta
} }
} }
pub unsafe fn enc_filestat_byref( pub fn enc_filestat_byref(
memory: &mut [u8], memory: &mut [u8],
filestat_ptr: wasm32::uintptr_t, filestat_ptr: wasm32::uintptr_t,
host_filestat: host::__wasi_filestat_t, host_filestat: host::__wasi_filestat_t,
@@ -261,7 +260,7 @@ pub fn dec_fdstat(fdstat: wasm32::__wasi_fdstat_t) -> host::__wasi_fdstat_t {
} }
} }
pub unsafe fn dec_fdstat_byref( pub fn dec_fdstat_byref(
memory: &mut [u8], memory: &mut [u8],
fdstat_ptr: wasm32::uintptr_t, fdstat_ptr: wasm32::uintptr_t,
) -> Result<host::__wasi_fdstat_t, host::__wasi_errno_t> { ) -> Result<host::__wasi_fdstat_t, host::__wasi_errno_t> {
@@ -278,7 +277,7 @@ pub fn enc_fdstat(fdstat: host::__wasi_fdstat_t) -> wasm32::__wasi_fdstat_t {
} }
} }
pub unsafe fn enc_fdstat_byref( pub fn enc_fdstat_byref(
memory: &mut [u8], memory: &mut [u8],
fdstat_ptr: wasm32::uintptr_t, fdstat_ptr: wasm32::uintptr_t,
host_fdstat: host::__wasi_fdstat_t, host_fdstat: host::__wasi_fdstat_t,
@@ -345,7 +344,7 @@ pub fn dec_prestat(
} }
} }
pub unsafe fn dec_prestat_byref( pub fn dec_prestat_byref(
memory: &mut [u8], memory: &mut [u8],
prestat_ptr: wasm32::uintptr_t, prestat_ptr: wasm32::uintptr_t,
) -> Result<host::__wasi_prestat_t, host::__wasi_errno_t> { ) -> Result<host::__wasi_prestat_t, host::__wasi_errno_t> {
@@ -371,7 +370,7 @@ pub fn enc_prestat(
} }
} }
pub unsafe fn enc_prestat_byref( pub fn enc_prestat_byref(
memory: &mut [u8], memory: &mut [u8],
prestat_ptr: wasm32::uintptr_t, prestat_ptr: wasm32::uintptr_t,
host_prestat: host::__wasi_prestat_t, host_prestat: host::__wasi_prestat_t,
@@ -403,7 +402,7 @@ pub fn enc_usize(size: usize) -> wasm32::size_t {
wasm32::size_t::cast(size).unwrap() wasm32::size_t::cast(size).unwrap()
} }
pub unsafe fn enc_usize_byref( pub fn enc_usize_byref(
memory: &mut [u8], memory: &mut [u8],
usize_ptr: wasm32::uintptr_t, usize_ptr: wasm32::uintptr_t,
host_usize: usize, host_usize: usize,