Migrate to wasi-common crate

This commit is contained in:
Jakub Konka
2019-05-04 14:23:47 +02:00
committed by Dan Gohman
parent 3dfeab50ad
commit e8142f076d
30 changed files with 477 additions and 7744 deletions

View File

@@ -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;

View File

@@ -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
}

View File

@@ -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)
}

View File

@@ -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

View File

@@ -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