Merge pull request #10 from CraneStation/api

Add experimental struct with views into memory and ctx
This commit is contained in:
Dan Gohman
2019-05-11 08:31:59 -07:00
committed by GitHub
3 changed files with 246 additions and 214 deletions

View File

@@ -1,6 +1,5 @@
use crate::fdentry::FdEntry; use crate::fdentry::FdEntry;
use crate::host; use crate::host;
use crate::wasm32;
use failure::{bail, format_err, Error}; use failure::{bail, format_err, Error};
use nix::unistd::dup; use nix::unistd::dup;
@@ -11,17 +10,6 @@ use std::io::{stderr, stdin, stdout};
use std::os::unix::prelude::{AsRawFd, FromRawFd, IntoRawFd, RawFd}; use std::os::unix::prelude::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
pub trait VmContext {
fn as_wasi_ctx(&self) -> *const WasiCtx;
fn as_wasi_ctx_mut(&mut self) -> *mut WasiCtx;
unsafe fn dec_ptr(
&mut self,
ptr: wasm32::uintptr_t,
len: usize,
) -> Result<*mut u8, host::__wasi_errno_t>;
}
pub struct WasiCtxBuilder { pub struct WasiCtxBuilder {
fds: HashMap<host::__wasi_fd_t, FdEntry>, fds: HashMap<host::__wasi_fd_t, FdEntry>,
preopens: HashMap<PathBuf, File>, preopens: HashMap<PathBuf, File>,

View File

@@ -11,7 +11,7 @@
#![allow(non_camel_case_types)] #![allow(non_camel_case_types)]
#![allow(unused_unsafe)] #![allow(unused_unsafe)]
#![allow(unused)] #![allow(unused)]
use crate::ctx::VmContext; use crate::ctx::WasiCtx;
use crate::fdentry::{determine_type_rights, FdEntry}; use crate::fdentry::{determine_type_rights, FdEntry};
use crate::memory::*; use crate::memory::*;
use crate::{host, wasm32}; use crate::{host, wasm32};
@@ -25,25 +25,24 @@ use std::os::unix::prelude::{FromRawFd, OsStrExt, OsStringExt, RawFd};
use std::time::SystemTime; use std::time::SystemTime;
use std::{cmp, slice}; use std::{cmp, slice};
pub unsafe fn proc_exit(_vmctx: &mut VmContext, rval: wasm32::__wasi_exitcode_t) -> () { pub fn proc_exit(rval: wasm32::__wasi_exitcode_t) -> () {
std::process::exit(dec_exitcode(rval) as i32); std::process::exit(dec_exitcode(rval) as i32);
} }
pub unsafe fn args_get( pub fn args_get(
vmctx: *mut VmContext, wasi_ctx: &WasiCtx,
memory: &mut [u8],
argv_ptr: wasm32::uintptr_t, argv_ptr: wasm32::uintptr_t,
argv_buf: wasm32::uintptr_t, argv_buf: wasm32::uintptr_t,
) -> wasm32::__wasi_errno_t { ) -> wasm32::__wasi_errno_t {
let ctx = (*vmctx).as_wasi_ctx();
let mut argv_buf_offset = 0; let mut argv_buf_offset = 0;
let mut argv = vec![]; let mut argv = vec![];
for arg in (*ctx).args.iter() { for arg in wasi_ctx.args.iter() {
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(vmctx, arg_bytes, arg_ptr) } { if let Err(e) = unsafe { enc_slice_of(memory, arg_bytes, arg_ptr) } {
return enc_errno(e); return enc_errno(e);
} }
@@ -60,39 +59,38 @@ pub unsafe fn args_get(
} }
unsafe { unsafe {
enc_slice_of(vmctx, 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 unsafe fn args_sizes_get( pub fn args_sizes_get(
vmctx: *mut VmContext, wasi_ctx: &WasiCtx,
memory: &mut [u8],
argc_ptr: wasm32::uintptr_t, argc_ptr: wasm32::uintptr_t,
argv_buf_size_ptr: wasm32::uintptr_t, argv_buf_size_ptr: wasm32::uintptr_t,
) -> wasm32::__wasi_errno_t { ) -> wasm32::__wasi_errno_t {
let ctx = (*vmctx).as_wasi_ctx(); let argc = wasi_ctx.args.len();
let argv_size = wasi_ctx
let argc = (*ctx).args.len();
let argv_size = (*ctx)
.args .args
.iter() .iter()
.map(|arg| arg.as_bytes_with_nul().len()) .map(|arg| arg.as_bytes_with_nul().len())
.sum(); .sum();
unsafe { unsafe {
if let Err(e) = enc_usize_byref(vmctx, 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(vmctx, 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
} }
pub unsafe fn clock_res_get( pub fn clock_res_get(
vmctx: *mut VmContext, memory: &mut [u8],
clock_id: wasm32::__wasi_clockid_t, clock_id: wasm32::__wasi_clockid_t,
resolution_ptr: wasm32::uintptr_t, resolution_ptr: wasm32::uintptr_t,
) -> wasm32::__wasi_errno_t { ) -> wasm32::__wasi_errno_t {
@@ -124,7 +122,7 @@ pub unsafe fn clock_res_get(
wasm32::__WASI_EINVAL wasm32::__WASI_EINVAL
} else { } else {
unsafe { unsafe {
enc_timestamp_byref(vmctx, 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)
} }
@@ -133,8 +131,8 @@ pub unsafe fn clock_res_get(
.unwrap_or(wasm32::__WASI_EOVERFLOW) .unwrap_or(wasm32::__WASI_EOVERFLOW)
} }
pub unsafe fn clock_time_get( pub fn clock_time_get(
vmctx: *mut VmContext, memory: &mut [u8],
clock_id: wasm32::__wasi_clockid_t, clock_id: wasm32::__wasi_clockid_t,
// ignored for now, but will be useful once we put optional limits on precision to reduce side // ignored for now, but will be useful once we put optional limits on precision to reduce side
// channels // channels
@@ -163,28 +161,27 @@ pub unsafe fn clock_time_get(
.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(|time| unsafe {
enc_timestamp_byref(vmctx, 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) .unwrap_or(wasm32::__WASI_EOVERFLOW)
} }
pub unsafe fn environ_get( pub fn environ_get(
vmctx: *mut VmContext, wasi_ctx: &WasiCtx,
memory: &mut [u8],
environ_ptr: wasm32::uintptr_t, environ_ptr: wasm32::uintptr_t,
environ_buf: wasm32::uintptr_t, environ_buf: wasm32::uintptr_t,
) -> wasm32::__wasi_errno_t { ) -> wasm32::__wasi_errno_t {
let ctx = (*vmctx).as_wasi_ctx();
let mut environ_buf_offset = 0; let mut environ_buf_offset = 0;
let mut environ = vec![]; let mut environ = vec![];
for pair in (*ctx).env.iter() { for pair in wasi_ctx.env.iter() {
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(vmctx, env_bytes, env_ptr) } { if let Err(e) = unsafe { enc_slice_of(memory, env_bytes, env_ptr) } {
return enc_errno(e); return enc_errno(e);
} }
@@ -201,28 +198,27 @@ pub unsafe fn environ_get(
} }
unsafe { unsafe {
enc_slice_of(vmctx, 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 unsafe fn environ_sizes_get( pub fn environ_sizes_get(
vmctx: *mut VmContext, wasi_ctx: &WasiCtx,
memory: &mut [u8],
environ_count_ptr: wasm32::uintptr_t, environ_count_ptr: wasm32::uintptr_t,
environ_size_ptr: wasm32::uintptr_t, environ_size_ptr: wasm32::uintptr_t,
) -> wasm32::__wasi_errno_t { ) -> wasm32::__wasi_errno_t {
let ctx = (*vmctx).as_wasi_ctx(); let environ_count = wasi_ctx.env.len();
if let Some(environ_size) = wasi_ctx.env.iter().try_fold(0, |acc: u32, pair| {
let environ_count = (*ctx).env.len();
if let Some(environ_size) = (*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 { unsafe {
if let Err(e) = enc_usize_byref(vmctx, 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(vmctx, 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);
} }
} }
@@ -232,16 +228,15 @@ pub unsafe fn environ_sizes_get(
} }
} }
pub unsafe fn fd_close(vmctx: *mut VmContext, fd: wasm32::__wasi_fd_t) -> wasm32::__wasi_errno_t { pub fn fd_close(wasi_ctx: &mut WasiCtx, fd: wasm32::__wasi_fd_t) -> wasm32::__wasi_errno_t {
let ctx = (*vmctx).as_wasi_ctx_mut();
let fd = dec_fd(fd); let fd = dec_fd(fd);
if let Some(fdent) = (*ctx).fds.get(&fd) { if let Some(fdent) = wasi_ctx.fds.get(&fd) {
// can't close preopened files // can't close preopened files
if fdent.preopen_path.is_some() { if fdent.preopen_path.is_some() {
return wasm32::__WASI_ENOTSUP; return wasm32::__WASI_ENOTSUP;
} }
} }
if let Some(mut fdent) = (*ctx).fds.remove(&fd) { if let Some(mut fdent) = wasi_ctx.fds.remove(&fd) {
fdent.fd_object.needs_close = false; fdent.fd_object.needs_close = false;
match nix::unistd::close(fdent.fd_object.rawfd) { match nix::unistd::close(fdent.fd_object.rawfd) {
Ok(_) => wasm32::__WASI_ESUCCESS, Ok(_) => wasm32::__WASI_ESUCCESS,
@@ -252,19 +247,19 @@ pub unsafe fn fd_close(vmctx: *mut VmContext, fd: wasm32::__wasi_fd_t) -> wasm32
} }
} }
pub unsafe fn fd_fdstat_get( pub fn fd_fdstat_get(
vmctx: *mut VmContext, wasi_ctx: &WasiCtx,
memory: &mut [u8],
fd: wasm32::__wasi_fd_t, fd: wasm32::__wasi_fd_t,
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(vmctx, fdstat_ptr) } { let mut host_fdstat = match unsafe { 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),
}; };
let ctx = (*vmctx).as_wasi_ctx_mut(); let errno = if let Some(fe) = wasi_ctx.fds.get(&host_fd) {
let errno = if let Some(fe) = (*ctx).fds.get(&host_fd) {
host_fdstat.fs_filetype = fe.fd_object.ty; host_fdstat.fs_filetype = fe.fd_object.ty;
host_fdstat.fs_rights_base = fe.rights_base; host_fdstat.fs_rights_base = fe.rights_base;
host_fdstat.fs_rights_inheriting = fe.rights_inheriting; host_fdstat.fs_rights_inheriting = fe.rights_inheriting;
@@ -281,15 +276,15 @@ pub unsafe fn fd_fdstat_get(
}; };
unsafe { unsafe {
enc_fdstat_byref(vmctx, 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
} }
pub unsafe fn fd_fdstat_set_flags( pub fn fd_fdstat_set_flags(
vmctx: &mut VmContext, wasi_ctx: &WasiCtx,
fd: wasm32::__wasi_fd_t, fd: wasm32::__wasi_fd_t,
fdflags: wasm32::__wasi_fdflags_t, fdflags: wasm32::__wasi_fdflags_t,
) -> wasm32::__wasi_errno_t { ) -> wasm32::__wasi_errno_t {
@@ -297,9 +292,7 @@ pub unsafe fn fd_fdstat_set_flags(
let host_fdflags = dec_fdflags(fdflags); let host_fdflags = dec_fdflags(fdflags);
let nix_flags = host::nix_from_fdflags(host_fdflags); let nix_flags = host::nix_from_fdflags(host_fdflags);
let ctx = (*vmctx).as_wasi_ctx_mut(); if let Some(fe) = wasi_ctx.fds.get(&host_fd) {
if let Some(fe) = (*ctx).fds.get(&host_fd) {
match nix::fcntl::fcntl(fe.fd_object.rawfd, nix::fcntl::F_SETFL(nix_flags)) { match nix::fcntl::fcntl(fe.fd_object.rawfd, nix::fcntl::F_SETFL(nix_flags)) {
Ok(_) => wasm32::__WASI_ESUCCESS, Ok(_) => wasm32::__WASI_ESUCCESS,
Err(e) => wasm32::errno_from_nix(e.as_errno().unwrap()), Err(e) => wasm32::errno_from_nix(e.as_errno().unwrap()),
@@ -309,14 +302,14 @@ pub unsafe fn fd_fdstat_set_flags(
} }
} }
pub unsafe fn fd_seek( pub fn fd_seek(
vmctx: *mut VmContext, wasi_ctx: &WasiCtx,
memory: &mut [u8],
fd: wasm32::__wasi_fd_t, fd: wasm32::__wasi_fd_t,
offset: wasm32::__wasi_filedelta_t, offset: wasm32::__wasi_filedelta_t,
whence: wasm32::__wasi_whence_t, whence: wasm32::__wasi_whence_t,
newoffset: wasm32::uintptr_t, newoffset: wasm32::uintptr_t,
) -> wasm32::__wasi_errno_t { ) -> wasm32::__wasi_errno_t {
let ctx = (*vmctx).as_wasi_ctx_mut();
let fd = dec_fd(fd); let fd = dec_fd(fd);
let offset = dec_filedelta(offset); let offset = dec_filedelta(offset);
let whence = dec_whence(whence); let whence = dec_whence(whence);
@@ -335,7 +328,7 @@ pub unsafe fn fd_seek(
} else { } else {
host::__WASI_RIGHT_FD_SEEK | host::__WASI_RIGHT_FD_TELL host::__WASI_RIGHT_FD_SEEK | host::__WASI_RIGHT_FD_TELL
}; };
match (*ctx).get_fd_entry(fd, rights.into(), 0) { match wasi_ctx.get_fd_entry(fd, rights.into(), 0) {
Ok(fe) => match lseek(fe.fd_object.rawfd, offset, nwhence) { Ok(fe) => match lseek(fe.fd_object.rawfd, offset, nwhence) {
Ok(newoffset) => newoffset, Ok(newoffset) => newoffset,
Err(e) => return wasm32::errno_from_nix(e.as_errno().unwrap()), Err(e) => return wasm32::errno_from_nix(e.as_errno().unwrap()),
@@ -345,21 +338,21 @@ pub unsafe fn fd_seek(
}; };
unsafe { unsafe {
enc_filesize_byref(vmctx, 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 unsafe fn fd_prestat_get( pub fn fd_prestat_get(
vmctx: *mut VmContext, wasi_ctx: &WasiCtx,
memory: &mut [u8],
fd: wasm32::__wasi_fd_t, fd: wasm32::__wasi_fd_t,
prestat_ptr: wasm32::uintptr_t, prestat_ptr: wasm32::uintptr_t,
) -> wasm32::__wasi_errno_t { ) -> wasm32::__wasi_errno_t {
let ctx = (*vmctx).as_wasi_ctx();
let fd = dec_fd(fd); let fd = dec_fd(fd);
// TODO: is this the correct right for this? // TODO: is this the correct right for this?
match (*ctx).get_fd_entry(fd, host::__WASI_RIGHT_PATH_OPEN.into(), 0) { match wasi_ctx.get_fd_entry(fd, host::__WASI_RIGHT_PATH_OPEN.into(), 0) {
Ok(fe) => { Ok(fe) => {
if let Some(po_path) = &fe.preopen_path { if let Some(po_path) = &fe.preopen_path {
if fe.fd_object.ty != host::__WASI_FILETYPE_DIRECTORY { if fe.fd_object.ty != host::__WASI_FILETYPE_DIRECTORY {
@@ -367,7 +360,7 @@ pub unsafe fn fd_prestat_get(
} }
unsafe { unsafe {
enc_prestat_byref( enc_prestat_byref(
vmctx, 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,
@@ -390,15 +383,16 @@ pub unsafe fn fd_prestat_get(
} }
} }
pub unsafe fn fd_prestat_dir_name( pub fn fd_prestat_dir_name(
vmctx: *mut VmContext, wasi_ctx: &WasiCtx,
memory: &mut [u8],
fd: wasm32::__wasi_fd_t, fd: wasm32::__wasi_fd_t,
path_ptr: wasm32::uintptr_t, path_ptr: wasm32::uintptr_t,
path_len: wasm32::size_t, path_len: wasm32::size_t,
) -> wasm32::__wasi_errno_t { ) -> wasm32::__wasi_errno_t {
let fd = dec_fd(fd); let fd = dec_fd(fd);
match (*(*vmctx).as_wasi_ctx()).get_fd_entry(fd, host::__WASI_RIGHT_PATH_OPEN.into(), 0) { match wasi_ctx.get_fd_entry(fd, host::__WASI_RIGHT_PATH_OPEN.into(), 0) {
Ok(fe) => { Ok(fe) => {
if let Some(po_path) = &fe.preopen_path { if let Some(po_path) = &fe.preopen_path {
if fe.fd_object.ty != host::__WASI_FILETYPE_DIRECTORY { if fe.fd_object.ty != host::__WASI_FILETYPE_DIRECTORY {
@@ -409,7 +403,7 @@ pub unsafe fn fd_prestat_dir_name(
return wasm32::__WASI_ENAMETOOLONG; return wasm32::__WASI_ENAMETOOLONG;
} }
unsafe { unsafe {
enc_slice_of(vmctx, 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)
} }
@@ -421,8 +415,9 @@ pub unsafe fn fd_prestat_dir_name(
} }
} }
pub unsafe fn fd_read( pub fn fd_read(
vmctx: *mut VmContext, wasi_ctx: &mut WasiCtx,
memory: &mut [u8],
fd: wasm32::__wasi_fd_t, fd: wasm32::__wasi_fd_t,
iovs_ptr: wasm32::uintptr_t, iovs_ptr: wasm32::uintptr_t,
iovs_len: wasm32::size_t, iovs_len: wasm32::size_t,
@@ -431,13 +426,12 @@ pub unsafe 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(vmctx, iovs_ptr, iovs_len) } { let mut iovs = match unsafe { 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),
}; };
let ctx = (*vmctx).as_wasi_ctx_mut(); let fe = match wasi_ctx.get_fd_entry(fd, host::__WASI_RIGHT_FD_READ.into(), 0) {
let fe = match (*ctx).get_fd_entry(fd, host::__WASI_RIGHT_FD_READ.into(), 0) {
Ok(fe) => fe, Ok(fe) => fe,
Err(e) => return enc_errno(e), Err(e) => return enc_errno(e),
}; };
@@ -454,19 +448,20 @@ pub unsafe fn fd_read(
if host_nread == 0 { if host_nread == 0 {
// we hit eof, so remove the fdentry from the context // we hit eof, so remove the fdentry from the context
let mut fe = (*ctx).fds.remove(&fd).expect("file entry is still there"); let mut fe = wasi_ctx.fds.remove(&fd).expect("file entry is still there");
fe.fd_object.needs_close = false; fe.fd_object.needs_close = false;
} }
unsafe { unsafe {
enc_usize_byref(vmctx, 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 unsafe fn fd_write( pub fn fd_write(
vmctx: *mut VmContext, wasi_ctx: &WasiCtx,
memory: &mut [u8],
fd: wasm32::__wasi_fd_t, fd: wasm32::__wasi_fd_t,
iovs_ptr: wasm32::uintptr_t, iovs_ptr: wasm32::uintptr_t,
iovs_len: wasm32::size_t, iovs_len: wasm32::size_t,
@@ -475,13 +470,12 @@ pub unsafe 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(vmctx, iovs_ptr, iovs_len) } { let iovs = match unsafe { 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),
}; };
let ctx = (*vmctx).as_wasi_ctx(); let fe = match wasi_ctx.get_fd_entry(fd, host::__WASI_RIGHT_FD_WRITE.into(), 0) {
let fe = match (*ctx).get_fd_entry(fd, host::__WASI_RIGHT_FD_WRITE.into(), 0) {
Ok(fe) => fe, Ok(fe) => fe,
Err(e) => return enc_errno(e), Err(e) => return enc_errno(e),
}; };
@@ -497,14 +491,15 @@ pub unsafe fn fd_write(
}; };
unsafe { unsafe {
enc_usize_byref(vmctx, 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 unsafe fn path_open( pub fn path_open(
vmctx: *mut VmContext, wasi_ctx: &mut WasiCtx,
memory: &mut [u8],
dirfd: wasm32::__wasi_fd_t, dirfd: wasm32::__wasi_fd_t,
dirflags: wasm32::__wasi_lookupflags_t, dirflags: wasm32::__wasi_lookupflags_t,
path_ptr: wasm32::uintptr_t, path_ptr: wasm32::uintptr_t,
@@ -569,13 +564,14 @@ pub unsafe 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>(vmctx, path_ptr, path_len) } { let path = match unsafe { 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),
}; };
let (dir, path) = match path_get( let (dir, path) = match path_get(
&*vmctx, wasi_ctx,
memory,
dirfd, dirfd,
dirflags, dirflags,
path, path,
@@ -627,7 +623,7 @@ pub unsafe fn path_open(
let mut fe = unsafe { FdEntry::from_raw_fd(new_fd) }; let mut fe = unsafe { FdEntry::from_raw_fd(new_fd) };
fe.rights_base &= max_base; fe.rights_base &= max_base;
fe.rights_inheriting &= max_inheriting; fe.rights_inheriting &= max_inheriting;
match (*(*vmctx).as_wasi_ctx_mut()).insert_fd_entry(fe) { match wasi_ctx.insert_fd_entry(fe) {
Ok(fd) => fd, Ok(fd) => fd,
Err(e) => return enc_errno(e), Err(e) => return enc_errno(e),
} }
@@ -635,21 +631,21 @@ pub unsafe fn path_open(
}; };
unsafe { unsafe {
enc_fd_byref(vmctx, 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 unsafe fn random_get( pub fn random_get(
vmctx: *mut VmContext, memory: &mut [u8],
buf_ptr: wasm32::uintptr_t, buf_ptr: wasm32::uintptr_t,
buf_len: wasm32::size_t, buf_len: wasm32::size_t,
) -> wasm32::__wasi_errno_t { ) -> wasm32::__wasi_errno_t {
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 { (*vmctx).dec_ptr(buf_ptr, buf_len) } { let buf_ptr = match unsafe { 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),
}; };
@@ -661,8 +657,8 @@ pub unsafe fn random_get(
return wasm32::__WASI_ESUCCESS; return wasm32::__WASI_ESUCCESS;
} }
pub unsafe fn poll_oneoff( pub fn poll_oneoff(
vmctx: *mut VmContext, memory: &mut [u8],
input: wasm32::uintptr_t, input: wasm32::uintptr_t,
output: wasm32::uintptr_t, output: wasm32::uintptr_t,
nsubscriptions: wasm32::size_t, nsubscriptions: wasm32::size_t,
@@ -671,14 +667,14 @@ pub unsafe 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(vmctx, nevents, 0) }.unwrap(); unsafe { enc_pointee(memory, nevents, 0) }.unwrap();
let input_slice_ = let input_slice_ =
unsafe { dec_slice_of::<wasm32::__wasi_subscription_t>(vmctx, input, nsubscriptions) } unsafe { 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>(vmctx, output, nsubscriptions) }.unwrap(); unsafe { 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();
@@ -744,29 +740,29 @@ pub unsafe fn poll_oneoff(
} }
}; };
if ready == 0 { if ready == 0 {
return poll_oneoff_handle_timeout_event(&mut *vmctx, output_slice, nevents, timeout); return poll_oneoff_handle_timeout_event(memory, output_slice, nevents, timeout);
} }
let events = fd_events.iter().zip(poll_fds.iter()).take(ready); let events = fd_events.iter().zip(poll_fds.iter()).take(ready);
poll_oneoff_handle_fd_event(&mut *vmctx, output_slice, nevents, events) poll_oneoff_handle_fd_event(memory, output_slice, nevents, events)
} }
pub unsafe fn fd_filestat_get( pub fn fd_filestat_get(
vmctx: *mut VmContext, wasi_ctx: &WasiCtx,
memory: &mut [u8],
fd: wasm32::__wasi_fd_t, fd: wasm32::__wasi_fd_t,
filestat_ptr: wasm32::uintptr_t, filestat_ptr: wasm32::uintptr_t,
) -> wasm32::__wasi_errno_t { ) -> wasm32::__wasi_errno_t {
use nix::sys::stat::fstat; use nix::sys::stat::fstat;
let host_fd = dec_fd(fd); let host_fd = dec_fd(fd);
let ctx = (*vmctx).as_wasi_ctx_mut();
let errno = if let Some(fe) = (*ctx).fds.get(&host_fd) { let errno = if let Some(fe) = wasi_ctx.fds.get(&host_fd) {
match fstat(fe.fd_object.rawfd) { match fstat(fe.fd_object.rawfd) {
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 { unsafe {
enc_filestat_byref(vmctx, 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
@@ -778,8 +774,9 @@ pub unsafe fn fd_filestat_get(
errno errno
} }
pub unsafe fn path_filestat_get( pub fn path_filestat_get(
vmctx: *mut VmContext, wasi_ctx: &WasiCtx,
memory: &mut [u8],
dirfd: wasm32::__wasi_fd_t, dirfd: wasm32::__wasi_fd_t,
dirflags: wasm32::__wasi_lookupflags_t, dirflags: wasm32::__wasi_lookupflags_t,
path_ptr: wasm32::uintptr_t, path_ptr: wasm32::uintptr_t,
@@ -791,12 +788,13 @@ pub unsafe 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>(vmctx, path_ptr, path_len) } { let path = match unsafe { 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),
}; };
let (dir, path) = match path_get( let (dir, path) = match path_get(
&*vmctx, wasi_ctx,
memory,
dirfd, dirfd,
dirflags, dirflags,
path, path,
@@ -816,7 +814,7 @@ pub unsafe fn path_filestat_get(
Ok(filestat) => { Ok(filestat) => {
let host_filestat = host::filestat_from_nix(filestat); let host_filestat = host::filestat_from_nix(filestat);
unsafe { unsafe {
enc_filestat_byref(vmctx, 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
@@ -824,8 +822,9 @@ pub unsafe fn path_filestat_get(
} }
} }
pub unsafe fn path_create_directory( pub fn path_create_directory(
vmctx: *mut VmContext, wasi_ctx: &WasiCtx,
memory: &mut [u8],
dirfd: wasm32::__wasi_fd_t, dirfd: wasm32::__wasi_fd_t,
path_ptr: wasm32::uintptr_t, path_ptr: wasm32::uintptr_t,
path_len: wasm32::size_t, path_len: wasm32::size_t,
@@ -834,12 +833,13 @@ pub unsafe 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>(vmctx, path_ptr, path_len) } { let path = match unsafe { 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),
}; };
let (dir, path) = match path_get( let (dir, path) = match path_get(
&*vmctx, wasi_ctx,
memory,
dirfd, dirfd,
0, 0,
path, path,
@@ -861,8 +861,9 @@ pub unsafe fn path_create_directory(
} }
} }
pub unsafe fn path_unlink_file( pub fn path_unlink_file(
vmctx: *mut VmContext, wasi_ctx: &WasiCtx,
memory: &mut [u8],
dirfd: wasm32::__wasi_fd_t, dirfd: wasm32::__wasi_fd_t,
path_ptr: wasm32::uintptr_t, path_ptr: wasm32::uintptr_t,
path_len: wasm32::size_t, path_len: wasm32::size_t,
@@ -871,12 +872,13 @@ pub unsafe 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>(vmctx, path_ptr, path_len) } { let path = match unsafe { 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),
}; };
let (dir, path) = match path_get( let (dir, path) = match path_get(
&*vmctx, wasi_ctx,
memory,
dirfd, dirfd,
0, 0,
path, path,
@@ -898,15 +900,17 @@ pub unsafe fn path_unlink_file(
} }
} }
pub unsafe fn fd_datasync( pub fn fd_datasync(
vmctx: *mut VmContext, wasi_ctx: &WasiCtx,
memory: &mut [u8],
fd: wasm32::__wasi_fd_t, fd: wasm32::__wasi_fd_t,
) -> wasm32::__wasi_errno_t { ) -> wasm32::__wasi_errno_t {
unimplemented!("fd_datasync") unimplemented!("fd_datasync")
} }
pub unsafe fn fd_pread( pub fn fd_pread(
vmctx: *mut VmContext, wasi_ctx: &WasiCtx,
memory: &mut [u8],
fd: wasm32::__wasi_fd_t, fd: wasm32::__wasi_fd_t,
iovs: wasm32::uintptr_t, iovs: wasm32::uintptr_t,
iovs_len: wasm32::size_t, iovs_len: wasm32::size_t,
@@ -916,8 +920,9 @@ pub unsafe fn fd_pread(
unimplemented!("fd_pread") unimplemented!("fd_pread")
} }
pub unsafe fn fd_pwrite( pub fn fd_pwrite(
vmctx: *mut VmContext, wasi_ctx: &WasiCtx,
memory: &mut [u8],
fd: wasm32::__wasi_fd_t, fd: wasm32::__wasi_fd_t,
iovs: wasm32::uintptr_t, iovs: wasm32::uintptr_t,
iovs_len: wasm32::size_t, iovs_len: wasm32::size_t,
@@ -927,24 +932,27 @@ pub unsafe fn fd_pwrite(
unimplemented!("fd_pwrite") unimplemented!("fd_pwrite")
} }
pub unsafe fn fd_renumber( pub fn fd_renumber(
vmctx: *mut VmContext, wasi_ctx: &WasiCtx,
memory: &mut [u8],
from: wasm32::__wasi_fd_t, from: wasm32::__wasi_fd_t,
to: wasm32::__wasi_fd_t, to: wasm32::__wasi_fd_t,
) -> wasm32::__wasi_errno_t { ) -> wasm32::__wasi_errno_t {
unimplemented!("fd_renumber") unimplemented!("fd_renumber")
} }
pub unsafe fn fd_tell( pub fn fd_tell(
vmctx: *mut VmContext, wasi_ctx: &WasiCtx,
memory: &mut [u8],
fd: wasm32::__wasi_fd_t, fd: wasm32::__wasi_fd_t,
newoffset: wasm32::uintptr_t, newoffset: wasm32::uintptr_t,
) -> wasm32::__wasi_errno_t { ) -> wasm32::__wasi_errno_t {
unimplemented!("fd_tell") unimplemented!("fd_tell")
} }
pub unsafe fn fd_fdstat_set_rights( pub fn fd_fdstat_set_rights(
vmctx: *mut VmContext, wasi_ctx: &WasiCtx,
memory: &mut [u8],
fd: wasm32::__wasi_fd_t, fd: wasm32::__wasi_fd_t,
fs_rights_base: wasm32::__wasi_rights_t, fs_rights_base: wasm32::__wasi_rights_t,
fs_rights_inheriting: wasm32::__wasi_rights_t, fs_rights_inheriting: wasm32::__wasi_rights_t,
@@ -952,12 +960,17 @@ pub unsafe fn fd_fdstat_set_rights(
unimplemented!("fd_fdstat_set_rights") unimplemented!("fd_fdstat_set_rights")
} }
pub unsafe fn fd_sync(vmctx: *mut VmContext, fd: wasm32::__wasi_fd_t) -> wasm32::__wasi_errno_t { pub fn fd_sync(
wasi_ctx: &WasiCtx,
memory: &mut [u8],
fd: wasm32::__wasi_fd_t,
) -> wasm32::__wasi_errno_t {
unimplemented!("fd_sync") unimplemented!("fd_sync")
} }
pub unsafe fn fd_advise( pub fn fd_advise(
vmctx: *mut VmContext, wasi_ctx: &WasiCtx,
memory: &mut [u8],
fd: wasm32::__wasi_fd_t, fd: wasm32::__wasi_fd_t,
offset: wasm32::__wasi_filesize_t, offset: wasm32::__wasi_filesize_t,
len: wasm32::__wasi_filesize_t, len: wasm32::__wasi_filesize_t,
@@ -966,8 +979,9 @@ pub unsafe fn fd_advise(
unimplemented!("fd_advise") unimplemented!("fd_advise")
} }
pub unsafe fn fd_allocate( pub fn fd_allocate(
vmctx: *mut VmContext, wasi_ctx: &WasiCtx,
memory: &mut [u8],
fd: wasm32::__wasi_fd_t, fd: wasm32::__wasi_fd_t,
offset: wasm32::__wasi_filesize_t, offset: wasm32::__wasi_filesize_t,
len: wasm32::__wasi_filesize_t, len: wasm32::__wasi_filesize_t,
@@ -975,8 +989,9 @@ pub unsafe fn fd_allocate(
unimplemented!("fd_allocate") unimplemented!("fd_allocate")
} }
pub unsafe fn path_link( pub fn path_link(
vmctx: *mut VmContext, wasi_ctx: &WasiCtx,
memory: &mut [u8],
fd0: wasm32::__wasi_fd_t, fd0: wasm32::__wasi_fd_t,
flags0: wasm32::__wasi_lookupflags_t, flags0: wasm32::__wasi_lookupflags_t,
path0: wasm32::uintptr_t, path0: wasm32::uintptr_t,
@@ -988,8 +1003,9 @@ pub unsafe fn path_link(
unimplemented!("path_link") unimplemented!("path_link")
} }
pub unsafe fn fd_readdir( pub fn fd_readdir(
vmctx: *mut VmContext, wasi_ctx: &WasiCtx,
memory: &mut [u8],
fd: wasm32::__wasi_fd_t, fd: wasm32::__wasi_fd_t,
buf: wasm32::uintptr_t, buf: wasm32::uintptr_t,
buf_len: wasm32::size_t, buf_len: wasm32::size_t,
@@ -999,8 +1015,9 @@ pub unsafe fn fd_readdir(
unimplemented!("fd_readdir") unimplemented!("fd_readdir")
} }
pub unsafe fn path_readlink( pub fn path_readlink(
vmctx: *mut VmContext, wasi_ctx: &WasiCtx,
memory: &mut [u8],
fd: wasm32::__wasi_fd_t, fd: wasm32::__wasi_fd_t,
path: wasm32::uintptr_t, path: wasm32::uintptr_t,
path_len: wasm32::size_t, path_len: wasm32::size_t,
@@ -1011,8 +1028,9 @@ pub unsafe fn path_readlink(
unimplemented!("path_readlink") unimplemented!("path_readlink")
} }
pub unsafe fn path_rename( pub fn path_rename(
vmctx: *mut VmContext, wasi_ctx: &WasiCtx,
memory: &mut [u8],
fd0: wasm32::__wasi_fd_t, fd0: wasm32::__wasi_fd_t,
path0: wasm32::uintptr_t, path0: wasm32::uintptr_t,
path_len0: wasm32::size_t, path_len0: wasm32::size_t,
@@ -1023,8 +1041,9 @@ pub unsafe fn path_rename(
unimplemented!("path_rename") unimplemented!("path_rename")
} }
pub unsafe fn fd_filestat_set_times( pub fn fd_filestat_set_times(
vmctx: *mut VmContext, wasi_ctx: &WasiCtx,
memory: &mut [u8],
fd: wasm32::__wasi_fd_t, fd: wasm32::__wasi_fd_t,
st_atim: wasm32::__wasi_timestamp_t, st_atim: wasm32::__wasi_timestamp_t,
st_mtim: wasm32::__wasi_timestamp_t, st_mtim: wasm32::__wasi_timestamp_t,
@@ -1033,16 +1052,18 @@ pub unsafe fn fd_filestat_set_times(
unimplemented!("fd_filestat_set_times") unimplemented!("fd_filestat_set_times")
} }
pub unsafe fn fd_filestat_set_size( pub fn fd_filestat_set_size(
vmctx: *mut VmContext, wasi_ctx: &WasiCtx,
memory: &mut [u8],
fd: wasm32::__wasi_fd_t, fd: wasm32::__wasi_fd_t,
size: wasm32::__wasi_filesize_t, size: wasm32::__wasi_filesize_t,
) -> wasm32::__wasi_errno_t { ) -> wasm32::__wasi_errno_t {
unimplemented!("fd_filestat_set_size") unimplemented!("fd_filestat_set_size")
} }
pub unsafe fn path_filestat_set_times( pub fn path_filestat_set_times(
vmctx: *mut VmContext, wasi_ctx: &WasiCtx,
memory: &mut [u8],
fd: wasm32::__wasi_fd_t, fd: wasm32::__wasi_fd_t,
flags: wasm32::__wasi_lookupflags_t, flags: wasm32::__wasi_lookupflags_t,
path: wasm32::uintptr_t, path: wasm32::uintptr_t,
@@ -1054,8 +1075,9 @@ pub unsafe fn path_filestat_set_times(
unimplemented!("path_filestat_set_times") unimplemented!("path_filestat_set_times")
} }
pub unsafe fn path_symlink( pub fn path_symlink(
vmctx: *mut VmContext, wasi_ctx: &WasiCtx,
memory: &mut [u8],
path0: wasm32::uintptr_t, path0: wasm32::uintptr_t,
path_len0: wasm32::size_t, path_len0: wasm32::size_t,
fd: wasm32::__wasi_fd_t, fd: wasm32::__wasi_fd_t,
@@ -1065,8 +1087,9 @@ pub unsafe fn path_symlink(
unimplemented!("path_symlink") unimplemented!("path_symlink")
} }
pub unsafe fn path_remove_directory( pub fn path_remove_directory(
vmctx: *mut VmContext, wasi_ctx: &WasiCtx,
memory: &mut [u8],
fd: wasm32::__wasi_fd_t, fd: wasm32::__wasi_fd_t,
path: wasm32::uintptr_t, path: wasm32::uintptr_t,
path_len: wasm32::size_t, path_len: wasm32::size_t,
@@ -1074,19 +1097,21 @@ pub unsafe fn path_remove_directory(
unimplemented!("path_remove_directory") unimplemented!("path_remove_directory")
} }
pub unsafe fn proc_raise( pub fn proc_raise(
_vmctx: *mut VmContext, wasi_ctx: &WasiCtx,
_sig: wasm32::__wasi_signal_t, memory: &mut [u8],
sig: wasm32::__wasi_signal_t,
) -> wasm32::__wasi_errno_t { ) -> wasm32::__wasi_errno_t {
unimplemented!("proc_raise") unimplemented!("proc_raise")
} }
pub unsafe fn sched_yield(_vmctx: *mut VmContext) -> wasm32::__wasi_errno_t { pub fn sched_yield() -> wasm32::__wasi_errno_t {
unimplemented!("sched_yield") unimplemented!("sched_yield")
} }
pub unsafe fn sock_recv( pub fn sock_recv(
vmctx: *mut VmContext, wasi_ctx: &WasiCtx,
memory: &mut [u8],
sock: wasm32::__wasi_fd_t, sock: wasm32::__wasi_fd_t,
ri_data: wasm32::uintptr_t, ri_data: wasm32::uintptr_t,
ri_data_len: wasm32::size_t, ri_data_len: wasm32::size_t,
@@ -1097,8 +1122,9 @@ pub unsafe fn sock_recv(
unimplemented!("sock_recv") unimplemented!("sock_recv")
} }
pub unsafe fn sock_send( pub fn sock_send(
vmctx: *mut VmContext, wasi_ctx: &WasiCtx,
memory: &mut [u8],
sock: wasm32::__wasi_fd_t, sock: wasm32::__wasi_fd_t,
si_data: wasm32::uintptr_t, si_data: wasm32::uintptr_t,
si_data_len: wasm32::size_t, si_data_len: wasm32::size_t,
@@ -1108,8 +1134,9 @@ pub unsafe fn sock_send(
unimplemented!("sock_send") unimplemented!("sock_send")
} }
pub unsafe fn sock_shutdown( pub fn sock_shutdown(
vmctx: *mut VmContext, wasi_ctx: &WasiCtx,
memory: &mut [u8],
sock: wasm32::__wasi_fd_t, sock: wasm32::__wasi_fd_t,
how: wasm32::__wasi_sdflags_t, how: wasm32::__wasi_sdflags_t,
) -> wasm32::__wasi_errno_t { ) -> wasm32::__wasi_errno_t {
@@ -1146,7 +1173,7 @@ struct FdEventData {
} }
fn poll_oneoff_handle_timeout_event( fn poll_oneoff_handle_timeout_event(
vmctx: *mut VmContext, memory: &mut [u8],
output_slice: &mut [wasm32::__wasi_event_t], output_slice: &mut [wasm32::__wasi_event_t],
nevents: wasm32::uintptr_t, nevents: wasm32::uintptr_t,
timeout: Option<ClockEventData>, timeout: Option<ClockEventData>,
@@ -1164,12 +1191,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(vmctx, nevents, 1) } { if let Err(e) = unsafe { 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(vmctx, nevents, 0) } { if let Err(e) = unsafe { enc_pointee(memory, nevents, 0) } {
return enc_errno(e); return enc_errno(e);
} }
} }
@@ -1177,7 +1204,7 @@ fn poll_oneoff_handle_timeout_event(
} }
fn poll_oneoff_handle_fd_event<'t>( fn poll_oneoff_handle_fd_event<'t>(
vmctx: *mut VmContext, memory: &mut [u8],
output_slice: &mut [wasm32::__wasi_event_t], output_slice: &mut [wasm32::__wasi_event_t],
nevents: wasm32::uintptr_t, nevents: wasm32::uintptr_t,
events: impl Iterator<Item = (&'t FdEventData, &'t nix::poll::PollFd)>, events: impl Iterator<Item = (&'t FdEventData, &'t nix::poll::PollFd)>,
@@ -1253,7 +1280,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(vmctx, nevents, revents_count) } { if let Err(e) = unsafe { enc_pointee(memory, nevents, revents_count) } {
return enc_errno(e); return enc_errno(e);
} }
wasm32::__WASI_ESUCCESS wasm32::__WASI_ESUCCESS
@@ -1263,7 +1290,8 @@ fn poll_oneoff_handle_fd_event<'t>(
/// ///
/// This is a workaround for not having Capsicum support in the OS. /// This is a workaround for not having Capsicum support in the OS.
pub fn path_get<P: AsRef<OsStr>>( pub fn path_get<P: AsRef<OsStr>>(
vmctx: &VmContext, wasi_ctx: &WasiCtx,
memory: &mut [u8],
dirfd: host::__wasi_fd_t, dirfd: host::__wasi_fd_t,
dirflags: host::__wasi_lookupflags_t, dirflags: host::__wasi_lookupflags_t,
path: P, path: P,
@@ -1307,9 +1335,7 @@ pub fn path_get<P: AsRef<OsStr>>(
Err(errno) Err(errno)
} }
let ctx = (*vmctx).as_wasi_ctx(); let dirfe = wasi_ctx.get_fd_entry(dirfd, needed_base, needed_inheriting)?;
let dirfe = unsafe { (*ctx).get_fd_entry(dirfd, needed_base, needed_inheriting)? };
// Stack of directory file descriptors. Index 0 always corresponds with the directory provided // Stack of directory file descriptors. Index 0 always corresponds with the directory provided
// to this function. Entering a directory causes a file descriptor to be pushed, while handling // to this function. Entering a directory causes a file descriptor to be pushed, while handling

View File

@@ -9,7 +9,6 @@
//! //!
//! This sort of manual encoding will hopefully be obsolete once the IDL is developed. //! This sort of manual encoding will hopefully be obsolete once the IDL is developed.
use crate::ctx::VmContext;
use crate::{host, wasm32}; use crate::{host, wasm32};
use cast; use cast;
@@ -23,34 +22,53 @@ macro_rules! bail_errno {
}; };
} }
pub unsafe fn dec_ptr(
memory: &mut [u8],
ptr: wasm32::uintptr_t,
len: usize,
) -> Result<*mut u8, host::__wasi_errno_t> {
// check that `len` fits in the wasm32 address space
if len > wasm32::UINTPTR_MAX as usize {
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
Ok(memory.as_mut_ptr().offset(ptr as isize))
}
pub unsafe fn dec_ptr_to<T>( pub unsafe fn dec_ptr_to<T>(
vmctx: *mut VmContext, memory: &mut [u8],
ptr: wasm32::uintptr_t, ptr: wasm32::uintptr_t,
) -> Result<*mut T, host::__wasi_errno_t> { ) -> Result<*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);
} }
(*vmctx).dec_ptr(ptr, size_of::<T>()).map(|p| p as *mut T) dec_ptr(memory, ptr, size_of::<T>()).map(|p| p as *mut T)
} }
pub unsafe fn dec_pointee<T>( pub unsafe fn dec_pointee<T>(
vmctx: *mut VmContext, 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>(vmctx, ptr).map(|p| p.read()) dec_ptr_to::<T>(memory, ptr).map(|p| p.read())
} }
pub unsafe fn enc_pointee<T>( pub unsafe fn enc_pointee<T>(
vmctx: *mut VmContext, 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>(vmctx, ptr).map(|p| p.write(t)) dec_ptr_to::<T>(memory, ptr).map(|p| p.write(t))
} }
pub unsafe fn dec_slice_of<T>( pub unsafe fn dec_slice_of<T>(
vmctx: *mut VmContext, 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<(*mut T, usize), host::__wasi_errno_t> {
@@ -65,13 +83,13 @@ pub unsafe fn dec_slice_of<T>(
return Err(host::__WASI_EOVERFLOW); return Err(host::__WASI_EOVERFLOW);
}; };
let ptr = (*vmctx).dec_ptr(ptr, len_bytes)? as *mut T; let ptr = dec_ptr(memory, ptr, len_bytes)? as *mut T;
Ok((ptr, len)) Ok((ptr, len))
} }
pub unsafe fn enc_slice_of<T>( pub unsafe fn enc_slice_of<T>(
vmctx: *mut VmContext, memory: &mut [u8],
slice: &[T], slice: &[T],
ptr: wasm32::uintptr_t, ptr: wasm32::uintptr_t,
) -> Result<(), host::__wasi_errno_t> { ) -> Result<(), host::__wasi_errno_t> {
@@ -87,7 +105,7 @@ 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 = (*vmctx).dec_ptr(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); libc::memcpy(ptr, slice.as_ptr() as *const libc::c_void, len_bytes);
Ok(()) Ok(())
@@ -100,10 +118,10 @@ macro_rules! dec_enc_scalar {
} }
pub unsafe fn $dec_byref( pub unsafe fn $dec_byref(
vmctx: *mut VmContext, 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> {
dec_pointee::<wasm32::$ty>(vmctx, ptr).map($dec) dec_pointee::<wasm32::$ty>(memory, ptr).map($dec)
} }
pub fn $enc(x: host::$ty) -> wasm32::$ty { pub fn $enc(x: host::$ty) -> wasm32::$ty {
@@ -111,34 +129,34 @@ macro_rules! dec_enc_scalar {
} }
pub unsafe fn $enc_byref( pub unsafe fn $enc_byref(
vmctx: *mut VmContext, memory: &mut [u8],
ptr: wasm32::uintptr_t, ptr: wasm32::uintptr_t,
x: host::$ty, x: host::$ty,
) -> Result<(), host::__wasi_errno_t> { ) -> Result<(), host::__wasi_errno_t> {
enc_pointee::<wasm32::$ty>(vmctx, ptr, $enc(x)) enc_pointee::<wasm32::$ty>(memory, ptr, $enc(x))
} }
}; };
} }
pub unsafe fn dec_ciovec( pub unsafe fn dec_ciovec(
vmctx: *mut VmContext, 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> {
let len = dec_usize(ciovec.buf_len); let len = dec_usize(ciovec.buf_len);
Ok(host::__wasi_ciovec_t { Ok(host::__wasi_ciovec_t {
buf: (*vmctx).dec_ptr(ciovec.buf, len)? as *const host::void, buf: dec_ptr(memory, ciovec.buf, len)? as *const host::void,
buf_len: len, buf_len: len,
}) })
} }
pub unsafe fn dec_ciovec_slice( pub unsafe fn dec_ciovec_slice(
vmctx: *mut VmContext, 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>(vmctx, 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 = slice::from_raw_parts(slice.0, slice.1);
slice.iter().map(|iov| dec_ciovec(vmctx, iov)).collect() slice.iter().map(|iov| dec_ciovec(memory, iov)).collect()
} }
dec_enc_scalar!( dec_enc_scalar!(
@@ -206,10 +224,10 @@ pub fn dec_filestat(filestat: wasm32::__wasi_filestat_t) -> host::__wasi_filesta
} }
pub unsafe fn dec_filestat_byref( pub unsafe fn dec_filestat_byref(
vmctx: *mut VmContext, 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> {
dec_pointee::<wasm32::__wasi_filestat_t>(vmctx, filestat_ptr).map(dec_filestat) dec_pointee::<wasm32::__wasi_filestat_t>(memory, filestat_ptr).map(dec_filestat)
} }
pub fn enc_filestat(filestat: host::__wasi_filestat_t) -> wasm32::__wasi_filestat_t { pub fn enc_filestat(filestat: host::__wasi_filestat_t) -> wasm32::__wasi_filestat_t {
@@ -226,12 +244,12 @@ pub fn enc_filestat(filestat: host::__wasi_filestat_t) -> wasm32::__wasi_filesta
} }
pub unsafe fn enc_filestat_byref( pub unsafe fn enc_filestat_byref(
vmctx: *mut VmContext, 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,
) -> Result<(), host::__wasi_errno_t> { ) -> Result<(), host::__wasi_errno_t> {
let filestat = enc_filestat(host_filestat); let filestat = enc_filestat(host_filestat);
enc_pointee::<wasm32::__wasi_filestat_t>(vmctx, filestat_ptr, filestat) enc_pointee::<wasm32::__wasi_filestat_t>(memory, filestat_ptr, filestat)
} }
pub fn dec_fdstat(fdstat: wasm32::__wasi_fdstat_t) -> host::__wasi_fdstat_t { pub fn dec_fdstat(fdstat: wasm32::__wasi_fdstat_t) -> host::__wasi_fdstat_t {
@@ -244,10 +262,10 @@ pub fn dec_fdstat(fdstat: wasm32::__wasi_fdstat_t) -> host::__wasi_fdstat_t {
} }
pub unsafe fn dec_fdstat_byref( pub unsafe fn dec_fdstat_byref(
vmctx: *mut VmContext, 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> {
dec_pointee::<wasm32::__wasi_fdstat_t>(vmctx, fdstat_ptr).map(dec_fdstat) dec_pointee::<wasm32::__wasi_fdstat_t>(memory, fdstat_ptr).map(dec_fdstat)
} }
pub fn enc_fdstat(fdstat: host::__wasi_fdstat_t) -> wasm32::__wasi_fdstat_t { pub fn enc_fdstat(fdstat: host::__wasi_fdstat_t) -> wasm32::__wasi_fdstat_t {
@@ -261,12 +279,12 @@ pub fn enc_fdstat(fdstat: host::__wasi_fdstat_t) -> wasm32::__wasi_fdstat_t {
} }
pub unsafe fn enc_fdstat_byref( pub unsafe fn enc_fdstat_byref(
vmctx: *mut VmContext, 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,
) -> Result<(), host::__wasi_errno_t> { ) -> Result<(), host::__wasi_errno_t> {
let fdstat = enc_fdstat(host_fdstat); let fdstat = enc_fdstat(host_fdstat);
enc_pointee::<wasm32::__wasi_fdstat_t>(vmctx, fdstat_ptr, fdstat) enc_pointee::<wasm32::__wasi_fdstat_t>(memory, fdstat_ptr, fdstat)
} }
dec_enc_scalar!( dec_enc_scalar!(
@@ -328,10 +346,10 @@ pub fn dec_prestat(
} }
pub unsafe fn dec_prestat_byref( pub unsafe fn dec_prestat_byref(
vmctx: *mut VmContext, 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> {
dec_pointee::<wasm32::__wasi_prestat_t>(vmctx, prestat_ptr).and_then(dec_prestat) dec_pointee::<wasm32::__wasi_prestat_t>(memory, prestat_ptr).and_then(dec_prestat)
} }
pub fn enc_prestat( pub fn enc_prestat(
@@ -354,12 +372,12 @@ pub fn enc_prestat(
} }
pub unsafe fn enc_prestat_byref( pub unsafe fn enc_prestat_byref(
vmctx: *mut VmContext, 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,
) -> Result<(), host::__wasi_errno_t> { ) -> Result<(), host::__wasi_errno_t> {
let prestat = enc_prestat(host_prestat)?; let prestat = enc_prestat(host_prestat)?;
enc_pointee::<wasm32::__wasi_prestat_t>(vmctx, prestat_ptr, prestat) enc_pointee::<wasm32::__wasi_prestat_t>(memory, prestat_ptr, prestat)
} }
dec_enc_scalar!( dec_enc_scalar!(
@@ -386,11 +404,11 @@ pub fn enc_usize(size: usize) -> wasm32::size_t {
} }
pub unsafe fn enc_usize_byref( pub unsafe fn enc_usize_byref(
vmctx: *mut VmContext, memory: &mut [u8],
usize_ptr: wasm32::uintptr_t, usize_ptr: wasm32::uintptr_t,
host_usize: usize, host_usize: usize,
) -> Result<(), host::__wasi_errno_t> { ) -> Result<(), host::__wasi_errno_t> {
enc_pointee::<wasm32::size_t>(vmctx, usize_ptr, enc_usize(host_usize)) enc_pointee::<wasm32::size_t>(memory, usize_ptr, enc_usize(host_usize))
} }
dec_enc_scalar!( dec_enc_scalar!(