Insulate API from intricacies of memory mgmt of calling runtimes
This commit is contained in:
22
src/ctx.rs
22
src/ctx.rs
@@ -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>,
|
||||||
@@ -198,16 +186,6 @@ pub struct WasiCtx {
|
|||||||
pub env: Vec<CString>,
|
pub env: Vec<CString>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for WasiCtx {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self {
|
|
||||||
fds: HashMap::new(),
|
|
||||||
args: Vec::new(),
|
|
||||||
env: Vec::new(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl WasiCtx {
|
impl WasiCtx {
|
||||||
/// Make a new `WasiCtx` with some default settings.
|
/// Make a new `WasiCtx` with some default settings.
|
||||||
///
|
///
|
||||||
|
|||||||
366
src/hostcalls.rs
366
src/hostcalls.rs
@@ -11,9 +11,9 @@
|
|||||||
#![allow(non_camel_case_types)]
|
#![allow(non_camel_case_types)]
|
||||||
#![allow(unused_unsafe)]
|
#![allow(unused_unsafe)]
|
||||||
#![allow(unused)]
|
#![allow(unused)]
|
||||||
|
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::vmctx::VmContextView;
|
|
||||||
use crate::{host, wasm32};
|
use crate::{host, wasm32};
|
||||||
|
|
||||||
use cast::From as _0;
|
use cast::From as _0;
|
||||||
@@ -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 VmContextView, 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 VmContextView,
|
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.get_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 VmContextView,
|
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.get_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 VmContextView,
|
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 VmContextView,
|
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 VmContextView,
|
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.get_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 VmContextView,
|
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.get_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,19 +228,15 @@ pub unsafe fn environ_sizes_get(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn fd_close(
|
pub fn fd_close(wasi_ctx: &mut WasiCtx, fd: wasm32::__wasi_fd_t) -> wasm32::__wasi_errno_t {
|
||||||
vmctx: &mut VmContextView,
|
|
||||||
fd: wasm32::__wasi_fd_t,
|
|
||||||
) -> wasm32::__wasi_errno_t {
|
|
||||||
let mut ctx = vmctx.get_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,
|
||||||
@@ -255,19 +247,19 @@ pub unsafe fn fd_close(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn fd_fdstat_get(
|
pub fn fd_fdstat_get(
|
||||||
vmctx: &mut VmContextView,
|
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.get_wasi_ctx();
|
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;
|
||||||
@@ -284,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 VmContextView,
|
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 {
|
||||||
@@ -300,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.get_wasi_ctx();
|
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()),
|
||||||
@@ -312,14 +302,14 @@ pub unsafe fn fd_fdstat_set_flags(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn fd_seek(
|
pub fn fd_seek(
|
||||||
vmctx: &mut VmContextView,
|
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.get_wasi_ctx();
|
|
||||||
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);
|
||||||
@@ -338,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()),
|
||||||
@@ -348,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 VmContextView,
|
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.get_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 {
|
||||||
@@ -370,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,
|
||||||
@@ -393,18 +383,16 @@ pub unsafe fn fd_prestat_get(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn fd_prestat_dir_name(
|
pub fn fd_prestat_dir_name(
|
||||||
vmctx: &mut VmContextView,
|
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
|
match wasi_ctx.get_fd_entry(fd, host::__WASI_RIGHT_PATH_OPEN.into(), 0) {
|
||||||
.get_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 {
|
||||||
@@ -415,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)
|
||||||
}
|
}
|
||||||
@@ -427,8 +415,9 @@ pub unsafe fn fd_prestat_dir_name(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn fd_read(
|
pub fn fd_read(
|
||||||
vmctx: &mut VmContextView,
|
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,
|
||||||
@@ -437,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 mut ctx = vmctx.get_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),
|
||||||
};
|
};
|
||||||
@@ -460,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 VmContextView,
|
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,
|
||||||
@@ -481,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.get_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),
|
||||||
};
|
};
|
||||||
@@ -503,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 VmContextView,
|
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,
|
||||||
@@ -575,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,
|
||||||
@@ -633,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.get_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),
|
||||||
}
|
}
|
||||||
@@ -641,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 VmContextView,
|
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 { dec_ptr(vmctx, 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),
|
||||||
};
|
};
|
||||||
@@ -667,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 VmContextView,
|
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,
|
||||||
@@ -677,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();
|
||||||
@@ -750,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 VmContextView,
|
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.get_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
|
||||||
@@ -784,8 +774,9 @@ pub unsafe fn fd_filestat_get(
|
|||||||
errno
|
errno
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn path_filestat_get(
|
pub fn path_filestat_get(
|
||||||
vmctx: &mut VmContextView,
|
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,
|
||||||
@@ -797,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,
|
||||||
@@ -822,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
|
||||||
@@ -830,8 +822,9 @@ pub unsafe fn path_filestat_get(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn path_create_directory(
|
pub fn path_create_directory(
|
||||||
vmctx: &mut VmContextView,
|
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,
|
||||||
@@ -840,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,
|
||||||
@@ -867,8 +861,9 @@ pub unsafe fn path_create_directory(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn path_unlink_file(
|
pub fn path_unlink_file(
|
||||||
vmctx: &mut VmContextView,
|
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,
|
||||||
@@ -877,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,
|
||||||
@@ -904,15 +900,17 @@ pub unsafe fn path_unlink_file(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn fd_datasync(
|
pub fn fd_datasync(
|
||||||
vmctx: &mut VmContextView,
|
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 VmContextView,
|
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,
|
||||||
@@ -922,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 VmContextView,
|
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,
|
||||||
@@ -933,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 VmContextView,
|
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 VmContextView,
|
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 VmContextView,
|
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,
|
||||||
@@ -958,15 +960,17 @@ pub unsafe fn fd_fdstat_set_rights(
|
|||||||
unimplemented!("fd_fdstat_set_rights")
|
unimplemented!("fd_fdstat_set_rights")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn fd_sync(
|
pub fn fd_sync(
|
||||||
vmctx: &mut VmContextView,
|
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_sync")
|
unimplemented!("fd_sync")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn fd_advise(
|
pub fn fd_advise(
|
||||||
vmctx: &mut VmContextView,
|
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 +979,9 @@ pub unsafe fn fd_advise(
|
|||||||
unimplemented!("fd_advise")
|
unimplemented!("fd_advise")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn fd_allocate(
|
pub fn fd_allocate(
|
||||||
vmctx: &mut VmContextView,
|
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,
|
||||||
@@ -984,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 VmContextView,
|
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,
|
||||||
@@ -997,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 VmContextView,
|
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,
|
||||||
@@ -1008,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 VmContextView,
|
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,
|
||||||
@@ -1020,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 VmContextView,
|
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,
|
||||||
@@ -1032,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 VmContextView,
|
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,
|
||||||
@@ -1042,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 VmContextView,
|
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 VmContextView,
|
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,
|
||||||
@@ -1063,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 VmContextView,
|
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,
|
||||||
@@ -1074,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 VmContextView,
|
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,
|
||||||
@@ -1083,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 VmContextView,
|
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 VmContextView) -> 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 VmContextView,
|
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,
|
||||||
@@ -1106,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 VmContextView,
|
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,
|
||||||
@@ -1117,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 VmContextView,
|
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 {
|
||||||
@@ -1155,7 +1173,7 @@ struct FdEventData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn poll_oneoff_handle_timeout_event(
|
fn poll_oneoff_handle_timeout_event(
|
||||||
vmctx: &mut VmContextView,
|
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>,
|
||||||
@@ -1173,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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1186,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 VmContextView,
|
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)>,
|
||||||
@@ -1262,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
|
||||||
@@ -1272,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: &VmContextView,
|
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,
|
||||||
@@ -1316,8 +1335,7 @@ pub fn path_get<P: AsRef<OsStr>>(
|
|||||||
Err(errno)
|
Err(errno)
|
||||||
}
|
}
|
||||||
|
|
||||||
let ctx = vmctx.get_wasi_ctx();
|
let dirfe = wasi_ctx.get_fd_entry(dirfd, needed_base, needed_inheriting)?;
|
||||||
let dirfe = 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
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ pub mod fdentry;
|
|||||||
pub mod host;
|
pub mod host;
|
||||||
pub mod hostcalls;
|
pub mod hostcalls;
|
||||||
pub mod memory;
|
pub mod memory;
|
||||||
pub mod vmctx;
|
|
||||||
pub mod wasm32;
|
pub mod wasm32;
|
||||||
|
|
||||||
pub use ctx::{WasiCtx, WasiCtxBuilder};
|
pub use ctx::{WasiCtx, WasiCtxBuilder};
|
||||||
|
|||||||
@@ -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::vmctx::VmContextView;
|
|
||||||
use crate::{host, wasm32};
|
use crate::{host, wasm32};
|
||||||
|
|
||||||
use cast;
|
use cast;
|
||||||
@@ -24,54 +23,52 @@ macro_rules! bail_errno {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn dec_ptr(
|
pub unsafe fn dec_ptr(
|
||||||
vmctx: &VmContextView,
|
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> {
|
||||||
let mut heap = vmctx.memory_mut();
|
|
||||||
|
|
||||||
// check that `len` fits in the wasm32 address space
|
// check that `len` fits in the wasm32 address space
|
||||||
if len > wasm32::UINTPTR_MAX as usize {
|
if len > wasm32::UINTPTR_MAX as usize {
|
||||||
bail_errno!(__WASI_EOVERFLOW);
|
bail_errno!(__WASI_EOVERFLOW);
|
||||||
}
|
}
|
||||||
|
|
||||||
// check that `ptr` and `ptr + len` are both within the guest heap
|
// check that `ptr` and `ptr + len` are both within the guest heap
|
||||||
if ptr as usize > heap.len() || ptr as usize + len > heap.len() {
|
if ptr as usize > memory.len() || ptr as usize + len > memory.len() {
|
||||||
bail_errno!(__WASI_EFAULT);
|
bail_errno!(__WASI_EFAULT);
|
||||||
}
|
}
|
||||||
|
|
||||||
// translate the pointer
|
// translate the pointer
|
||||||
Ok(heap.as_mut_ptr().offset(ptr as isize))
|
Ok(memory.as_mut_ptr().offset(ptr as isize))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn dec_ptr_to<T>(
|
pub unsafe fn dec_ptr_to<T>(
|
||||||
vmctx: &VmContextView,
|
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);
|
||||||
}
|
}
|
||||||
dec_ptr(vmctx, 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: &VmContextView,
|
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: &VmContextView,
|
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: &VmContextView,
|
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> {
|
||||||
@@ -86,13 +83,13 @@ pub unsafe fn dec_slice_of<T>(
|
|||||||
return Err(host::__WASI_EOVERFLOW);
|
return Err(host::__WASI_EOVERFLOW);
|
||||||
};
|
};
|
||||||
|
|
||||||
let ptr = dec_ptr(vmctx, 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: &VmContextView,
|
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> {
|
||||||
@@ -108,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 = dec_ptr(vmctx, 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(())
|
||||||
@@ -121,10 +118,10 @@ macro_rules! dec_enc_scalar {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn $dec_byref(
|
pub unsafe fn $dec_byref(
|
||||||
vmctx: &VmContextView,
|
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 {
|
||||||
@@ -132,34 +129,34 @@ macro_rules! dec_enc_scalar {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn $enc_byref(
|
pub unsafe fn $enc_byref(
|
||||||
vmctx: &VmContextView,
|
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: &VmContextView,
|
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: dec_ptr(vmctx, 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: &VmContextView,
|
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!(
|
||||||
@@ -227,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: &VmContextView,
|
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 {
|
||||||
@@ -247,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: &VmContextView,
|
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 {
|
||||||
@@ -265,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: &VmContextView,
|
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 {
|
||||||
@@ -282,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: &VmContextView,
|
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!(
|
||||||
@@ -349,10 +346,10 @@ pub fn dec_prestat(
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn dec_prestat_byref(
|
pub unsafe fn dec_prestat_byref(
|
||||||
vmctx: &VmContextView,
|
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(
|
||||||
@@ -375,12 +372,12 @@ pub fn enc_prestat(
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn enc_prestat_byref(
|
pub unsafe fn enc_prestat_byref(
|
||||||
vmctx: &VmContextView,
|
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!(
|
||||||
@@ -407,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: &VmContextView,
|
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!(
|
||||||
|
|||||||
59
src/vmctx.rs
59
src/vmctx.rs
@@ -1,59 +0,0 @@
|
|||||||
//! This code borrows heavily from Lucet's Vmctx implementation
|
|
||||||
//! https://github.com/fastly/lucet/blob/master/lucet-runtime/lucet-runtime-internals/src/vmctx.rs
|
|
||||||
|
|
||||||
use crate::ctx::WasiCtx;
|
|
||||||
use std::borrow::{Borrow, BorrowMut};
|
|
||||||
use std::cell::{Ref, RefCell, RefMut};
|
|
||||||
|
|
||||||
pub trait AsVmContextView {
|
|
||||||
unsafe fn as_vm_context_view(&mut self) -> VmContextView;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct VmContextView {
|
|
||||||
pub memory_view: RefCell<Box<[u8]>>,
|
|
||||||
pub wasi_ctx_view: RefCell<Box<WasiCtx>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Drop for VmContextView {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
let memory_view = self.memory_view.replace(Box::new([]));
|
|
||||||
let wasi_ctx_view = self.wasi_ctx_view.replace(Box::new(WasiCtx::default()));
|
|
||||||
Box::leak(memory_view);
|
|
||||||
Box::leak(wasi_ctx_view);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl VmContextView {
|
|
||||||
pub fn memory(&self) -> Ref<[u8]> {
|
|
||||||
let r = self
|
|
||||||
.memory_view
|
|
||||||
.try_borrow()
|
|
||||||
.expect("memory not already borrowed mutably");
|
|
||||||
Ref::map(r, |b| b.borrow())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn memory_mut(&self) -> RefMut<[u8]> {
|
|
||||||
let r = self
|
|
||||||
.memory_view
|
|
||||||
.try_borrow_mut()
|
|
||||||
.expect("memory not already borrowed");
|
|
||||||
RefMut::map(r, |b| b.borrow_mut())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_wasi_ctx(&self) -> Ref<WasiCtx> {
|
|
||||||
let r = self
|
|
||||||
.wasi_ctx_view
|
|
||||||
.try_borrow()
|
|
||||||
.expect("WASI context not already borrowed mutably");
|
|
||||||
Ref::map(r, |b| b.borrow())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_wasi_ctx_mut(&self) -> RefMut<WasiCtx> {
|
|
||||||
let r = self
|
|
||||||
.wasi_ctx_view
|
|
||||||
.try_borrow_mut()
|
|
||||||
.expect("WASI context not already borrowed");
|
|
||||||
RefMut::map(r, |b| b.borrow_mut())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user