Migrate to wasi-common crate
This commit is contained in:
@@ -1,88 +0,0 @@
|
||||
#![allow(non_camel_case_types, dead_code)]
|
||||
|
||||
include!(concat!(env!("OUT_DIR"), "/wasmtime_ssp.rs"));
|
||||
|
||||
pub type char = ::std::os::raw::c_char;
|
||||
pub type void = ::std::os::raw::c_void;
|
||||
// pub type __wasi_errno_t = u16;
|
||||
|
||||
pub const __WASI_ESUCCESS: __wasi_errno_t = 0;
|
||||
pub const __WASI_E2BIG: __wasi_errno_t = 1;
|
||||
pub const __WASI_EACCES: __wasi_errno_t = 2;
|
||||
pub const __WASI_EADDRINUSE: __wasi_errno_t = 3;
|
||||
pub const __WASI_EADDRNOTAVAIL: __wasi_errno_t = 4;
|
||||
pub const __WASI_EAFNOSUPPORT: __wasi_errno_t = 5;
|
||||
pub const __WASI_EAGAIN: __wasi_errno_t = 6;
|
||||
pub const __WASI_EALREADY: __wasi_errno_t = 7;
|
||||
pub const __WASI_EBADF: __wasi_errno_t = 8;
|
||||
pub const __WASI_EBADMSG: __wasi_errno_t = 9;
|
||||
pub const __WASI_EBUSY: __wasi_errno_t = 10;
|
||||
pub const __WASI_ECANCELED: __wasi_errno_t = 11;
|
||||
pub const __WASI_ECHILD: __wasi_errno_t = 12;
|
||||
pub const __WASI_ECONNABORTED: __wasi_errno_t = 13;
|
||||
pub const __WASI_ECONNREFUSED: __wasi_errno_t = 14;
|
||||
pub const __WASI_ECONNRESET: __wasi_errno_t = 15;
|
||||
pub const __WASI_EDEADLK: __wasi_errno_t = 16;
|
||||
pub const __WASI_EDESTADDRREQ: __wasi_errno_t = 17;
|
||||
pub const __WASI_EDOM: __wasi_errno_t = 18;
|
||||
pub const __WASI_EDQUOT: __wasi_errno_t = 19;
|
||||
pub const __WASI_EEXIST: __wasi_errno_t = 20;
|
||||
pub const __WASI_EFAULT: __wasi_errno_t = 21;
|
||||
pub const __WASI_EFBIG: __wasi_errno_t = 22;
|
||||
pub const __WASI_EHOSTUNREACH: __wasi_errno_t = 23;
|
||||
pub const __WASI_EIDRM: __wasi_errno_t = 24;
|
||||
pub const __WASI_EILSEQ: __wasi_errno_t = 25;
|
||||
pub const __WASI_EINPROGRESS: __wasi_errno_t = 26;
|
||||
pub const __WASI_EINTR: __wasi_errno_t = 27;
|
||||
pub const __WASI_EINVAL: __wasi_errno_t = 28;
|
||||
pub const __WASI_EIO: __wasi_errno_t = 29;
|
||||
pub const __WASI_EISCONN: __wasi_errno_t = 30;
|
||||
pub const __WASI_EISDIR: __wasi_errno_t = 31;
|
||||
pub const __WASI_ELOOP: __wasi_errno_t = 32;
|
||||
pub const __WASI_EMFILE: __wasi_errno_t = 33;
|
||||
pub const __WASI_EMLINK: __wasi_errno_t = 34;
|
||||
pub const __WASI_EMSGSIZE: __wasi_errno_t = 35;
|
||||
pub const __WASI_EMULTIHOP: __wasi_errno_t = 36;
|
||||
pub const __WASI_ENAMETOOLONG: __wasi_errno_t = 37;
|
||||
pub const __WASI_ENETDOWN: __wasi_errno_t = 38;
|
||||
pub const __WASI_ENETRESET: __wasi_errno_t = 39;
|
||||
pub const __WASI_ENETUNREACH: __wasi_errno_t = 40;
|
||||
pub const __WASI_ENFILE: __wasi_errno_t = 41;
|
||||
pub const __WASI_ENOBUFS: __wasi_errno_t = 42;
|
||||
pub const __WASI_ENODEV: __wasi_errno_t = 43;
|
||||
pub const __WASI_ENOENT: __wasi_errno_t = 44;
|
||||
pub const __WASI_ENOEXEC: __wasi_errno_t = 45;
|
||||
pub const __WASI_ENOLCK: __wasi_errno_t = 46;
|
||||
pub const __WASI_ENOLINK: __wasi_errno_t = 47;
|
||||
pub const __WASI_ENOMEM: __wasi_errno_t = 48;
|
||||
pub const __WASI_ENOMSG: __wasi_errno_t = 49;
|
||||
pub const __WASI_ENOPROTOOPT: __wasi_errno_t = 50;
|
||||
pub const __WASI_ENOSPC: __wasi_errno_t = 51;
|
||||
pub const __WASI_ENOSYS: __wasi_errno_t = 52;
|
||||
pub const __WASI_ENOTCONN: __wasi_errno_t = 53;
|
||||
pub const __WASI_ENOTDIR: __wasi_errno_t = 54;
|
||||
pub const __WASI_ENOTEMPTY: __wasi_errno_t = 55;
|
||||
pub const __WASI_ENOTRECOVERABLE: __wasi_errno_t = 56;
|
||||
pub const __WASI_ENOTSOCK: __wasi_errno_t = 57;
|
||||
pub const __WASI_ENOTSUP: __wasi_errno_t = 58;
|
||||
pub const __WASI_ENOTTY: __wasi_errno_t = 59;
|
||||
pub const __WASI_ENXIO: __wasi_errno_t = 60;
|
||||
pub const __WASI_EOVERFLOW: __wasi_errno_t = 61;
|
||||
pub const __WASI_EOWNERDEAD: __wasi_errno_t = 62;
|
||||
pub const __WASI_EPERM: __wasi_errno_t = 63;
|
||||
pub const __WASI_EPIPE: __wasi_errno_t = 64;
|
||||
pub const __WASI_EPROTO: __wasi_errno_t = 65;
|
||||
pub const __WASI_EPROTONOSUPPORT: __wasi_errno_t = 66;
|
||||
pub const __WASI_EPROTOTYPE: __wasi_errno_t = 67;
|
||||
pub const __WASI_ERANGE: __wasi_errno_t = 68;
|
||||
pub const __WASI_EROFS: __wasi_errno_t = 69;
|
||||
pub const __WASI_ESPIPE: __wasi_errno_t = 70;
|
||||
pub const __WASI_ESRCH: __wasi_errno_t = 71;
|
||||
pub const __WASI_ESTALE: __wasi_errno_t = 72;
|
||||
pub const __WASI_ETIMEDOUT: __wasi_errno_t = 73;
|
||||
pub const __WASI_ETXTBSY: __wasi_errno_t = 74;
|
||||
pub const __WASI_EXDEV: __wasi_errno_t = 75;
|
||||
pub const __WASI_ENOTCAPABLE: __wasi_errno_t = 76;
|
||||
|
||||
// pub type __wasi_preopentype_t = u8;
|
||||
pub const __WASI_PREOPENTYPE_DIR: __wasi_preopentype_t = 0;
|
||||
@@ -1,183 +0,0 @@
|
||||
use super::host;
|
||||
use super::wasm32;
|
||||
use errno::{errno, Errno};
|
||||
|
||||
/// Convert POSIX error code to host's WASI error code
|
||||
fn convert_errno(error: Errno) -> host::__wasi_errno_t {
|
||||
#[allow(unreachable_patterns)]
|
||||
match error.into() {
|
||||
libc::E2BIG => host::__WASI_E2BIG,
|
||||
libc::EACCES => host::__WASI_EACCES,
|
||||
libc::EADDRINUSE => host::__WASI_EADDRINUSE,
|
||||
libc::EADDRNOTAVAIL => host::__WASI_EADDRNOTAVAIL,
|
||||
libc::EAFNOSUPPORT => host::__WASI_EAFNOSUPPORT,
|
||||
libc::EAGAIN | libc::EWOULDBLOCK => host::__WASI_EAGAIN,
|
||||
libc::EALREADY => host::__WASI_EALREADY,
|
||||
libc::EBADF => host::__WASI_EBADF,
|
||||
libc::EBADMSG => host::__WASI_EBADMSG,
|
||||
libc::EBUSY => host::__WASI_EBUSY,
|
||||
libc::ECANCELED => host::__WASI_ECANCELED,
|
||||
libc::ECHILD => host::__WASI_ECHILD,
|
||||
libc::ECONNABORTED => host::__WASI_ECONNABORTED,
|
||||
libc::ECONNREFUSED => host::__WASI_ECONNREFUSED,
|
||||
libc::ECONNRESET => host::__WASI_ECONNRESET,
|
||||
libc::EDEADLK => host::__WASI_EDEADLK,
|
||||
libc::EDESTADDRREQ => host::__WASI_EDESTADDRREQ,
|
||||
libc::EDOM => host::__WASI_EDOM,
|
||||
libc::EDQUOT => host::__WASI_EDQUOT,
|
||||
libc::EEXIST => host::__WASI_EEXIST,
|
||||
libc::EFAULT => host::__WASI_EFAULT,
|
||||
libc::EFBIG => host::__WASI_EFBIG,
|
||||
libc::EHOSTUNREACH => host::__WASI_EHOSTUNREACH,
|
||||
libc::EIDRM => host::__WASI_EIDRM,
|
||||
libc::EILSEQ => host::__WASI_EILSEQ,
|
||||
libc::EINPROGRESS => host::__WASI_EINPROGRESS,
|
||||
libc::EINTR => host::__WASI_EINTR,
|
||||
libc::EINVAL => host::__WASI_EINVAL,
|
||||
libc::EIO => host::__WASI_EIO,
|
||||
libc::EISCONN => host::__WASI_EISCONN,
|
||||
libc::EISDIR => host::__WASI_EISDIR,
|
||||
libc::ELOOP => host::__WASI_ELOOP,
|
||||
libc::EMFILE => host::__WASI_EMFILE,
|
||||
libc::EMLINK => host::__WASI_EMLINK,
|
||||
libc::EMSGSIZE => host::__WASI_EMSGSIZE,
|
||||
libc::EMULTIHOP => host::__WASI_EMULTIHOP,
|
||||
libc::ENAMETOOLONG => host::__WASI_ENAMETOOLONG,
|
||||
libc::ENETDOWN => host::__WASI_ENETDOWN,
|
||||
libc::ENETRESET => host::__WASI_ENETRESET,
|
||||
libc::ENETUNREACH => host::__WASI_ENETUNREACH,
|
||||
libc::ENFILE => host::__WASI_ENFILE,
|
||||
libc::ENOBUFS => host::__WASI_ENOBUFS,
|
||||
libc::ENODEV => host::__WASI_ENODEV,
|
||||
libc::ENOENT => host::__WASI_ENOENT,
|
||||
libc::ENOEXEC => host::__WASI_ENOEXEC,
|
||||
libc::ENOLCK => host::__WASI_ENOLCK,
|
||||
libc::ENOLINK => host::__WASI_ENOLINK,
|
||||
libc::ENOMEM => host::__WASI_ENOMEM,
|
||||
libc::ENOMSG => host::__WASI_ENOMSG,
|
||||
libc::ENOPROTOOPT => host::__WASI_ENOPROTOOPT,
|
||||
libc::ENOSPC => host::__WASI_ENOSPC,
|
||||
libc::ENOSYS => host::__WASI_ENOSYS,
|
||||
// TODO: verify if this is correct
|
||||
#[cfg(target_os = "freebsd")]
|
||||
libc::ENOTCAPABLE => host::__WASI_ENOTCAPABLE,
|
||||
libc::ENOTCONN => host::__WASI_ENOTCONN,
|
||||
libc::ENOTDIR => host::__WASI_ENOTDIR,
|
||||
libc::ENOTEMPTY => host::__WASI_ENOTEMPTY,
|
||||
libc::ENOTRECOVERABLE => host::__WASI_ENOTRECOVERABLE,
|
||||
libc::ENOTSOCK => host::__WASI_ENOTSOCK,
|
||||
libc::ENOTSUP | libc::EOPNOTSUPP => host::__WASI_ENOTSUP,
|
||||
libc::ENOTTY => host::__WASI_ENOTTY,
|
||||
libc::ENXIO => host::__WASI_ENXIO,
|
||||
libc::EOVERFLOW => host::__WASI_EOVERFLOW,
|
||||
libc::EOWNERDEAD => host::__WASI_EOWNERDEAD,
|
||||
libc::EPERM => host::__WASI_EPERM,
|
||||
libc::EPIPE => host::__WASI_EPIPE,
|
||||
libc::EPROTO => host::__WASI_EPROTO,
|
||||
libc::EPROTONOSUPPORT => host::__WASI_EPROTONOSUPPORT,
|
||||
libc::EPROTOTYPE => host::__WASI_EPROTOTYPE,
|
||||
libc::ERANGE => host::__WASI_ERANGE,
|
||||
libc::EROFS => host::__WASI_EROFS,
|
||||
libc::ESPIPE => host::__WASI_ESPIPE,
|
||||
libc::ESRCH => host::__WASI_ESRCH,
|
||||
libc::ESTALE => host::__WASI_ESTALE,
|
||||
libc::ETIMEDOUT => host::__WASI_ETIMEDOUT,
|
||||
libc::ETXTBSY => host::__WASI_ETXTBSY,
|
||||
libc::EXDEV => host::__WASI_EXDEV,
|
||||
_ => host::__WASI_ENOSYS,
|
||||
}
|
||||
}
|
||||
|
||||
fn fd_prestats_get_entry(
|
||||
pt: &host::fd_prestats,
|
||||
fd: host::__wasi_fd_t,
|
||||
) -> Option<&host::fd_prestat> {
|
||||
// Test for file descriptor existence
|
||||
if fd as usize >= pt.size {
|
||||
return None;
|
||||
}
|
||||
|
||||
let prestat = unsafe { &*pt.prestats.add(fd as usize) };
|
||||
if prestat.dir_name == ::std::ptr::null() {
|
||||
return None;
|
||||
}
|
||||
|
||||
Some(prestat)
|
||||
}
|
||||
|
||||
macro_rules! rwlock_rdlock {
|
||||
($prestats:expr) => {
|
||||
unsafe {
|
||||
host::rwlock_rdlock(&mut (*$prestats).lock as *mut host::rwlock);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! rwlock_unlock {
|
||||
($prestats:expr) => {
|
||||
unsafe {
|
||||
host::rwlock_unlock(&mut (*$prestats).lock as *mut host::rwlock);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub fn wasmtime_ssp_proc_exit(rval: wasm32::__wasi_exitcode_t) {
|
||||
::std::process::exit(rval as i32)
|
||||
}
|
||||
|
||||
pub fn wasmtime_ssp_fd_prestat_get(
|
||||
prestats: &mut host::fd_prestats,
|
||||
fd: host::__wasi_fd_t,
|
||||
buf: &mut host::__wasi_prestat_t,
|
||||
) -> host::__wasi_errno_t {
|
||||
rwlock_rdlock!(prestats);
|
||||
|
||||
let ret_code = if let Some(prestat) = fd_prestats_get_entry(prestats, fd) {
|
||||
buf.pr_type = host::__WASI_PREOPENTYPE_DIR;
|
||||
unsafe {
|
||||
buf.u.dir.pr_name_len = prestat.dir_name_len;
|
||||
}
|
||||
host::__WASI_ESUCCESS
|
||||
} else {
|
||||
host::__WASI_EBADF
|
||||
};
|
||||
|
||||
rwlock_unlock!(prestats);
|
||||
|
||||
ret_code
|
||||
}
|
||||
|
||||
pub fn wasmtime_ssp_fd_prestat_dir_name(
|
||||
prestats: &mut host::fd_prestats,
|
||||
fd: host::__wasi_fd_t,
|
||||
path: &mut [host::char],
|
||||
) -> host::__wasi_errno_t {
|
||||
rwlock_rdlock!(prestats);
|
||||
|
||||
let ret_code = if let Some(prestat) = fd_prestats_get_entry(prestats, fd) {
|
||||
if path.len() != prestat.dir_name_len {
|
||||
host::__WASI_EINVAL
|
||||
} else {
|
||||
path.copy_from_slice(unsafe {
|
||||
::std::slice::from_raw_parts(prestat.dir_name, prestat.dir_name_len)
|
||||
});
|
||||
host::__WASI_ESUCCESS
|
||||
}
|
||||
} else {
|
||||
host::__WASI_EBADF
|
||||
};
|
||||
|
||||
rwlock_unlock!(prestats);
|
||||
|
||||
ret_code
|
||||
}
|
||||
|
||||
pub fn wasmtime_ssp_sched_yield() -> host::__wasi_errno_t {
|
||||
unsafe {
|
||||
if libc::sched_yield() < 0 {
|
||||
return convert_errno(errno());
|
||||
}
|
||||
}
|
||||
|
||||
host::__WASI_ESUCCESS
|
||||
}
|
||||
@@ -1,32 +1,22 @@
|
||||
use crate::host::{
|
||||
argv_environ_init, argv_environ_values, fd_prestats, fd_prestats_init, fd_prestats_insert,
|
||||
fd_table, fd_table_init, fd_table_insert_existing,
|
||||
};
|
||||
use cranelift_codegen::ir::types;
|
||||
use cranelift_codegen::{ir, isa};
|
||||
use cranelift_entity::PrimaryMap;
|
||||
use cranelift_wasm::DefinedFuncIndex;
|
||||
use std::cell::RefCell;
|
||||
use std::collections::HashMap;
|
||||
use std::ffi::CString;
|
||||
use std::mem;
|
||||
use std::fs::File;
|
||||
use std::rc::Rc;
|
||||
use syscalls;
|
||||
use target_lexicon::HOST;
|
||||
use wasi_common::WasiCtxBuilder;
|
||||
use wasmtime_environ::{translate_signature, Export, Module};
|
||||
use wasmtime_runtime::{Imports, InstanceHandle, InstantiationError, VMFunctionBody};
|
||||
|
||||
pub(crate) struct WASIState {
|
||||
pub curfds: Box<fd_table>,
|
||||
pub prestats: Box<fd_prestats>,
|
||||
pub argv_environ: Box<argv_environ_values>,
|
||||
}
|
||||
|
||||
/// Return an instance implementing the "wasi" interface.
|
||||
pub fn instantiate_wasi(
|
||||
prefix: &str,
|
||||
global_exports: Rc<RefCell<HashMap<String, Option<wasmtime_runtime::Export>>>>,
|
||||
preopened_dirs: &[(String, libc::c_int)],
|
||||
preopened_dirs: &[(String, File)],
|
||||
argv: &[String],
|
||||
environ: &[(String, String)],
|
||||
) -> Result<InstanceHandle, InstantiationError> {
|
||||
@@ -110,54 +100,29 @@ pub fn instantiate_wasi(
|
||||
let imports = Imports::none();
|
||||
let data_initializers = Vec::new();
|
||||
let signatures = PrimaryMap::new();
|
||||
let mut curfds = Box::new(unsafe { mem::zeroed::<fd_table>() });
|
||||
let mut prestats = Box::new(unsafe { mem::zeroed::<fd_prestats>() });
|
||||
let mut argv_environ = Box::new(unsafe { mem::zeroed::<argv_environ_values>() });
|
||||
|
||||
unsafe {
|
||||
let argv_environ: &mut argv_environ_values = &mut *argv_environ;
|
||||
let (argv_offsets, argv_buf, environ_offsets, environ_buf) =
|
||||
allocate_argv_environ(argv, environ);
|
||||
argv_environ_init(
|
||||
argv_environ,
|
||||
argv_offsets.as_ptr(),
|
||||
argv_offsets.len(),
|
||||
argv_buf.as_ptr(),
|
||||
argv_buf.len(),
|
||||
environ_offsets.as_ptr(),
|
||||
environ_offsets.len(),
|
||||
environ_buf.as_ptr(),
|
||||
environ_buf.len(),
|
||||
);
|
||||
let args: Vec<&str> = argv.iter().map(AsRef::as_ref).collect();
|
||||
let mut wasi_ctx_builder = WasiCtxBuilder::new().args(&args).inherit_stdio();
|
||||
|
||||
let curfds: *mut fd_table = &mut *curfds;
|
||||
fd_table_init(curfds);
|
||||
|
||||
let prestats: *mut fd_prestats = &mut *prestats;
|
||||
fd_prestats_init(prestats);
|
||||
|
||||
// Prepopulate curfds with stdin, stdout, and stderr file descriptors.
|
||||
assert!(fd_table_insert_existing(curfds, 0, 0));
|
||||
assert!(fd_table_insert_existing(curfds, 1, 1));
|
||||
assert!(fd_table_insert_existing(curfds, 2, 2));
|
||||
|
||||
let mut wasm_fd = 3;
|
||||
for (dir, fd) in preopened_dirs {
|
||||
assert!(fd_table_insert_existing(curfds, wasm_fd, *fd));
|
||||
assert!(fd_prestats_insert(
|
||||
prestats,
|
||||
CString::new(dir.as_str()).unwrap().as_ptr(),
|
||||
wasm_fd,
|
||||
));
|
||||
wasm_fd += 1;
|
||||
}
|
||||
for (k, v) in environ {
|
||||
wasi_ctx_builder = wasi_ctx_builder.env(k, v);
|
||||
}
|
||||
|
||||
let host_state = WASIState {
|
||||
curfds,
|
||||
prestats,
|
||||
argv_environ,
|
||||
};
|
||||
for (dir, f) in preopened_dirs {
|
||||
wasi_ctx_builder = wasi_ctx_builder.preopened_dir(
|
||||
f.try_clone().map_err(|err| {
|
||||
InstantiationError::Resource(format!(
|
||||
"couldn't clone an instance handle to pre-opened dir: {}",
|
||||
err
|
||||
))
|
||||
})?,
|
||||
dir,
|
||||
);
|
||||
}
|
||||
|
||||
let wasi_ctx = wasi_ctx_builder.build().map_err(|err| {
|
||||
InstantiationError::Resource(format!("couldn't assemble WASI context object: {}", err))
|
||||
})?;
|
||||
|
||||
InstanceHandle::new(
|
||||
Rc::new(module),
|
||||
@@ -167,37 +132,6 @@ pub fn instantiate_wasi(
|
||||
&data_initializers,
|
||||
signatures.into_boxed_slice(),
|
||||
None,
|
||||
Box::new(host_state),
|
||||
Box::new(wasi_ctx),
|
||||
)
|
||||
}
|
||||
|
||||
fn allocate_argv_environ(
|
||||
argv: &[String],
|
||||
environ: &[(String, String)],
|
||||
) -> (Vec<usize>, Vec<libc::c_char>, Vec<usize>, Vec<libc::c_char>) {
|
||||
let mut argv_offsets = Vec::new();
|
||||
let mut argv_buf = Vec::new();
|
||||
let mut environ_offsets = Vec::new();
|
||||
let mut environ_buf = Vec::new();
|
||||
|
||||
for arg in argv {
|
||||
argv_offsets.push(argv_buf.len());
|
||||
for c in arg.bytes() {
|
||||
argv_buf.push(c as libc::c_char);
|
||||
}
|
||||
argv_buf.push('\0' as libc::c_char);
|
||||
}
|
||||
for (key, value) in environ {
|
||||
environ_offsets.push(environ_buf.len());
|
||||
for c in key.bytes() {
|
||||
environ_buf.push(c as libc::c_char);
|
||||
}
|
||||
environ_buf.push('=' as libc::c_char);
|
||||
for c in value.bytes() {
|
||||
environ_buf.push(c as libc::c_char);
|
||||
}
|
||||
environ_buf.push('\0' as libc::c_char);
|
||||
}
|
||||
|
||||
(argv_offsets, argv_buf, environ_offsets, environ_buf)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
extern crate cast;
|
||||
extern crate cranelift_codegen;
|
||||
extern crate cranelift_entity;
|
||||
extern crate cranelift_wasm;
|
||||
@@ -8,13 +7,9 @@ extern crate wasmtime_jit;
|
||||
extern crate wasmtime_runtime;
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
extern crate errno;
|
||||
extern crate wasi_common;
|
||||
|
||||
mod host;
|
||||
mod host_impls;
|
||||
mod instantiate;
|
||||
mod syscalls;
|
||||
mod translate;
|
||||
mod wasm32;
|
||||
|
||||
pub use instantiate::instantiate_wasi;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,573 +0,0 @@
|
||||
use cast;
|
||||
use cast::From as _0;
|
||||
use host;
|
||||
use std::mem::{align_of, size_of, zeroed};
|
||||
use std::slice;
|
||||
use wasm32;
|
||||
use wasmtime_runtime::{Export, VMContext};
|
||||
|
||||
/// Translate a wasm pointer into a native pointer.
|
||||
///
|
||||
/// This is unsafe due to trusting the contents of vmctx. The pointer result
|
||||
/// is bounds and alignment checked.
|
||||
unsafe fn decode_ptr(
|
||||
vmctx: &mut VMContext,
|
||||
ptr: wasm32::uintptr_t,
|
||||
len: usize,
|
||||
align: usize,
|
||||
) -> Result<*mut u8, host::__wasi_errno_t> {
|
||||
match vmctx.lookup_global_export("memory") {
|
||||
Some(Export::Memory {
|
||||
definition,
|
||||
vmctx: _,
|
||||
memory: _,
|
||||
}) => {
|
||||
if len > 0 {
|
||||
// Check for overflow within the access.
|
||||
let last = match (ptr as usize).checked_add(len - 1) {
|
||||
Some(sum) => sum,
|
||||
None => {
|
||||
println!("!!! overflow");
|
||||
return Err(host::__WASI_EFAULT as host::__wasi_errno_t);
|
||||
}
|
||||
};
|
||||
// Check for out of bounds.
|
||||
if last >= (*definition).current_length {
|
||||
println!("!!! out of bounds");
|
||||
return Err(host::__WASI_EFAULT as host::__wasi_errno_t);
|
||||
}
|
||||
}
|
||||
// Check alignment.
|
||||
if (ptr as usize) % align != 0 {
|
||||
println!("!!! bad alignment: {} % {}", ptr, align);
|
||||
return Err(host::__WASI_EINVAL as host::__wasi_errno_t);
|
||||
}
|
||||
// Ok, translate the address.
|
||||
Ok((((*definition).base as usize) + (ptr as usize)) as *mut u8)
|
||||
}
|
||||
// No export named "__wasi_memory", or the export isn't a memory.
|
||||
// FIXME: Is EINVAL the best code here?
|
||||
x => {
|
||||
println!(
|
||||
"!!! no export named __wasi_memory, or the export isn't a mem: {:?}",
|
||||
x
|
||||
);
|
||||
Err(host::__WASI_EINVAL as host::__wasi_errno_t)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn decode_ptr_to<T>(
|
||||
vmctx: &mut VMContext,
|
||||
ptr: wasm32::uintptr_t,
|
||||
) -> Result<*mut T, host::__wasi_errno_t> {
|
||||
decode_ptr(vmctx, ptr, size_of::<T>(), align_of::<T>()).map(|ptr| ptr as *mut T)
|
||||
}
|
||||
|
||||
unsafe fn decode_pointee<T>(
|
||||
vmctx: &mut VMContext,
|
||||
ptr: wasm32::uintptr_t,
|
||||
) -> Result<(), host::__wasi_errno_t> {
|
||||
// Check bounds and alignment.
|
||||
decode_ptr_to::<T>(vmctx, ptr)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub unsafe fn encode_pointee<T>(vmctx: &mut VMContext, ptr: wasm32::uintptr_t, t: T) {
|
||||
// Bounds and alignment are checked in `decode_pointee`.
|
||||
let ptr = decode_ptr_to::<T>(vmctx, ptr).unwrap();
|
||||
|
||||
ptr.write(t);
|
||||
}
|
||||
|
||||
pub unsafe fn decode_slice_of<T>(
|
||||
vmctx: &mut VMContext,
|
||||
ptr: wasm32::uintptr_t,
|
||||
len: wasm32::size_t,
|
||||
) -> Result<(*mut T, usize), host::__wasi_errno_t> {
|
||||
let len = cast::usize(len);
|
||||
|
||||
let ptr = decode_ptr(
|
||||
vmctx,
|
||||
ptr,
|
||||
size_of::<T>().checked_mul(len).unwrap(),
|
||||
align_of::<T>(),
|
||||
)? as *mut T;
|
||||
|
||||
Ok((ptr, len))
|
||||
}
|
||||
|
||||
pub fn encode_usize(len: usize) -> wasm32::size_t {
|
||||
cast::u32(len).unwrap()
|
||||
}
|
||||
|
||||
pub fn encode_device(device: host::__wasi_device_t) -> wasm32::__wasi_device_t {
|
||||
device
|
||||
}
|
||||
|
||||
pub fn encode_inode(inode: host::__wasi_inode_t) -> wasm32::__wasi_inode_t {
|
||||
inode
|
||||
}
|
||||
|
||||
pub fn encode_linkcount(linkcount: host::__wasi_linkcount_t) -> wasm32::__wasi_linkcount_t {
|
||||
linkcount
|
||||
}
|
||||
|
||||
pub fn decode_userdata(userdata: wasm32::__wasi_userdata_t) -> host::__wasi_userdata_t {
|
||||
userdata
|
||||
}
|
||||
|
||||
pub fn encode_userdata(userdata: host::__wasi_userdata_t) -> wasm32::__wasi_userdata_t {
|
||||
userdata
|
||||
}
|
||||
|
||||
pub fn decode_eventtype(eventtype: wasm32::__wasi_eventtype_t) -> host::__wasi_eventtype_t {
|
||||
eventtype
|
||||
}
|
||||
|
||||
pub fn encode_eventtype(eventtype: host::__wasi_eventtype_t) -> wasm32::__wasi_eventtype_t {
|
||||
eventtype
|
||||
}
|
||||
|
||||
pub fn decode_filesize(filesize: wasm32::__wasi_filesize_t) -> host::__wasi_filesize_t {
|
||||
filesize
|
||||
}
|
||||
|
||||
pub fn encode_filesize(filesize: host::__wasi_filesize_t) -> wasm32::__wasi_filesize_t {
|
||||
filesize
|
||||
}
|
||||
|
||||
pub fn encode_eventrwflags(
|
||||
eventrwflags: host::__wasi_eventrwflags_t,
|
||||
) -> wasm32::__wasi_eventrwflags_t {
|
||||
eventrwflags
|
||||
}
|
||||
|
||||
pub fn decode_subclockflags(
|
||||
subclockflags: wasm32::__wasi_subclockflags_t,
|
||||
) -> host::__wasi_subclockflags_t {
|
||||
subclockflags
|
||||
}
|
||||
|
||||
pub fn decode_fd(fd: wasm32::__wasi_fd_t) -> host::__wasi_fd_t {
|
||||
fd
|
||||
}
|
||||
|
||||
pub fn decode_filedelta(filedelta: wasm32::__wasi_filedelta_t) -> host::__wasi_filedelta_t {
|
||||
filedelta
|
||||
}
|
||||
|
||||
pub fn decode_whence(whence: wasm32::__wasi_whence_t) -> host::__wasi_whence_t {
|
||||
whence
|
||||
}
|
||||
|
||||
pub fn decode_clockid(clockid: wasm32::__wasi_clockid_t) -> host::__wasi_clockid_t {
|
||||
clockid
|
||||
}
|
||||
|
||||
pub fn decode_timestamp(timestamp: wasm32::__wasi_timestamp_t) -> host::__wasi_timestamp_t {
|
||||
timestamp
|
||||
}
|
||||
|
||||
pub fn encode_timestamp(timestamp: host::__wasi_timestamp_t) -> wasm32::__wasi_timestamp_t {
|
||||
timestamp
|
||||
}
|
||||
|
||||
pub fn decode_exitcode(exitcode: wasm32::__wasi_exitcode_t) -> host::__wasi_exitcode_t {
|
||||
exitcode
|
||||
}
|
||||
|
||||
pub fn decode_lookupflags(lookupflags: wasm32::__wasi_lookupflags_t) -> host::__wasi_lookupflags_t {
|
||||
lookupflags
|
||||
}
|
||||
|
||||
pub fn decode_oflags(oflags: wasm32::__wasi_oflags_t) -> host::__wasi_oflags_t {
|
||||
oflags
|
||||
}
|
||||
|
||||
pub fn decode_advice(advice: wasm32::__wasi_advice_t) -> host::__wasi_advice_t {
|
||||
advice
|
||||
}
|
||||
|
||||
pub fn decode_dircookie(dircookie: wasm32::__wasi_dircookie_t) -> host::__wasi_dircookie_t {
|
||||
dircookie
|
||||
}
|
||||
|
||||
pub fn encode_preopentype(preopentype: host::__wasi_preopentype_t) -> wasm32::__wasi_preopentype_t {
|
||||
preopentype
|
||||
}
|
||||
|
||||
pub fn encode_filetype(filetype: host::__wasi_filetype_t) -> wasm32::__wasi_filetype_t {
|
||||
filetype
|
||||
}
|
||||
|
||||
pub fn decode_fstflags(fstflags: wasm32::__wasi_fstflags_t) -> host::__wasi_fstflags_t {
|
||||
fstflags
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn encode_fstflags(fstflags: host::__wasi_fstflags_t) -> wasm32::__wasi_fstflags_t {
|
||||
fstflags
|
||||
}
|
||||
|
||||
pub fn decode_fdflags(fdflags: wasm32::__wasi_fdflags_t) -> host::__wasi_fdflags_t {
|
||||
fdflags
|
||||
}
|
||||
|
||||
pub fn encode_fdflags(fdflags: host::__wasi_fdflags_t) -> wasm32::__wasi_fdflags_t {
|
||||
fdflags
|
||||
}
|
||||
|
||||
pub fn decode_sdflags(sdflags: wasm32::__wasi_sdflags_t) -> host::__wasi_sdflags_t {
|
||||
sdflags
|
||||
}
|
||||
|
||||
pub fn decode_rights(rights: wasm32::__wasi_rights_t) -> host::__wasi_rights_t {
|
||||
rights
|
||||
}
|
||||
|
||||
pub fn encode_rights(rights: host::__wasi_rights_t) -> wasm32::__wasi_rights_t {
|
||||
rights
|
||||
}
|
||||
|
||||
pub fn decode_riflags(riflags: wasm32::__wasi_riflags_t) -> host::__wasi_riflags_t {
|
||||
riflags
|
||||
}
|
||||
|
||||
pub fn decode_siflags(siflags: wasm32::__wasi_siflags_t) -> host::__wasi_siflags_t {
|
||||
siflags
|
||||
}
|
||||
|
||||
pub unsafe fn decode_char_slice(
|
||||
vmctx: &mut VMContext,
|
||||
ptr: wasm32::uintptr_t,
|
||||
len: wasm32::size_t,
|
||||
) -> Result<(*mut host::char, usize), host::__wasi_errno_t> {
|
||||
decode_slice_of::<wasm32::char>(vmctx, ptr, len)
|
||||
}
|
||||
|
||||
pub unsafe fn decode_charstar_slice(
|
||||
vmctx: &mut VMContext,
|
||||
ptr: wasm32::uintptr_t,
|
||||
count: wasm32::size_t,
|
||||
) -> Result<(*mut wasm32::uintptr_t, usize), host::__wasi_errno_t> {
|
||||
decode_slice_of::<wasm32::uintptr_t>(vmctx, ptr, count)
|
||||
}
|
||||
|
||||
pub unsafe fn encode_charstar_slice(
|
||||
ptr: *mut wasm32::uintptr_t,
|
||||
host_vec: Vec<*mut libc::c_char>,
|
||||
guest_base: wasm32::uintptr_t,
|
||||
host_base: *mut libc::c_char,
|
||||
) {
|
||||
for (i, host) in host_vec.iter().enumerate() {
|
||||
let guest = if host.is_null() {
|
||||
0
|
||||
} else {
|
||||
guest_base + (*host as usize - host_base as usize) as wasm32::uintptr_t
|
||||
};
|
||||
ptr.add(i).write(guest);
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe fn decode_ciovec(
|
||||
vmctx: &mut VMContext,
|
||||
ciovec: &wasm32::__wasi_ciovec_t,
|
||||
) -> Result<host::__wasi_ciovec_t, host::__wasi_errno_t> {
|
||||
let len = cast::usize(ciovec.buf_len);
|
||||
Ok(host::__wasi_ciovec_t {
|
||||
buf: decode_ptr(vmctx, ciovec.buf, len, 1)? as *const host::void,
|
||||
buf_len: len,
|
||||
})
|
||||
}
|
||||
|
||||
pub unsafe fn decode_iovec(
|
||||
vmctx: &mut VMContext,
|
||||
iovec: &wasm32::__wasi_iovec_t,
|
||||
) -> Result<host::__wasi_iovec_t, host::__wasi_errno_t> {
|
||||
let len = cast::usize(iovec.buf_len);
|
||||
Ok(host::__wasi_iovec_t {
|
||||
buf: decode_ptr(vmctx, iovec.buf, len, 1)? as *mut host::void,
|
||||
buf_len: len,
|
||||
})
|
||||
}
|
||||
|
||||
pub unsafe fn decode_ciovec_slice(
|
||||
vmctx: &mut VMContext,
|
||||
ptr: wasm32::uintptr_t,
|
||||
len: wasm32::size_t,
|
||||
) -> Result<Vec<host::__wasi_ciovec_t>, host::__wasi_errno_t> {
|
||||
let slice = decode_slice_of::<wasm32::__wasi_ciovec_t>(vmctx, ptr, len)?;
|
||||
let slice = slice::from_raw_parts(slice.0, slice.1);
|
||||
slice.iter().map(|iov| decode_ciovec(vmctx, iov)).collect()
|
||||
}
|
||||
|
||||
pub unsafe fn decode_iovec_slice(
|
||||
vmctx: &mut VMContext,
|
||||
ptr: wasm32::uintptr_t,
|
||||
len: wasm32::size_t,
|
||||
) -> Result<Vec<host::__wasi_iovec_t>, host::__wasi_errno_t> {
|
||||
let slice = decode_slice_of::<wasm32::__wasi_iovec_t>(vmctx, ptr, len)?;
|
||||
let slice = slice::from_raw_parts(slice.0, slice.1);
|
||||
slice.iter().map(|iov| decode_iovec(vmctx, iov)).collect()
|
||||
}
|
||||
|
||||
pub fn decode_subscription(
|
||||
guest_subscription: wasm32::__wasi_subscription_t,
|
||||
) -> Result<host::__wasi_subscription_t, host::__wasi_errno_t> {
|
||||
let mut host_subscription = host::__wasi_subscription_t {
|
||||
userdata: decode_userdata(guest_subscription.userdata),
|
||||
type_: decode_eventtype(guest_subscription.type_),
|
||||
u: unsafe { zeroed() },
|
||||
};
|
||||
|
||||
match guest_subscription.type_ {
|
||||
wasm32::__WASI_EVENTTYPE_CLOCK => unsafe {
|
||||
host_subscription.u.clock =
|
||||
host::__wasi_subscription_t___wasi_subscription_u___wasi_subscription_u_clock_t {
|
||||
identifier: decode_userdata(guest_subscription.u.clock.identifier),
|
||||
clock_id: decode_clockid(guest_subscription.u.clock.clock_id),
|
||||
timeout: decode_timestamp(guest_subscription.u.clock.timeout),
|
||||
precision: decode_timestamp(guest_subscription.u.clock.precision),
|
||||
flags: decode_subclockflags(guest_subscription.u.clock.flags),
|
||||
};
|
||||
},
|
||||
wasm32::__WASI_EVENTTYPE_FD_READ | wasm32::__WASI_EVENTTYPE_FD_WRITE => unsafe {
|
||||
host_subscription
|
||||
.u
|
||||
.fd_readwrite =
|
||||
host::__wasi_subscription_t___wasi_subscription_u___wasi_subscription_u_fd_readwrite_t {
|
||||
fd: decode_fd(guest_subscription.u.fd_readwrite.fd),
|
||||
}
|
||||
},
|
||||
_ => return Err(host::__WASI_EINVAL as host::__wasi_errno_t),
|
||||
};
|
||||
|
||||
Ok(host_subscription)
|
||||
}
|
||||
|
||||
pub unsafe fn decode_subscription_slice(
|
||||
vmctx: &mut VMContext,
|
||||
ptr: wasm32::uintptr_t,
|
||||
len: wasm32::size_t,
|
||||
) -> Result<Vec<host::__wasi_subscription_t>, host::__wasi_errno_t> {
|
||||
let slice = decode_slice_of::<wasm32::__wasi_subscription_t>(vmctx, ptr, len)?;
|
||||
let slice = slice::from_raw_parts(slice.0, slice.1);
|
||||
slice
|
||||
.iter()
|
||||
.map(|subscription| decode_subscription(*subscription))
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn encode_event(host_event: host::__wasi_event_t) -> wasm32::__wasi_event_t {
|
||||
let mut guest_event = wasm32::__wasi_event_t {
|
||||
userdata: encode_userdata(host_event.userdata),
|
||||
error: encode_errno(host_event.error),
|
||||
type_: encode_eventtype(host_event.type_),
|
||||
u: unsafe { zeroed() },
|
||||
__bindgen_padding_0: 0,
|
||||
};
|
||||
|
||||
match u32::from(host_event.type_) {
|
||||
host::__WASI_EVENTTYPE_CLOCK => {}
|
||||
host::__WASI_EVENTTYPE_FD_READ | host::__WASI_EVENTTYPE_FD_WRITE => unsafe {
|
||||
guest_event.u.fd_readwrite =
|
||||
wasm32::__wasi_event_t___wasi_event_u___wasi_event_u_fd_readwrite_t {
|
||||
nbytes: encode_filesize(host_event.u.fd_readwrite.nbytes),
|
||||
flags: encode_eventrwflags(host_event.u.fd_readwrite.flags),
|
||||
__bindgen_padding_0: zeroed(),
|
||||
}
|
||||
},
|
||||
_ => panic!("unrecognized event type"),
|
||||
};
|
||||
|
||||
guest_event
|
||||
}
|
||||
|
||||
pub unsafe fn decode_event_slice(
|
||||
vmctx: &mut VMContext,
|
||||
ptr: wasm32::uintptr_t,
|
||||
len: wasm32::size_t,
|
||||
) -> Result<(*mut wasm32::__wasi_event_t, usize), host::__wasi_errno_t> {
|
||||
decode_slice_of::<wasm32::__wasi_event_t>(vmctx, ptr, len)
|
||||
}
|
||||
|
||||
pub unsafe fn encode_event_slice(
|
||||
ptr: *mut wasm32::__wasi_event_t,
|
||||
host_vec: Vec<host::__wasi_event_t>,
|
||||
) {
|
||||
for (i, host) in host_vec.iter().enumerate() {
|
||||
let guest = encode_event(*host);
|
||||
|
||||
ptr.add(i * size_of::<wasm32::__wasi_event_t>())
|
||||
.write(guest);
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe fn decode_fd_byref(
|
||||
vmctx: &mut VMContext,
|
||||
fd_ptr: wasm32::uintptr_t,
|
||||
) -> Result<(), host::__wasi_errno_t> {
|
||||
decode_pointee::<wasm32::__wasi_fd_t>(vmctx, fd_ptr)
|
||||
}
|
||||
|
||||
pub unsafe fn encode_fd_byref(
|
||||
vmctx: &mut VMContext,
|
||||
fd_ptr: wasm32::uintptr_t,
|
||||
fd: host::__wasi_fd_t,
|
||||
) {
|
||||
encode_pointee::<wasm32::__wasi_fd_t>(vmctx, fd_ptr, wasm32::size_t::cast(fd))
|
||||
}
|
||||
|
||||
pub unsafe fn decode_timestamp_byref(
|
||||
vmctx: &mut VMContext,
|
||||
timestamp_ptr: wasm32::uintptr_t,
|
||||
) -> Result<(), host::__wasi_errno_t> {
|
||||
decode_pointee::<wasm32::__wasi_timestamp_t>(vmctx, timestamp_ptr)
|
||||
}
|
||||
|
||||
pub unsafe fn encode_timestamp_byref(
|
||||
vmctx: &mut VMContext,
|
||||
timestamp_ptr: wasm32::uintptr_t,
|
||||
host_timestamp: host::__wasi_timestamp_t,
|
||||
) {
|
||||
encode_pointee::<wasm32::__wasi_timestamp_t>(
|
||||
vmctx,
|
||||
timestamp_ptr,
|
||||
wasm32::__wasi_timestamp_t::cast(host_timestamp),
|
||||
)
|
||||
}
|
||||
|
||||
pub unsafe fn decode_filesize_byref(
|
||||
vmctx: &mut VMContext,
|
||||
filesize_ptr: wasm32::uintptr_t,
|
||||
) -> Result<(), host::__wasi_errno_t> {
|
||||
decode_pointee::<wasm32::__wasi_filesize_t>(vmctx, filesize_ptr)
|
||||
}
|
||||
|
||||
pub unsafe fn encode_filesize_byref(
|
||||
vmctx: &mut VMContext,
|
||||
filesize_ptr: wasm32::uintptr_t,
|
||||
host_filesize: host::__wasi_filesize_t,
|
||||
) {
|
||||
encode_pointee::<wasm32::__wasi_filesize_t>(
|
||||
vmctx,
|
||||
filesize_ptr,
|
||||
wasm32::__wasi_filesize_t::cast(host_filesize),
|
||||
)
|
||||
}
|
||||
|
||||
pub unsafe fn decode_roflags_byref(
|
||||
vmctx: &mut VMContext,
|
||||
roflags_ptr: wasm32::uintptr_t,
|
||||
) -> Result<(), host::__wasi_errno_t> {
|
||||
decode_pointee::<wasm32::__wasi_roflags_t>(vmctx, roflags_ptr)
|
||||
}
|
||||
|
||||
pub unsafe fn encode_roflags_byref(
|
||||
vmctx: &mut VMContext,
|
||||
roflags_ptr: wasm32::uintptr_t,
|
||||
host_roflags: host::__wasi_roflags_t,
|
||||
) {
|
||||
encode_pointee::<wasm32::__wasi_roflags_t>(
|
||||
vmctx,
|
||||
roflags_ptr,
|
||||
wasm32::__wasi_roflags_t::cast(host_roflags),
|
||||
)
|
||||
}
|
||||
|
||||
pub unsafe fn decode_usize_byref(
|
||||
vmctx: &mut VMContext,
|
||||
usize_ptr: wasm32::uintptr_t,
|
||||
) -> Result<(), host::__wasi_errno_t> {
|
||||
decode_pointee::<wasm32::size_t>(vmctx, usize_ptr)
|
||||
}
|
||||
|
||||
pub unsafe fn encode_usize_byref(
|
||||
vmctx: &mut VMContext,
|
||||
usize_ptr: wasm32::uintptr_t,
|
||||
host_usize: usize,
|
||||
) {
|
||||
encode_pointee::<wasm32::size_t>(vmctx, usize_ptr, wasm32::size_t::cast(host_usize).unwrap())
|
||||
}
|
||||
|
||||
pub unsafe fn decode_prestat_byref(
|
||||
vmctx: &mut VMContext,
|
||||
prestat_ptr: wasm32::uintptr_t,
|
||||
) -> Result<(), host::__wasi_errno_t> {
|
||||
decode_pointee::<wasm32::__wasi_prestat_t>(vmctx, prestat_ptr)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub unsafe fn encode_prestat_byref(
|
||||
vmctx: &mut VMContext,
|
||||
prestat_ptr: wasm32::uintptr_t,
|
||||
host_prestat: host::__wasi_prestat_t,
|
||||
) {
|
||||
let wasm32_prestat = wasm32::__wasi_prestat_t {
|
||||
pr_type: encode_preopentype(host_prestat.pr_type),
|
||||
u: wasm32::__wasi_prestat_t___wasi_prestat_u {
|
||||
dir: wasm32::__wasi_prestat_t___wasi_prestat_u___wasi_prestat_u_dir_t {
|
||||
pr_name_len: encode_usize(host_prestat.u.dir.pr_name_len),
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
encode_pointee::<wasm32::__wasi_prestat_t>(vmctx, prestat_ptr, wasm32_prestat)
|
||||
}
|
||||
|
||||
pub unsafe fn decode_fdstat_byref(
|
||||
vmctx: &mut VMContext,
|
||||
fdstat_ptr: wasm32::uintptr_t,
|
||||
) -> Result<(), host::__wasi_errno_t> {
|
||||
decode_pointee::<wasm32::__wasi_fdstat_t>(vmctx, fdstat_ptr)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub unsafe fn encode_fdstat_byref(
|
||||
vmctx: &mut VMContext,
|
||||
fdstat_ptr: wasm32::uintptr_t,
|
||||
host_fdstat: host::__wasi_fdstat_t,
|
||||
) {
|
||||
let wasm32_fdstat = wasm32::__wasi_fdstat_t {
|
||||
fs_filetype: encode_filetype(host_fdstat.fs_filetype),
|
||||
fs_flags: encode_fdflags(host_fdstat.fs_flags),
|
||||
__bindgen_padding_0: 0,
|
||||
fs_rights_base: encode_rights(host_fdstat.fs_rights_base),
|
||||
fs_rights_inheriting: encode_rights(host_fdstat.fs_rights_inheriting),
|
||||
};
|
||||
|
||||
encode_pointee::<wasm32::__wasi_fdstat_t>(vmctx, fdstat_ptr, wasm32_fdstat)
|
||||
}
|
||||
|
||||
pub unsafe fn decode_filestat_byref(
|
||||
vmctx: &mut VMContext,
|
||||
filestat_ptr: wasm32::uintptr_t,
|
||||
) -> Result<(), host::__wasi_errno_t> {
|
||||
decode_pointee::<wasm32::__wasi_filestat_t>(vmctx, filestat_ptr)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub unsafe fn encode_filestat_byref(
|
||||
vmctx: &mut VMContext,
|
||||
filestat_ptr: wasm32::uintptr_t,
|
||||
host_filestat: host::__wasi_filestat_t,
|
||||
) {
|
||||
let wasm32_filestat = wasm32::__wasi_filestat_t {
|
||||
st_dev: encode_device(host_filestat.st_dev),
|
||||
st_ino: encode_inode(host_filestat.st_ino),
|
||||
st_filetype: encode_filetype(host_filestat.st_filetype),
|
||||
st_nlink: encode_linkcount(host_filestat.st_nlink),
|
||||
st_size: encode_filesize(host_filestat.st_size),
|
||||
st_atim: encode_timestamp(host_filestat.st_atim),
|
||||
st_mtim: encode_timestamp(host_filestat.st_mtim),
|
||||
st_ctim: encode_timestamp(host_filestat.st_ctim),
|
||||
};
|
||||
|
||||
encode_pointee::<wasm32::__wasi_filestat_t>(vmctx, filestat_ptr, wasm32_filestat)
|
||||
}
|
||||
|
||||
pub fn encode_errno(e: host::__wasi_errno_t) -> wasm32::__wasi_errno_t {
|
||||
assert!(e <= wasm32::__WASI_ENOTCAPABLE);
|
||||
e
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user