From 3129b550e5ab0e9939dbef62c3caa0d19fb0accb Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Tue, 8 Jun 2021 15:13:26 +0200 Subject: [PATCH 1/5] feat(wasi-types) Extract types from `wasi` to a new `wasi-types` crate. Because we are very likely to re-use those types in other crates (it already happens in private repos already), we want to extract the WASI types from the `wasi` crate. This patch extracts the `wasi/src/syscalls/types.rs` module into its own `wasi-types` crate. This new crate takes this opportunity to classify the numerous types in submodules. All exported public types are flatten. What's missing is the documentation, let's address in another round of PR. --- Cargo.lock | 13 +- Cargo.toml | 1 + lib/wasi-types/Cargo.toml | 17 + lib/wasi-types/README.md | 3 + lib/wasi-types/src/advice.rs | 7 + lib/wasi-types/src/directory.rs | 41 ++ lib/wasi-types/src/error.rs | 78 +++ lib/wasi-types/src/event.rs | 82 +++ lib/wasi-types/src/file.rs | 295 +++++++++ lib/wasi-types/src/io.rs | 20 + lib/wasi-types/src/lib.rs | 37 ++ lib/{wasi => wasi-types}/src/ptr.rs | 2 +- lib/wasi-types/src/signal.rs | 31 + lib/wasi-types/src/subscription.rs | 143 ++++ lib/wasi-types/src/time.rs | 7 + lib/wasi-types/src/versions/mod.rs | 1 + lib/wasi-types/src/versions/snapshot0.rs | 101 +++ lib/wasi/Cargo.toml | 3 +- lib/wasi/src/lib.rs | 4 +- lib/wasi/src/syscalls/mod.rs | 5 +- lib/wasi/src/syscalls/types.rs | 804 ----------------------- scripts/publish.py | 4 +- 22 files changed, 887 insertions(+), 812 deletions(-) create mode 100644 lib/wasi-types/Cargo.toml create mode 100644 lib/wasi-types/README.md create mode 100644 lib/wasi-types/src/advice.rs create mode 100644 lib/wasi-types/src/directory.rs create mode 100644 lib/wasi-types/src/error.rs create mode 100644 lib/wasi-types/src/event.rs create mode 100644 lib/wasi-types/src/file.rs create mode 100644 lib/wasi-types/src/io.rs create mode 100644 lib/wasi-types/src/lib.rs rename lib/{wasi => wasi-types}/src/ptr.rs (97%) create mode 100644 lib/wasi-types/src/signal.rs create mode 100644 lib/wasi-types/src/subscription.rs create mode 100644 lib/wasi-types/src/time.rs create mode 100644 lib/wasi-types/src/versions/mod.rs create mode 100644 lib/wasi-types/src/versions/snapshot0.rs delete mode 100644 lib/wasi/src/syscalls/types.rs diff --git a/Cargo.lock b/Cargo.lock index 44f118854f9..d61f55c6ebc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2729,16 +2729,15 @@ name = "wasmer-wasi" version = "2.0.0-rc2" dependencies = [ "bincode", - "byteorder", "generational-arena", "getrandom", "libc", "serde", "thiserror", - "time", "tracing", "typetag", "wasmer", + "wasmer-wasi-types", "winapi", ] @@ -2754,6 +2753,16 @@ dependencies = [ "wasmer-wasi", ] +[[package]] +name = "wasmer-wasi-types" +version = "2.0.0-rc2" +dependencies = [ + "byteorder", + "serde", + "time", + "wasmer", +] + [[package]] name = "wasmer-wast" version = "2.0.0-rc2" diff --git a/Cargo.toml b/Cargo.toml index 2cc1cf11833..08fe2402302 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -46,6 +46,7 @@ members = [ "lib/object", "lib/vm", "lib/wasi", + "lib/wasi-types", "lib/wasi-experimental-io-devices", "lib/types", "tests/lib/wast", diff --git a/lib/wasi-types/Cargo.toml b/lib/wasi-types/Cargo.toml new file mode 100644 index 00000000000..67974c60c18 --- /dev/null +++ b/lib/wasi-types/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "wasmer-wasi-types" +version = "2.0.0-rc2" +description = "WASI types for Wasmer WebAssembly runtime" +categories = ["wasm", "os"] +keywords = ["wasm", "webassembly", "wasi", "sandbox", "ABI"] +authors = ["Wasmer Engineering Team "] +repository = "https://github.com/wasmerio/wasmer" +license = "MIT" +readme = "README.md" +edition = "2018" + +[dependencies] +wasmer = { path = "../api", version = "2.0.0-rc2" } +serde = { version = "1.0", features = ["derive"] } +byteorder = "1.3" +time = "0.1" \ No newline at end of file diff --git a/lib/wasi-types/README.md b/lib/wasi-types/README.md new file mode 100644 index 00000000000..96010bacf45 --- /dev/null +++ b/lib/wasi-types/README.md @@ -0,0 +1,3 @@ +# `wasmer-wasi-types` [![Build Status](https://github.com/wasmerio/wasmer/workflows/build/badge.svg?style=flat-square)](https://github.com/wasmerio/wasmer/actions?query=workflow%3Abuild) [![Join Wasmer Slack](https://img.shields.io/static/v1?label=Slack&message=join%20chat&color=brighgreen&style=flat-square)](https://slack.wasmer.io) [![MIT License](https://img.shields.io/github/license/wasmerio/wasmer.svg?style=flat-square)](https://github.com/wasmerio/wasmer/blob/master/LICENSE) [![crates.io](https://img.shields.io/crates/v/wasmer-wasi-types.svg)](https://crates.io/crates/wasmer-wasi-types) + +This crate contains the WASI types necessary for `wasmer-wasi`. Please check this crate to learn more! diff --git a/lib/wasi-types/src/advice.rs b/lib/wasi-types/src/advice.rs new file mode 100644 index 00000000000..55cf4aebcd2 --- /dev/null +++ b/lib/wasi-types/src/advice.rs @@ -0,0 +1,7 @@ +pub type __wasi_advice_t = u8; +pub const __WASI_ADVICE_NORMAL: u8 = 0; +pub const __WASI_ADVICE_SEQUENTIAL: u8 = 1; +pub const __WASI_ADVICE_RANDOM: u8 = 2; +pub const __WASI_ADVICE_WILLNEED: u8 = 3; +pub const __WASI_ADVICE_DONTNEED: u8 = 4; +pub const __WASI_ADVICE_NOREUSE: u8 = 5; diff --git a/lib/wasi-types/src/directory.rs b/lib/wasi-types/src/directory.rs new file mode 100644 index 00000000000..95aa2c043a9 --- /dev/null +++ b/lib/wasi-types/src/directory.rs @@ -0,0 +1,41 @@ +use crate::*; +use std::mem; +use wasmer::ValueType; + +pub type __wasi_dircookie_t = u64; +pub const __WASI_DIRCOOKIE_START: u64 = 0; + +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +#[repr(C)] +pub struct __wasi_dirent_t { + pub d_next: __wasi_dircookie_t, + pub d_ino: __wasi_inode_t, + pub d_namlen: u32, + pub d_type: __wasi_filetype_t, +} + +unsafe impl ValueType for __wasi_dirent_t {} + +pub fn dirent_to_le_bytes(ent: &__wasi_dirent_t) -> Vec { + use mem::transmute; + + let mut out = Vec::with_capacity(mem::size_of::<__wasi_dirent_t>()); + let bytes: [u8; 8] = unsafe { transmute(ent.d_next.to_le()) }; + for &b in &bytes { + out.push(b); + } + let bytes: [u8; 8] = unsafe { transmute(ent.d_ino.to_le()) }; + for &b in &bytes { + out.push(b); + } + let bytes: [u8; 4] = unsafe { transmute(ent.d_namlen.to_le()) }; + for &b in &bytes { + out.push(b); + } + out.push(ent.d_type); + out.push(0); + out.push(0); + out.push(0); + assert_eq!(out.len(), mem::size_of::<__wasi_dirent_t>()); + out +} diff --git a/lib/wasi-types/src/error.rs b/lib/wasi-types/src/error.rs new file mode 100644 index 00000000000..87d01bb0fac --- /dev/null +++ b/lib/wasi-types/src/error.rs @@ -0,0 +1,78 @@ +pub type __wasi_errno_t = u16; +pub const __WASI_ESUCCESS: u16 = 0; +pub const __WASI_E2BIG: u16 = 1; +pub const __WASI_EACCES: u16 = 2; +pub const __WASI_EADDRINUSE: u16 = 3; +pub const __WASI_EADDRNOTAVAIL: u16 = 4; +pub const __WASI_EAFNOSUPPORT: u16 = 5; +pub const __WASI_EAGAIN: u16 = 6; +pub const __WASI_EALREADY: u16 = 7; +pub const __WASI_EBADF: u16 = 8; +pub const __WASI_EBADMSG: u16 = 9; +pub const __WASI_EBUSY: u16 = 10; +pub const __WASI_ECANCELED: u16 = 11; +pub const __WASI_ECHILD: u16 = 12; +pub const __WASI_ECONNABORTED: u16 = 13; +pub const __WASI_ECONNREFUSED: u16 = 14; +pub const __WASI_ECONNRESET: u16 = 15; +pub const __WASI_EDEADLK: u16 = 16; +pub const __WASI_EDESTADDRREQ: u16 = 17; +pub const __WASI_EDOM: u16 = 18; +pub const __WASI_EDQUOT: u16 = 19; +pub const __WASI_EEXIST: u16 = 20; +pub const __WASI_EFAULT: u16 = 21; +pub const __WASI_EFBIG: u16 = 22; +pub const __WASI_EHOSTUNREACH: u16 = 23; +pub const __WASI_EIDRM: u16 = 24; +pub const __WASI_EILSEQ: u16 = 25; +pub const __WASI_EINPROGRESS: u16 = 26; +pub const __WASI_EINTR: u16 = 27; +pub const __WASI_EINVAL: u16 = 28; +pub const __WASI_EIO: u16 = 29; +pub const __WASI_EISCONN: u16 = 30; +pub const __WASI_EISDIR: u16 = 31; +pub const __WASI_ELOOP: u16 = 32; +pub const __WASI_EMFILE: u16 = 33; +pub const __WASI_EMLINK: u16 = 34; +pub const __WASI_EMSGSIZE: u16 = 35; +pub const __WASI_EMULTIHOP: u16 = 36; +pub const __WASI_ENAMETOOLONG: u16 = 37; +pub const __WASI_ENETDOWN: u16 = 38; +pub const __WASI_ENETRESET: u16 = 39; +pub const __WASI_ENETUNREACH: u16 = 40; +pub const __WASI_ENFILE: u16 = 41; +pub const __WASI_ENOBUFS: u16 = 42; +pub const __WASI_ENODEV: u16 = 43; +pub const __WASI_ENOENT: u16 = 44; +pub const __WASI_ENOEXEC: u16 = 45; +pub const __WASI_ENOLCK: u16 = 46; +pub const __WASI_ENOLINK: u16 = 47; +pub const __WASI_ENOMEM: u16 = 48; +pub const __WASI_ENOMSG: u16 = 49; +pub const __WASI_ENOPROTOOPT: u16 = 50; +pub const __WASI_ENOSPC: u16 = 51; +pub const __WASI_ENOSYS: u16 = 52; +pub const __WASI_ENOTCONN: u16 = 53; +pub const __WASI_ENOTDIR: u16 = 54; +pub const __WASI_ENOTEMPTY: u16 = 55; +pub const __WASI_ENOTRECOVERABLE: u16 = 56; +pub const __WASI_ENOTSOCK: u16 = 57; +pub const __WASI_ENOTSUP: u16 = 58; +pub const __WASI_ENOTTY: u16 = 59; +pub const __WASI_ENXIO: u16 = 60; +pub const __WASI_EOVERFLOW: u16 = 61; +pub const __WASI_EOWNERDEAD: u16 = 62; +pub const __WASI_EPERM: u16 = 63; +pub const __WASI_EPIPE: u16 = 64; +pub const __WASI_EPROTO: u16 = 65; +pub const __WASI_EPROTONOSUPPORT: u16 = 66; +pub const __WASI_EPROTOTYPE: u16 = 67; +pub const __WASI_ERANGE: u16 = 68; +pub const __WASI_EROFS: u16 = 69; +pub const __WASI_ESPIPE: u16 = 70; +pub const __WASI_ESRCH: u16 = 71; +pub const __WASI_ESTALE: u16 = 72; +pub const __WASI_ETIMEDOUT: u16 = 73; +pub const __WASI_ETXTBSY: u16 = 74; +pub const __WASI_EXDEV: u16 = 75; +pub const __WASI_ENOTCAPABLE: u16 = 76; diff --git a/lib/wasi-types/src/event.rs b/lib/wasi-types/src/event.rs new file mode 100644 index 00000000000..ad70ce0f0b6 --- /dev/null +++ b/lib/wasi-types/src/event.rs @@ -0,0 +1,82 @@ +use crate::*; +use std::fmt; + +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +#[repr(C)] +pub struct __wasi_event_fd_readwrite_t { + pub nbytes: __wasi_filesize_t, + pub flags: __wasi_eventrwflags_t, +} + +#[derive(Copy, Clone)] +#[repr(C)] +pub union __wasi_event_u { + pub fd_readwrite: __wasi_event_fd_readwrite_t, +} + +// TODO: remove this implementation of Debug when `__wasi_event_u` gets more than 1 variant +impl fmt::Debug for __wasi_event_u { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("__wasi_event_u") + .field("fd_readwrite", unsafe { &self.fd_readwrite }) + .finish() + } +} + +#[derive(Debug, Copy, Clone)] +pub enum EventEnum { + FdReadWrite { + nbytes: __wasi_filesize_t, + flags: __wasi_eventrwflags_t, + }, +} + +impl EventEnum { + pub fn untagged(self) -> __wasi_event_u { + match self { + EventEnum::FdReadWrite { nbytes, flags } => __wasi_event_u { + fd_readwrite: __wasi_event_fd_readwrite_t { nbytes, flags }, + }, + } + } +} + +#[derive(Debug, Copy, Clone)] +#[repr(C)] +pub struct __wasi_event_t { + pub userdata: __wasi_userdata_t, + pub error: __wasi_errno_t, + pub type_: __wasi_eventtype_t, + pub u: __wasi_event_u, +} + +impl __wasi_event_t { + pub fn tagged(&self) -> Option { + match self.type_ { + __WASI_EVENTTYPE_FD_READ | __WASI_EVENTTYPE_FD_WRITE => Some(EventEnum::FdReadWrite { + nbytes: unsafe { self.u.fd_readwrite.nbytes }, + flags: unsafe { self.u.fd_readwrite.flags }, + }), + _ => None, + } + } +} + +unsafe impl ValueType for __wasi_event_t {} + +pub type __wasi_eventrwflags_t = u16; +pub const __WASI_EVENT_FD_READWRITE_HANGUP: u16 = 1 << 0; + +pub type __wasi_eventtype_t = u8; +pub const __WASI_EVENTTYPE_CLOCK: u8 = 0; +pub const __WASI_EVENTTYPE_FD_READ: u8 = 1; +pub const __WASI_EVENTTYPE_FD_WRITE: u8 = 2; + +pub fn eventtype_to_str(event_type: __wasi_eventtype_t) -> &'static str { + match event_type { + __WASI_EVENTTYPE_CLOCK => "__WASI_EVENTTYPE_CLOCK", + __WASI_EVENTTYPE_FD_READ => "__WASI_EVENTTYPE_FD_READ", + __WASI_EVENTTYPE_FD_WRITE => "__WASI_EVENTTYPE_FD_WRITE", + _ => "INVALID EVENTTYPE", + } +} diff --git a/lib/wasi-types/src/file.rs b/lib/wasi-types/src/file.rs new file mode 100644 index 00000000000..0a409ba546b --- /dev/null +++ b/lib/wasi-types/src/file.rs @@ -0,0 +1,295 @@ +use crate::*; +use serde::{Deserialize, Serialize}; +use std::fmt; +use wasmer::ValueType; + +pub type __wasi_device_t = u64; + +pub type __wasi_fd_t = u32; +pub const __WASI_STDIN_FILENO: u32 = 0; +pub const __WASI_STDOUT_FILENO: u32 = 1; +pub const __WASI_STDERR_FILENO: u32 = 2; + +pub type __wasi_fdflags_t = u16; +pub const __WASI_FDFLAG_APPEND: u16 = 1 << 0; +pub const __WASI_FDFLAG_DSYNC: u16 = 1 << 1; +pub const __WASI_FDFLAG_NONBLOCK: u16 = 1 << 2; +pub const __WASI_FDFLAG_RSYNC: u16 = 1 << 3; +pub const __WASI_FDFLAG_SYNC: u16 = 1 << 4; + +pub type __wasi_preopentype_t = u8; +pub const __WASI_PREOPENTYPE_DIR: u8 = 0; + +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +#[repr(C)] +pub struct __wasi_prestat_u_dir_t { + pub pr_name_len: u32, +} + +unsafe impl ValueType for __wasi_prestat_u_dir_t {} + +#[derive(Copy, Clone)] +#[repr(C)] +pub union __wasi_prestat_u { + dir: __wasi_prestat_u_dir_t, +} + +impl fmt::Debug for __wasi_prestat_u { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "__wasi_prestat_u") + } +} + +unsafe impl ValueType for __wasi_prestat_u {} + +#[derive(Debug, Copy, Clone)] +#[repr(C)] +pub struct __wasi_prestat_t { + pub pr_type: __wasi_preopentype_t, + pub u: __wasi_prestat_u, +} + +#[derive(Copy, Clone)] +pub enum PrestatEnum { + Dir { pr_name_len: u32 }, +} + +impl PrestatEnum { + pub fn untagged(self) -> __wasi_prestat_u { + match self { + PrestatEnum::Dir { pr_name_len } => __wasi_prestat_u { + dir: __wasi_prestat_u_dir_t { pr_name_len }, + }, + } + } +} + +impl __wasi_prestat_t { + #[allow(clippy::trivially_copy_pass_by_ref)] + pub fn tagged(&self) -> Option { + match self.pr_type { + __WASI_PREOPENTYPE_DIR => Some(PrestatEnum::Dir { + pr_name_len: unsafe { self.u.dir.pr_name_len }, + }), + _ => None, + } + } +} + +unsafe impl ValueType for __wasi_prestat_t {} + +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +#[repr(C)] +pub struct __wasi_fdstat_t { + pub fs_filetype: __wasi_filetype_t, + pub fs_flags: __wasi_fdflags_t, + pub fs_rights_base: __wasi_rights_t, + pub fs_rights_inheriting: __wasi_rights_t, +} + +unsafe impl ValueType for __wasi_fdstat_t {} + +pub type __wasi_filedelta_t = i64; + +pub type __wasi_filesize_t = u64; + +#[derive(Copy, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[repr(C)] +pub struct __wasi_filestat_t { + pub st_dev: __wasi_device_t, + pub st_ino: __wasi_inode_t, + pub st_filetype: __wasi_filetype_t, + pub st_nlink: __wasi_linkcount_t, + pub st_size: __wasi_filesize_t, + pub st_atim: __wasi_timestamp_t, + pub st_mtim: __wasi_timestamp_t, + pub st_ctim: __wasi_timestamp_t, +} + +impl Default for __wasi_filestat_t { + fn default() -> Self { + __wasi_filestat_t { + st_dev: Default::default(), + st_ino: Default::default(), + st_filetype: __WASI_FILETYPE_UNKNOWN, + st_nlink: 1, + st_size: Default::default(), + st_atim: Default::default(), + st_mtim: Default::default(), + st_ctim: Default::default(), + } + } +} + +impl fmt::Debug for __wasi_filestat_t { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let convert_ts_into_time_string = |ts| { + let tspec = + ::time::Timespec::new(ts as i64 / 1_000_000_000, (ts % 1_000_000_000) as i32); + let tm = ::time::at(tspec); + let out_time = tm.rfc822(); + format!("{} ({})", out_time, ts) + }; + f.debug_struct("__wasi_filestat_t") + .field("st_dev", &self.st_dev) + .field("st_ino", &self.st_ino) + .field( + "st_filetype", + &format!( + "{} ({})", + wasi_filetype_to_name(self.st_filetype), + self.st_filetype, + ), + ) + .field("st_nlink", &self.st_nlink) + .field("st_size", &self.st_size) + .field("st_atim", &convert_ts_into_time_string(self.st_atim)) + .field("st_mtim", &convert_ts_into_time_string(self.st_mtim)) + .field("st_ctim", &convert_ts_into_time_string(self.st_ctim)) + .finish() + } +} + +unsafe impl ValueType for __wasi_filestat_t {} + +pub fn wasi_filetype_to_name(ft: __wasi_filetype_t) -> &'static str { + match ft { + __WASI_FILETYPE_UNKNOWN => "Unknown", + __WASI_FILETYPE_BLOCK_DEVICE => "Block device", + __WASI_FILETYPE_CHARACTER_DEVICE => "Character device", + __WASI_FILETYPE_DIRECTORY => "Directory", + __WASI_FILETYPE_REGULAR_FILE => "Regular file", + __WASI_FILETYPE_SOCKET_DGRAM => "Socket dgram", + __WASI_FILETYPE_SOCKET_STREAM => "Socket stream", + __WASI_FILETYPE_SYMBOLIC_LINK => "Symbolic link", + _ => "Invalid", + } +} + +pub type __wasi_filetype_t = u8; +pub const __WASI_FILETYPE_UNKNOWN: u8 = 0; +pub const __WASI_FILETYPE_BLOCK_DEVICE: u8 = 1; +pub const __WASI_FILETYPE_CHARACTER_DEVICE: u8 = 2; +pub const __WASI_FILETYPE_DIRECTORY: u8 = 3; +pub const __WASI_FILETYPE_REGULAR_FILE: u8 = 4; +pub const __WASI_FILETYPE_SOCKET_DGRAM: u8 = 5; +pub const __WASI_FILETYPE_SOCKET_STREAM: u8 = 6; +pub const __WASI_FILETYPE_SYMBOLIC_LINK: u8 = 7; + +pub type __wasi_fstflags_t = u16; +pub const __WASI_FILESTAT_SET_ATIM: u16 = 1 << 0; +pub const __WASI_FILESTAT_SET_ATIM_NOW: u16 = 1 << 1; +pub const __WASI_FILESTAT_SET_MTIM: u16 = 1 << 2; +pub const __WASI_FILESTAT_SET_MTIM_NOW: u16 = 1 << 3; + +pub type __wasi_inode_t = u64; + +pub type __wasi_linkcount_t = u64; + +pub type __wasi_lookupflags_t = u32; +pub const __WASI_LOOKUP_SYMLINK_FOLLOW: u32 = 1 << 0; + +pub type __wasi_oflags_t = u16; +pub const __WASI_O_CREAT: u16 = 1 << 0; +pub const __WASI_O_DIRECTORY: u16 = 1 << 1; +pub const __WASI_O_EXCL: u16 = 1 << 2; +pub const __WASI_O_TRUNC: u16 = 1 << 3; + +pub type __wasi_rights_t = u64; +pub const __WASI_RIGHT_FD_DATASYNC: u64 = 1 << 0; +pub const __WASI_RIGHT_FD_READ: u64 = 1 << 1; +pub const __WASI_RIGHT_FD_SEEK: u64 = 1 << 2; +pub const __WASI_RIGHT_FD_FDSTAT_SET_FLAGS: u64 = 1 << 3; +pub const __WASI_RIGHT_FD_SYNC: u64 = 1 << 4; +pub const __WASI_RIGHT_FD_TELL: u64 = 1 << 5; +pub const __WASI_RIGHT_FD_WRITE: u64 = 1 << 6; +pub const __WASI_RIGHT_FD_ADVISE: u64 = 1 << 7; +pub const __WASI_RIGHT_FD_ALLOCATE: u64 = 1 << 8; +pub const __WASI_RIGHT_PATH_CREATE_DIRECTORY: u64 = 1 << 9; +pub const __WASI_RIGHT_PATH_CREATE_FILE: u64 = 1 << 10; +pub const __WASI_RIGHT_PATH_LINK_SOURCE: u64 = 1 << 11; +pub const __WASI_RIGHT_PATH_LINK_TARGET: u64 = 1 << 12; +pub const __WASI_RIGHT_PATH_OPEN: u64 = 1 << 13; +pub const __WASI_RIGHT_FD_READDIR: u64 = 1 << 14; +pub const __WASI_RIGHT_PATH_READLINK: u64 = 1 << 15; +pub const __WASI_RIGHT_PATH_RENAME_SOURCE: u64 = 1 << 16; +pub const __WASI_RIGHT_PATH_RENAME_TARGET: u64 = 1 << 17; +pub const __WASI_RIGHT_PATH_FILESTAT_GET: u64 = 1 << 18; +pub const __WASI_RIGHT_PATH_FILESTAT_SET_SIZE: u64 = 1 << 19; +pub const __WASI_RIGHT_PATH_FILESTAT_SET_TIMES: u64 = 1 << 20; +pub const __WASI_RIGHT_FD_FILESTAT_GET: u64 = 1 << 21; +pub const __WASI_RIGHT_FD_FILESTAT_SET_SIZE: u64 = 1 << 22; +pub const __WASI_RIGHT_FD_FILESTAT_SET_TIMES: u64 = 1 << 23; +pub const __WASI_RIGHT_PATH_SYMLINK: u64 = 1 << 24; +pub const __WASI_RIGHT_PATH_REMOVE_DIRECTORY: u64 = 1 << 25; +pub const __WASI_RIGHT_PATH_UNLINK_FILE: u64 = 1 << 26; +pub const __WASI_RIGHT_POLL_FD_READWRITE: u64 = 1 << 27; +pub const __WASI_RIGHT_SOCK_SHUTDOWN: u64 = 1 << 28; + +/// function for debugging rights issues +#[allow(dead_code)] +pub fn print_right_set(rights: __wasi_rights_t) { + // BTreeSet for consistent order + let mut right_set = std::collections::BTreeSet::new(); + for i in 0..28 { + let cur_right = rights & (1 << i); + if cur_right != 0 { + right_set.insert(right_to_string(cur_right).unwrap_or("INVALID RIGHT")); + } + } + println!("{:#?}", right_set); +} + +/// expects a single right, returns None if out of bounds or > 1 bit set +pub fn right_to_string(right: __wasi_rights_t) -> Option<&'static str> { + Some(match right { + __WASI_RIGHT_FD_DATASYNC => "__WASI_RIGHT_FD_DATASYNC", + __WASI_RIGHT_FD_READ => "__WASI_RIGHT_FD_READ", + __WASI_RIGHT_FD_SEEK => "__WASI_RIGHT_FD_SEEK", + __WASI_RIGHT_FD_FDSTAT_SET_FLAGS => "__WASI_RIGHT_FD_FDSTAT_SET_FLAGS", + __WASI_RIGHT_FD_SYNC => "__WASI_RIGHT_FD_SYNC", + __WASI_RIGHT_FD_TELL => "__WASI_RIGHT_FD_TELL", + __WASI_RIGHT_FD_WRITE => "__WASI_RIGHT_FD_WRITE", + __WASI_RIGHT_FD_ADVISE => "__WASI_RIGHT_FD_ADVISE", + __WASI_RIGHT_FD_ALLOCATE => "__WASI_RIGHT_FD_ALLOCATE", + __WASI_RIGHT_PATH_CREATE_DIRECTORY => "__WASI_RIGHT_PATH_CREATE_DIRECTORY", + __WASI_RIGHT_PATH_CREATE_FILE => "__WASI_RIGHT_PATH_CREATE_FILE", + __WASI_RIGHT_PATH_LINK_SOURCE => "__WASI_RIGHT_PATH_LINK_SOURCE", + __WASI_RIGHT_PATH_LINK_TARGET => "__WASI_RIGHT_PATH_LINK_TARGET", + __WASI_RIGHT_PATH_OPEN => "__WASI_RIGHT_PATH_OPEN", + __WASI_RIGHT_FD_READDIR => "__WASI_RIGHT_FD_READDIR", + __WASI_RIGHT_PATH_READLINK => "__WASI_RIGHT_PATH_READLINK", + __WASI_RIGHT_PATH_RENAME_SOURCE => "__WASI_RIGHT_PATH_RENAME_SOURCE", + __WASI_RIGHT_PATH_RENAME_TARGET => "__WASI_RIGHT_PATH_RENAME_TARGET", + __WASI_RIGHT_PATH_FILESTAT_GET => "__WASI_RIGHT_PATH_FILESTAT_GET", + __WASI_RIGHT_PATH_FILESTAT_SET_SIZE => "__WASI_RIGHT_PATH_FILESTAT_SET_SIZE", + __WASI_RIGHT_PATH_FILESTAT_SET_TIMES => "__WASI_RIGHT_PATH_FILESTAT_SET_TIMES", + __WASI_RIGHT_FD_FILESTAT_GET => "__WASI_RIGHT_FD_FILESTAT_GET", + __WASI_RIGHT_FD_FILESTAT_SET_SIZE => "__WASI_RIGHT_FD_FILESTAT_SET_SIZE", + __WASI_RIGHT_FD_FILESTAT_SET_TIMES => "__WASI_RIGHT_FD_FILESTAT_SET_TIMES", + __WASI_RIGHT_PATH_SYMLINK => "__WASI_RIGHT_PATH_SYMLINK", + __WASI_RIGHT_PATH_UNLINK_FILE => "__WASI_RIGHT_PATH_UNLINK_FILE", + __WASI_RIGHT_PATH_REMOVE_DIRECTORY => "__WASI_RIGHT_PATH_REMOVE_DIRECTORY", + __WASI_RIGHT_POLL_FD_READWRITE => "__WASI_RIGHT_POLL_FD_READWRITE", + __WASI_RIGHT_SOCK_SHUTDOWN => "__WASI_RIGHT_SOCK_SHUTDOWN", + _ => return None, + }) +} + +pub type __wasi_riflags_t = u16; +pub const __WASI_SOCK_RECV_PEEK: u16 = 1 << 0; +pub const __WASI_SOCK_RECV_WAITALL: u16 = 1 << 1; + +pub type __wasi_roflags_t = u16; +pub const __WASI_SOCK_RECV_DATA_TRUNCATED: u16 = 1 << 0; + +pub type __wasi_whence_t = u8; +pub const __WASI_WHENCE_SET: u8 = 0; +pub const __WASI_WHENCE_CUR: u8 = 1; +pub const __WASI_WHENCE_END: u8 = 2; + +pub type __wasi_sdflags_t = u8; +pub const __WASI_SHUT_RD: u8 = 1 << 0; +pub const __WASI_SHUT_WR: u8 = 1 << 1; + +pub type __wasi_siflags_t = u16; diff --git a/lib/wasi-types/src/io.rs b/lib/wasi-types/src/io.rs new file mode 100644 index 00000000000..76d229f9d12 --- /dev/null +++ b/lib/wasi-types/src/io.rs @@ -0,0 +1,20 @@ +use crate::*; +use wasmer::ValueType; + +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +#[repr(C)] +pub struct __wasi_ciovec_t { + pub buf: WasmPtr, + pub buf_len: u32, +} + +unsafe impl ValueType for __wasi_ciovec_t {} + +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +#[repr(C)] +pub struct __wasi_iovec_t { + pub buf: WasmPtr, + pub buf_len: u32, +} + +unsafe impl ValueType for __wasi_iovec_t {} diff --git a/lib/wasi-types/src/lib.rs b/lib/wasi-types/src/lib.rs new file mode 100644 index 00000000000..e19e1a2a432 --- /dev/null +++ b/lib/wasi-types/src/lib.rs @@ -0,0 +1,37 @@ +#![deny(unused_mut)] +#![doc(html_favicon_url = "https://wasmer.io/images/icons/favicon-32x32.png")] +#![doc(html_logo_url = "https://github.com/wasmerio.png?size=200")] +#![allow(non_camel_case_types, clippy::identity_op)] + +//! Wasmer's WASI types implementation. +//! +//! Those types aim at being used by [the `wasmer-wasi` +//! crate](https://github.com/wasmerio/wasmer/blob/master/lib/wasi). + +mod advice; +mod directory; +mod error; +mod event; +mod file; +mod io; +mod ptr; +mod signal; +mod subscription; +mod time; +mod versions; + +pub use crate::time::*; +pub use advice::*; +pub use directory::*; +pub use error::*; +pub use event::*; +pub use file::*; +pub use io::*; +pub use ptr::*; +pub use signal::*; +pub use subscription::*; +pub use versions::*; + +pub type __wasi_exitcode_t = u32; + +pub type __wasi_userdata_t = u64; diff --git a/lib/wasi/src/ptr.rs b/lib/wasi-types/src/ptr.rs similarity index 97% rename from lib/wasi/src/ptr.rs rename to lib/wasi-types/src/ptr.rs index 4d5ca86a8e0..87ad3b76a59 100644 --- a/lib/wasi/src/ptr.rs +++ b/lib/wasi-types/src/ptr.rs @@ -1,7 +1,7 @@ //! This is a wrapper around the `WasmPtr` abstraction that returns __WASI_EFAULT //! if memory access failed -use crate::syscalls::types::{__wasi_errno_t, __WASI_EFAULT}; +use crate::{__wasi_errno_t, __WASI_EFAULT}; use std::{cell::Cell, fmt}; pub use wasmer::{Array, FromToNativeWasmType, Item, Memory, ValueType, WasmPtr as BaseWasmPtr}; diff --git a/lib/wasi-types/src/signal.rs b/lib/wasi-types/src/signal.rs new file mode 100644 index 00000000000..55d093d842e --- /dev/null +++ b/lib/wasi-types/src/signal.rs @@ -0,0 +1,31 @@ +pub type __wasi_signal_t = u8; +pub const __WASI_SIGHUP: u8 = 1; +pub const __WASI_SIGINT: u8 = 2; +pub const __WASI_SIGQUIT: u8 = 3; +pub const __WASI_SIGILL: u8 = 4; +pub const __WASI_SIGTRAP: u8 = 5; +pub const __WASI_SIGABRT: u8 = 6; +pub const __WASI_SIGBUS: u8 = 7; +pub const __WASI_SIGFPE: u8 = 8; +pub const __WASI_SIGKILL: u8 = 9; +pub const __WASI_SIGUSR1: u8 = 10; +pub const __WASI_SIGSEGV: u8 = 11; +pub const __WASI_SIGUSR2: u8 = 12; +pub const __WASI_SIGPIPE: u8 = 13; +pub const __WASI_SIGALRM: u8 = 14; +pub const __WASI_SIGTERM: u8 = 15; +pub const __WASI_SIGCHLD: u8 = 16; +pub const __WASI_SIGCONT: u8 = 17; +pub const __WASI_SIGSTOP: u8 = 18; +pub const __WASI_SIGTSTP: u8 = 19; +pub const __WASI_SIGTTIN: u8 = 20; +pub const __WASI_SIGTTOU: u8 = 21; +pub const __WASI_SIGURG: u8 = 22; +pub const __WASI_SIGXCPU: u8 = 23; +pub const __WASI_SIGXFSZ: u8 = 24; +pub const __WASI_SIGVTALRM: u8 = 25; +pub const __WASI_SIGPROF: u8 = 26; +pub const __WASI_SIGWINCH: u8 = 27; +pub const __WASI_SIGPOLL: u8 = 28; +pub const __WASI_SIGPWR: u8 = 29; +pub const __WASI_SIGSYS: u8 = 30; diff --git a/lib/wasi-types/src/subscription.rs b/lib/wasi-types/src/subscription.rs new file mode 100644 index 00000000000..c8265bcc13a --- /dev/null +++ b/lib/wasi-types/src/subscription.rs @@ -0,0 +1,143 @@ +use crate::*; +use std::convert::TryFrom; +use std::fmt; + +pub type __wasi_subclockflags_t = u16; +pub const __WASI_SUBSCRIPTION_CLOCK_ABSTIME: u16 = 1 << 0; + +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +#[repr(C)] +pub struct __wasi_subscription_clock_t { + pub clock_id: __wasi_clockid_t, + pub timeout: __wasi_timestamp_t, + pub precision: __wasi_timestamp_t, + pub flags: __wasi_subclockflags_t, +} + +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +#[repr(C)] +pub struct __wasi_subscription_fs_readwrite_t { + pub fd: __wasi_fd_t, +} + +#[derive(Copy, Clone)] +#[repr(C)] +pub union __wasi_subscription_u { + pub clock: __wasi_subscription_clock_t, + pub fd_readwrite: __wasi_subscription_fs_readwrite_t, +} + +#[derive(Copy, Clone)] +#[repr(C)] +pub struct __wasi_subscription_t { + pub userdata: __wasi_userdata_t, + pub type_: __wasi_eventtype_t, + pub u: __wasi_subscription_u, +} + +/// Safe Rust wrapper around `__wasi_subscription_t::type_` and `__wasi_subscription_t::u` +#[derive(Debug, Clone)] +pub enum EventType { + Clock(__wasi_subscription_clock_t), + Read(__wasi_subscription_fs_readwrite_t), + Write(__wasi_subscription_fs_readwrite_t), +} + +impl EventType { + pub fn raw_tag(&self) -> __wasi_eventtype_t { + match self { + EventType::Clock(_) => __WASI_EVENTTYPE_CLOCK, + EventType::Read(_) => __WASI_EVENTTYPE_FD_READ, + EventType::Write(_) => __WASI_EVENTTYPE_FD_WRITE, + } + } +} + +/// Safe Rust wrapper around `__wasi_subscription_t` +#[derive(Debug, Clone)] +pub struct WasiSubscription { + pub user_data: __wasi_userdata_t, + pub event_type: EventType, +} + +impl TryFrom<__wasi_subscription_t> for WasiSubscription { + type Error = __wasi_errno_t; + + fn try_from(ws: __wasi_subscription_t) -> Result { + Ok(Self { + user_data: ws.userdata, + event_type: match ws.type_ { + __WASI_EVENTTYPE_CLOCK => EventType::Clock(unsafe { ws.u.clock }), + __WASI_EVENTTYPE_FD_READ => EventType::Read(unsafe { ws.u.fd_readwrite }), + __WASI_EVENTTYPE_FD_WRITE => EventType::Write(unsafe { ws.u.fd_readwrite }), + _ => return Err(__WASI_EINVAL), + }, + }) + } +} + +impl TryFrom for __wasi_subscription_t { + type Error = __wasi_errno_t; + + fn try_from(ws: WasiSubscription) -> Result { + #[allow(unreachable_patterns)] + let (type_, u) = match ws.event_type { + EventType::Clock(c) => (__WASI_EVENTTYPE_CLOCK, __wasi_subscription_u { clock: c }), + EventType::Read(rw) => ( + __WASI_EVENTTYPE_FD_READ, + __wasi_subscription_u { fd_readwrite: rw }, + ), + EventType::Write(rw) => ( + __WASI_EVENTTYPE_FD_WRITE, + __wasi_subscription_u { fd_readwrite: rw }, + ), + _ => return Err(__WASI_EINVAL), + }; + + Ok(Self { + userdata: ws.user_data, + type_, + u, + }) + } +} + +impl fmt::Debug for __wasi_subscription_t { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("__wasi_subscription_t") + .field("userdata", &self.userdata) + .field("type", &eventtype_to_str(self.type_)) + .field( + "u", + match self.type_ { + __WASI_EVENTTYPE_CLOCK => unsafe { &self.u.clock }, + __WASI_EVENTTYPE_FD_READ | __WASI_EVENTTYPE_FD_WRITE => unsafe { + &self.u.fd_readwrite + }, + _ => &"INVALID EVENTTYPE", + }, + ) + .finish() + } +} + +unsafe impl ValueType for __wasi_subscription_t {} + +pub enum SubscriptionEnum { + Clock(__wasi_subscription_clock_t), + FdReadWrite(__wasi_subscription_fs_readwrite_t), +} + +impl __wasi_subscription_t { + pub fn tagged(&self) -> Option { + match self.type_ { + __WASI_EVENTTYPE_CLOCK => Some(SubscriptionEnum::Clock(unsafe { self.u.clock })), + __WASI_EVENTTYPE_FD_READ | __WASI_EVENTTYPE_FD_WRITE => { + Some(SubscriptionEnum::FdReadWrite(unsafe { + self.u.fd_readwrite + })) + } + _ => None, + } + } +} diff --git a/lib/wasi-types/src/time.rs b/lib/wasi-types/src/time.rs new file mode 100644 index 00000000000..85b3ef05f12 --- /dev/null +++ b/lib/wasi-types/src/time.rs @@ -0,0 +1,7 @@ +pub type __wasi_clockid_t = u32; +pub const __WASI_CLOCK_REALTIME: u32 = 0; +pub const __WASI_CLOCK_MONOTONIC: u32 = 1; +pub const __WASI_CLOCK_PROCESS_CPUTIME_ID: u32 = 2; +pub const __WASI_CLOCK_THREAD_CPUTIME_ID: u32 = 3; + +pub type __wasi_timestamp_t = u64; diff --git a/lib/wasi-types/src/versions/mod.rs b/lib/wasi-types/src/versions/mod.rs new file mode 100644 index 00000000000..9ed2b1d4f5f --- /dev/null +++ b/lib/wasi-types/src/versions/mod.rs @@ -0,0 +1 @@ +pub mod snapshot0; diff --git a/lib/wasi-types/src/versions/snapshot0.rs b/lib/wasi-types/src/versions/snapshot0.rs new file mode 100644 index 00000000000..8dd747d6058 --- /dev/null +++ b/lib/wasi-types/src/versions/snapshot0.rs @@ -0,0 +1,101 @@ +use crate::*; +use serde::{Deserialize, Serialize}; +use std::fmt; +use wasmer::ValueType; + +pub type __wasi_linkcount_t = u32; + +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +#[repr(C)] +pub struct __wasi_subscription_clock_t { + pub userdata: __wasi_userdata_t, + pub clock_id: __wasi_clockid_t, + pub timeout: __wasi_timestamp_t, + pub precision: __wasi_timestamp_t, + pub flags: __wasi_subclockflags_t, +} + +#[derive(Copy, Clone)] +#[repr(C)] +pub union __wasi_subscription_u { + pub clock: __wasi_subscription_clock_t, + pub fd_readwrite: __wasi_subscription_fs_readwrite_t, +} + +#[derive(Copy, Clone)] +#[repr(C)] +pub struct __wasi_subscription_t { + pub userdata: __wasi_userdata_t, + pub type_: __wasi_eventtype_t, + pub u: __wasi_subscription_u, +} + +unsafe impl ValueType for __wasi_subscription_t {} + +pub type __wasi_whence_t = u8; +pub const __WASI_WHENCE_CUR: u8 = 0; +pub const __WASI_WHENCE_END: u8 = 1; +pub const __WASI_WHENCE_SET: u8 = 2; + +#[derive(Copy, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[repr(C)] +pub struct __wasi_filestat_t { + pub st_dev: __wasi_device_t, + pub st_ino: __wasi_inode_t, + pub st_filetype: __wasi_filetype_t, + pub st_nlink: __wasi_linkcount_t, + pub st_size: __wasi_filesize_t, + pub st_atim: __wasi_timestamp_t, + pub st_mtim: __wasi_timestamp_t, + pub st_ctim: __wasi_timestamp_t, +} + +unsafe impl ValueType for __wasi_filestat_t {} + +impl fmt::Debug for __wasi_filestat_t { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let convert_ts_into_time_string = |ts| { + let tspec = + ::time::Timespec::new(ts as i64 / 1_000_000_000, (ts % 1_000_000_000) as i32); + let tm = ::time::at(tspec); + let out_time = tm.rfc822(); + format!("{} ({})", out_time, ts) + }; + f.debug_struct("__wasi_filestat_t") + .field("st_dev", &self.st_dev) + .field("st_ino", &self.st_ino) + .field( + "st_filetype", + &format!( + "{} ({})", + wasi_filetype_to_name(self.st_filetype), + self.st_filetype, + ), + ) + .field("st_nlink", &self.st_nlink) + .field("st_size", &self.st_size) + .field("st_atim", &convert_ts_into_time_string(self.st_atim)) + .field("st_mtim", &convert_ts_into_time_string(self.st_mtim)) + .field("st_ctim", &convert_ts_into_time_string(self.st_ctim)) + .finish() + } +} + +impl fmt::Debug for __wasi_subscription_t { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("__wasi_subscription_t") + .field("userdata", &self.userdata) + .field("type", &eventtype_to_str(self.type_)) + .field( + "u", + match self.type_ { + __WASI_EVENTTYPE_CLOCK => unsafe { &self.u.clock }, + __WASI_EVENTTYPE_FD_READ | __WASI_EVENTTYPE_FD_WRITE => unsafe { + &self.u.fd_readwrite + }, + _ => &"INVALID EVENTTYPE", + }, + ) + .finish() + } +} diff --git a/lib/wasi/Cargo.toml b/lib/wasi/Cargo.toml index b4f434416d7..9e37067f3f3 100644 --- a/lib/wasi/Cargo.toml +++ b/lib/wasi/Cargo.toml @@ -12,15 +12,14 @@ edition = "2018" [dependencies] bincode = "1" -byteorder = "1.3" thiserror = "1" generational-arena = { version = "0.2", features = ["serde"] } libc = { version = "^0.2", default-features = false } tracing = { version = "0.1" } getrandom = "0.2" -time = "0.1" typetag = "0.1" serde = { version = "1.0", features = ["derive"] } +wasmer-wasi-types = { path = "../wasi-types", version = "2.0.0-rc2" } wasmer = { path = "../api", version = "2.0.0-rc2", default-features = false } [target.'cfg(windows)'.dependencies] diff --git a/lib/wasi/src/lib.rs b/lib/wasi/src/lib.rs index 181f485b982..9c595ecdbe7 100644 --- a/lib/wasi/src/lib.rs +++ b/lib/wasi/src/lib.rs @@ -14,7 +14,9 @@ #[macro_use] mod macros; -mod ptr; +mod ptr { + pub use wasmer_wasi_types::{Array, WasmPtr}; +} mod state; mod syscalls; mod utils; diff --git a/lib/wasi/src/syscalls/mod.rs b/lib/wasi/src/syscalls/mod.rs index 8444100e121..a8855221a68 100644 --- a/lib/wasi/src/syscalls/mod.rs +++ b/lib/wasi/src/syscalls/mod.rs @@ -1,6 +1,9 @@ #![allow(unused, clippy::too_many_arguments, clippy::cognitive_complexity)] -pub mod types; +pub mod types { + pub use wasmer_wasi_types::*; +} + #[cfg(any( target_os = "freebsd", target_os = "linux", diff --git a/lib/wasi/src/syscalls/types.rs b/lib/wasi/src/syscalls/types.rs deleted file mode 100644 index 6fe1311e638..00000000000 --- a/lib/wasi/src/syscalls/types.rs +++ /dev/null @@ -1,804 +0,0 @@ -#![allow(non_camel_case_types, clippy::identity_op)] - -use crate::ptr::{Array, WasmPtr}; -use byteorder::{ReadBytesExt, WriteBytesExt, LE}; -use serde::{Deserialize, Serialize}; -use std::fmt; -use std::mem; -use wasmer::ValueType; - -pub type __wasi_advice_t = u8; -pub const __WASI_ADVICE_NORMAL: u8 = 0; -pub const __WASI_ADVICE_SEQUENTIAL: u8 = 1; -pub const __WASI_ADVICE_RANDOM: u8 = 2; -pub const __WASI_ADVICE_WILLNEED: u8 = 3; -pub const __WASI_ADVICE_DONTNEED: u8 = 4; -pub const __WASI_ADVICE_NOREUSE: u8 = 5; - -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -#[repr(C)] -pub struct __wasi_ciovec_t { - pub buf: WasmPtr, - pub buf_len: u32, -} - -unsafe impl ValueType for __wasi_ciovec_t {} - -pub type __wasi_clockid_t = u32; -pub const __WASI_CLOCK_REALTIME: u32 = 0; -pub const __WASI_CLOCK_MONOTONIC: u32 = 1; -pub const __WASI_CLOCK_PROCESS_CPUTIME_ID: u32 = 2; -pub const __WASI_CLOCK_THREAD_CPUTIME_ID: u32 = 3; - -pub type __wasi_device_t = u64; - -pub type __wasi_dircookie_t = u64; -pub const __WASI_DIRCOOKIE_START: u64 = 0; - -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -#[repr(C)] -pub struct __wasi_dirent_t { - pub d_next: __wasi_dircookie_t, - pub d_ino: __wasi_inode_t, - pub d_namlen: u32, - pub d_type: __wasi_filetype_t, -} - -unsafe impl ValueType for __wasi_dirent_t {} - -pub fn dirent_to_le_bytes(ent: &__wasi_dirent_t) -> Vec { - use std::mem::transmute; - let mut out = Vec::with_capacity(std::mem::size_of::<__wasi_dirent_t>()); - let bytes: [u8; 8] = unsafe { transmute(ent.d_next.to_le()) }; - for &b in &bytes { - out.push(b); - } - let bytes: [u8; 8] = unsafe { transmute(ent.d_ino.to_le()) }; - for &b in &bytes { - out.push(b); - } - let bytes: [u8; 4] = unsafe { transmute(ent.d_namlen.to_le()) }; - for &b in &bytes { - out.push(b); - } - out.push(ent.d_type); - out.push(0); - out.push(0); - out.push(0); - assert_eq!(out.len(), std::mem::size_of::<__wasi_dirent_t>()); - out -} - -pub type __wasi_errno_t = u16; -pub const __WASI_ESUCCESS: u16 = 0; -pub const __WASI_E2BIG: u16 = 1; -pub const __WASI_EACCES: u16 = 2; -pub const __WASI_EADDRINUSE: u16 = 3; -pub const __WASI_EADDRNOTAVAIL: u16 = 4; -pub const __WASI_EAFNOSUPPORT: u16 = 5; -pub const __WASI_EAGAIN: u16 = 6; -pub const __WASI_EALREADY: u16 = 7; -pub const __WASI_EBADF: u16 = 8; -pub const __WASI_EBADMSG: u16 = 9; -pub const __WASI_EBUSY: u16 = 10; -pub const __WASI_ECANCELED: u16 = 11; -pub const __WASI_ECHILD: u16 = 12; -pub const __WASI_ECONNABORTED: u16 = 13; -pub const __WASI_ECONNREFUSED: u16 = 14; -pub const __WASI_ECONNRESET: u16 = 15; -pub const __WASI_EDEADLK: u16 = 16; -pub const __WASI_EDESTADDRREQ: u16 = 17; -pub const __WASI_EDOM: u16 = 18; -pub const __WASI_EDQUOT: u16 = 19; -pub const __WASI_EEXIST: u16 = 20; -pub const __WASI_EFAULT: u16 = 21; -pub const __WASI_EFBIG: u16 = 22; -pub const __WASI_EHOSTUNREACH: u16 = 23; -pub const __WASI_EIDRM: u16 = 24; -pub const __WASI_EILSEQ: u16 = 25; -pub const __WASI_EINPROGRESS: u16 = 26; -pub const __WASI_EINTR: u16 = 27; -pub const __WASI_EINVAL: u16 = 28; -pub const __WASI_EIO: u16 = 29; -pub const __WASI_EISCONN: u16 = 30; -pub const __WASI_EISDIR: u16 = 31; -pub const __WASI_ELOOP: u16 = 32; -pub const __WASI_EMFILE: u16 = 33; -pub const __WASI_EMLINK: u16 = 34; -pub const __WASI_EMSGSIZE: u16 = 35; -pub const __WASI_EMULTIHOP: u16 = 36; -pub const __WASI_ENAMETOOLONG: u16 = 37; -pub const __WASI_ENETDOWN: u16 = 38; -pub const __WASI_ENETRESET: u16 = 39; -pub const __WASI_ENETUNREACH: u16 = 40; -pub const __WASI_ENFILE: u16 = 41; -pub const __WASI_ENOBUFS: u16 = 42; -pub const __WASI_ENODEV: u16 = 43; -pub const __WASI_ENOENT: u16 = 44; -pub const __WASI_ENOEXEC: u16 = 45; -pub const __WASI_ENOLCK: u16 = 46; -pub const __WASI_ENOLINK: u16 = 47; -pub const __WASI_ENOMEM: u16 = 48; -pub const __WASI_ENOMSG: u16 = 49; -pub const __WASI_ENOPROTOOPT: u16 = 50; -pub const __WASI_ENOSPC: u16 = 51; -pub const __WASI_ENOSYS: u16 = 52; -pub const __WASI_ENOTCONN: u16 = 53; -pub const __WASI_ENOTDIR: u16 = 54; -pub const __WASI_ENOTEMPTY: u16 = 55; -pub const __WASI_ENOTRECOVERABLE: u16 = 56; -pub const __WASI_ENOTSOCK: u16 = 57; -pub const __WASI_ENOTSUP: u16 = 58; -pub const __WASI_ENOTTY: u16 = 59; -pub const __WASI_ENXIO: u16 = 60; -pub const __WASI_EOVERFLOW: u16 = 61; -pub const __WASI_EOWNERDEAD: u16 = 62; -pub const __WASI_EPERM: u16 = 63; -pub const __WASI_EPIPE: u16 = 64; -pub const __WASI_EPROTO: u16 = 65; -pub const __WASI_EPROTONOSUPPORT: u16 = 66; -pub const __WASI_EPROTOTYPE: u16 = 67; -pub const __WASI_ERANGE: u16 = 68; -pub const __WASI_EROFS: u16 = 69; -pub const __WASI_ESPIPE: u16 = 70; -pub const __WASI_ESRCH: u16 = 71; -pub const __WASI_ESTALE: u16 = 72; -pub const __WASI_ETIMEDOUT: u16 = 73; -pub const __WASI_ETXTBSY: u16 = 74; -pub const __WASI_EXDEV: u16 = 75; -pub const __WASI_ENOTCAPABLE: u16 = 76; - -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -#[repr(C)] -pub struct __wasi_event_fd_readwrite_t { - pub nbytes: __wasi_filesize_t, - pub flags: __wasi_eventrwflags_t, -} - -#[derive(Copy, Clone)] -#[repr(C)] -pub union __wasi_event_u { - pub fd_readwrite: __wasi_event_fd_readwrite_t, -} - -// TODO: remove this implementation of Debug when `__wasi_event_u` gets more than 1 variant -impl std::fmt::Debug for __wasi_event_u { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("__wasi_event_u") - .field("fd_readwrite", unsafe { &self.fd_readwrite }) - .finish() - } -} - -#[derive(Debug, Copy, Clone)] -pub enum EventEnum { - FdReadWrite { - nbytes: __wasi_filesize_t, - flags: __wasi_eventrwflags_t, - }, -} - -impl EventEnum { - pub fn untagged(self) -> __wasi_event_u { - match self { - EventEnum::FdReadWrite { nbytes, flags } => __wasi_event_u { - fd_readwrite: __wasi_event_fd_readwrite_t { nbytes, flags }, - }, - } - } -} - -#[derive(Debug, Copy, Clone)] -#[repr(C)] -pub struct __wasi_event_t { - pub userdata: __wasi_userdata_t, - pub error: __wasi_errno_t, - pub type_: __wasi_eventtype_t, - pub u: __wasi_event_u, -} - -impl __wasi_event_t { - pub fn tagged(&self) -> Option { - match self.type_ { - __WASI_EVENTTYPE_FD_READ | __WASI_EVENTTYPE_FD_WRITE => Some(EventEnum::FdReadWrite { - nbytes: unsafe { self.u.fd_readwrite.nbytes }, - flags: unsafe { self.u.fd_readwrite.flags }, - }), - _ => None, - } - } -} - -unsafe impl ValueType for __wasi_event_t {} - -pub type __wasi_eventrwflags_t = u16; -pub const __WASI_EVENT_FD_READWRITE_HANGUP: u16 = 1 << 0; - -pub type __wasi_eventtype_t = u8; -pub const __WASI_EVENTTYPE_CLOCK: u8 = 0; -pub const __WASI_EVENTTYPE_FD_READ: u8 = 1; -pub const __WASI_EVENTTYPE_FD_WRITE: u8 = 2; - -pub fn eventtype_to_str(event_type: __wasi_eventtype_t) -> &'static str { - match event_type { - __WASI_EVENTTYPE_CLOCK => "__WASI_EVENTTYPE_CLOCK", - __WASI_EVENTTYPE_FD_READ => "__WASI_EVENTTYPE_FD_READ", - __WASI_EVENTTYPE_FD_WRITE => "__WASI_EVENTTYPE_FD_WRITE", - _ => "INVALID EVENTTYPE", - } -} - -pub type __wasi_exitcode_t = u32; - -pub type __wasi_fd_t = u32; -pub const __WASI_STDIN_FILENO: u32 = 0; -pub const __WASI_STDOUT_FILENO: u32 = 1; -pub const __WASI_STDERR_FILENO: u32 = 2; - -pub type __wasi_fdflags_t = u16; -pub const __WASI_FDFLAG_APPEND: u16 = 1 << 0; -pub const __WASI_FDFLAG_DSYNC: u16 = 1 << 1; -pub const __WASI_FDFLAG_NONBLOCK: u16 = 1 << 2; -pub const __WASI_FDFLAG_RSYNC: u16 = 1 << 3; -pub const __WASI_FDFLAG_SYNC: u16 = 1 << 4; - -pub type __wasi_preopentype_t = u8; -pub const __WASI_PREOPENTYPE_DIR: u8 = 0; - -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -#[repr(C)] -pub struct __wasi_prestat_u_dir_t { - pub pr_name_len: u32, -} - -unsafe impl ValueType for __wasi_prestat_u_dir_t {} - -#[derive(Copy, Clone)] -#[repr(C)] -pub union __wasi_prestat_u { - dir: __wasi_prestat_u_dir_t, -} - -impl fmt::Debug for __wasi_prestat_u { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "__wasi_prestat_u") - } -} - -unsafe impl ValueType for __wasi_prestat_u {} - -#[derive(Debug, Copy, Clone)] -#[repr(C)] -pub struct __wasi_prestat_t { - pub pr_type: __wasi_preopentype_t, - pub u: __wasi_prestat_u, -} - -#[derive(Copy, Clone)] -pub enum PrestatEnum { - Dir { pr_name_len: u32 }, -} - -impl PrestatEnum { - pub fn untagged(self) -> __wasi_prestat_u { - match self { - PrestatEnum::Dir { pr_name_len } => __wasi_prestat_u { - dir: __wasi_prestat_u_dir_t { pr_name_len }, - }, - } - } -} - -impl __wasi_prestat_t { - #[allow(clippy::trivially_copy_pass_by_ref)] - pub fn tagged(&self) -> Option { - match self.pr_type { - __WASI_PREOPENTYPE_DIR => Some(PrestatEnum::Dir { - pr_name_len: unsafe { self.u.dir.pr_name_len }, - }), - _ => None, - } - } -} - -unsafe impl ValueType for __wasi_prestat_t {} - -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -#[repr(C)] -pub struct __wasi_fdstat_t { - pub fs_filetype: __wasi_filetype_t, - pub fs_flags: __wasi_fdflags_t, - pub fs_rights_base: __wasi_rights_t, - pub fs_rights_inheriting: __wasi_rights_t, -} - -unsafe impl ValueType for __wasi_fdstat_t {} - -pub type __wasi_filedelta_t = i64; - -pub type __wasi_filesize_t = u64; - -#[derive(Copy, Clone, PartialEq, Eq, Serialize, Deserialize)] -#[repr(C)] -pub struct __wasi_filestat_t { - pub st_dev: __wasi_device_t, - pub st_ino: __wasi_inode_t, - pub st_filetype: __wasi_filetype_t, - pub st_nlink: __wasi_linkcount_t, - pub st_size: __wasi_filesize_t, - pub st_atim: __wasi_timestamp_t, - pub st_mtim: __wasi_timestamp_t, - pub st_ctim: __wasi_timestamp_t, -} - -impl Default for __wasi_filestat_t { - fn default() -> Self { - __wasi_filestat_t { - st_dev: Default::default(), - st_ino: Default::default(), - st_filetype: __WASI_FILETYPE_UNKNOWN, - st_nlink: 1, - st_size: Default::default(), - st_atim: Default::default(), - st_mtim: Default::default(), - st_ctim: Default::default(), - } - } -} - -impl std::fmt::Debug for __wasi_filestat_t { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let convert_ts_into_time_string = |ts| { - let tspec = time::Timespec::new(ts as i64 / 1_000_000_000, (ts % 1_000_000_000) as i32); - let tm = time::at(tspec); - let out_time = tm.rfc822(); - format!("{} ({})", out_time, ts) - }; - f.debug_struct("__wasi_filestat_t") - .field("st_dev", &self.st_dev) - .field("st_ino", &self.st_ino) - .field( - "st_filetype", - &format!( - "{} ({})", - wasi_filetype_to_name(self.st_filetype), - self.st_filetype, - ), - ) - .field("st_nlink", &self.st_nlink) - .field("st_size", &self.st_size) - .field("st_atim", &convert_ts_into_time_string(self.st_atim)) - .field("st_mtim", &convert_ts_into_time_string(self.st_mtim)) - .field("st_ctim", &convert_ts_into_time_string(self.st_ctim)) - .finish() - } -} - -unsafe impl ValueType for __wasi_filestat_t {} - -pub fn wasi_filetype_to_name(ft: __wasi_filetype_t) -> &'static str { - match ft { - __WASI_FILETYPE_UNKNOWN => "Unknown", - __WASI_FILETYPE_BLOCK_DEVICE => "Block device", - __WASI_FILETYPE_CHARACTER_DEVICE => "Character device", - __WASI_FILETYPE_DIRECTORY => "Directory", - __WASI_FILETYPE_REGULAR_FILE => "Regular file", - __WASI_FILETYPE_SOCKET_DGRAM => "Socket dgram", - __WASI_FILETYPE_SOCKET_STREAM => "Socket stream", - __WASI_FILETYPE_SYMBOLIC_LINK => "Symbolic link", - _ => "Invalid", - } -} - -pub type __wasi_filetype_t = u8; -pub const __WASI_FILETYPE_UNKNOWN: u8 = 0; -pub const __WASI_FILETYPE_BLOCK_DEVICE: u8 = 1; -pub const __WASI_FILETYPE_CHARACTER_DEVICE: u8 = 2; -pub const __WASI_FILETYPE_DIRECTORY: u8 = 3; -pub const __WASI_FILETYPE_REGULAR_FILE: u8 = 4; -pub const __WASI_FILETYPE_SOCKET_DGRAM: u8 = 5; -pub const __WASI_FILETYPE_SOCKET_STREAM: u8 = 6; -pub const __WASI_FILETYPE_SYMBOLIC_LINK: u8 = 7; - -pub type __wasi_fstflags_t = u16; -pub const __WASI_FILESTAT_SET_ATIM: u16 = 1 << 0; -pub const __WASI_FILESTAT_SET_ATIM_NOW: u16 = 1 << 1; -pub const __WASI_FILESTAT_SET_MTIM: u16 = 1 << 2; -pub const __WASI_FILESTAT_SET_MTIM_NOW: u16 = 1 << 3; - -pub type __wasi_inode_t = u64; - -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -#[repr(C)] -pub struct __wasi_iovec_t { - pub buf: WasmPtr, - pub buf_len: u32, -} - -unsafe impl ValueType for __wasi_iovec_t {} - -pub type __wasi_linkcount_t = u64; - -pub type __wasi_lookupflags_t = u32; -pub const __WASI_LOOKUP_SYMLINK_FOLLOW: u32 = 1 << 0; - -pub type __wasi_oflags_t = u16; -pub const __WASI_O_CREAT: u16 = 1 << 0; -pub const __WASI_O_DIRECTORY: u16 = 1 << 1; -pub const __WASI_O_EXCL: u16 = 1 << 2; -pub const __WASI_O_TRUNC: u16 = 1 << 3; - -pub type __wasi_riflags_t = u16; -pub const __WASI_SOCK_RECV_PEEK: u16 = 1 << 0; -pub const __WASI_SOCK_RECV_WAITALL: u16 = 1 << 1; - -pub type __wasi_rights_t = u64; -pub const __WASI_RIGHT_FD_DATASYNC: u64 = 1 << 0; -pub const __WASI_RIGHT_FD_READ: u64 = 1 << 1; -pub const __WASI_RIGHT_FD_SEEK: u64 = 1 << 2; -pub const __WASI_RIGHT_FD_FDSTAT_SET_FLAGS: u64 = 1 << 3; -pub const __WASI_RIGHT_FD_SYNC: u64 = 1 << 4; -pub const __WASI_RIGHT_FD_TELL: u64 = 1 << 5; -pub const __WASI_RIGHT_FD_WRITE: u64 = 1 << 6; -pub const __WASI_RIGHT_FD_ADVISE: u64 = 1 << 7; -pub const __WASI_RIGHT_FD_ALLOCATE: u64 = 1 << 8; -pub const __WASI_RIGHT_PATH_CREATE_DIRECTORY: u64 = 1 << 9; -pub const __WASI_RIGHT_PATH_CREATE_FILE: u64 = 1 << 10; -pub const __WASI_RIGHT_PATH_LINK_SOURCE: u64 = 1 << 11; -pub const __WASI_RIGHT_PATH_LINK_TARGET: u64 = 1 << 12; -pub const __WASI_RIGHT_PATH_OPEN: u64 = 1 << 13; -pub const __WASI_RIGHT_FD_READDIR: u64 = 1 << 14; -pub const __WASI_RIGHT_PATH_READLINK: u64 = 1 << 15; -pub const __WASI_RIGHT_PATH_RENAME_SOURCE: u64 = 1 << 16; -pub const __WASI_RIGHT_PATH_RENAME_TARGET: u64 = 1 << 17; -pub const __WASI_RIGHT_PATH_FILESTAT_GET: u64 = 1 << 18; -pub const __WASI_RIGHT_PATH_FILESTAT_SET_SIZE: u64 = 1 << 19; -pub const __WASI_RIGHT_PATH_FILESTAT_SET_TIMES: u64 = 1 << 20; -pub const __WASI_RIGHT_FD_FILESTAT_GET: u64 = 1 << 21; -pub const __WASI_RIGHT_FD_FILESTAT_SET_SIZE: u64 = 1 << 22; -pub const __WASI_RIGHT_FD_FILESTAT_SET_TIMES: u64 = 1 << 23; -pub const __WASI_RIGHT_PATH_SYMLINK: u64 = 1 << 24; -pub const __WASI_RIGHT_PATH_REMOVE_DIRECTORY: u64 = 1 << 25; -pub const __WASI_RIGHT_PATH_UNLINK_FILE: u64 = 1 << 26; -pub const __WASI_RIGHT_POLL_FD_READWRITE: u64 = 1 << 27; -pub const __WASI_RIGHT_SOCK_SHUTDOWN: u64 = 1 << 28; - -/// function for debugging rights issues -#[allow(dead_code)] -pub fn print_right_set(rights: __wasi_rights_t) { - // BTreeSet for consistent order - let mut right_set = std::collections::BTreeSet::new(); - for i in 0..28 { - let cur_right = rights & (1 << i); - if cur_right != 0 { - right_set.insert(right_to_string(cur_right).unwrap_or("INVALID RIGHT")); - } - } - println!("{:#?}", right_set); -} - -/// expects a single right, returns None if out of bounds or > 1 bit set -pub fn right_to_string(right: __wasi_rights_t) -> Option<&'static str> { - Some(match right { - __WASI_RIGHT_FD_DATASYNC => "__WASI_RIGHT_FD_DATASYNC", - __WASI_RIGHT_FD_READ => "__WASI_RIGHT_FD_READ", - __WASI_RIGHT_FD_SEEK => "__WASI_RIGHT_FD_SEEK", - __WASI_RIGHT_FD_FDSTAT_SET_FLAGS => "__WASI_RIGHT_FD_FDSTAT_SET_FLAGS", - __WASI_RIGHT_FD_SYNC => "__WASI_RIGHT_FD_SYNC", - __WASI_RIGHT_FD_TELL => "__WASI_RIGHT_FD_TELL", - __WASI_RIGHT_FD_WRITE => "__WASI_RIGHT_FD_WRITE", - __WASI_RIGHT_FD_ADVISE => "__WASI_RIGHT_FD_ADVISE", - __WASI_RIGHT_FD_ALLOCATE => "__WASI_RIGHT_FD_ALLOCATE", - __WASI_RIGHT_PATH_CREATE_DIRECTORY => "__WASI_RIGHT_PATH_CREATE_DIRECTORY", - __WASI_RIGHT_PATH_CREATE_FILE => "__WASI_RIGHT_PATH_CREATE_FILE", - __WASI_RIGHT_PATH_LINK_SOURCE => "__WASI_RIGHT_PATH_LINK_SOURCE", - __WASI_RIGHT_PATH_LINK_TARGET => "__WASI_RIGHT_PATH_LINK_TARGET", - __WASI_RIGHT_PATH_OPEN => "__WASI_RIGHT_PATH_OPEN", - __WASI_RIGHT_FD_READDIR => "__WASI_RIGHT_FD_READDIR", - __WASI_RIGHT_PATH_READLINK => "__WASI_RIGHT_PATH_READLINK", - __WASI_RIGHT_PATH_RENAME_SOURCE => "__WASI_RIGHT_PATH_RENAME_SOURCE", - __WASI_RIGHT_PATH_RENAME_TARGET => "__WASI_RIGHT_PATH_RENAME_TARGET", - __WASI_RIGHT_PATH_FILESTAT_GET => "__WASI_RIGHT_PATH_FILESTAT_GET", - __WASI_RIGHT_PATH_FILESTAT_SET_SIZE => "__WASI_RIGHT_PATH_FILESTAT_SET_SIZE", - __WASI_RIGHT_PATH_FILESTAT_SET_TIMES => "__WASI_RIGHT_PATH_FILESTAT_SET_TIMES", - __WASI_RIGHT_FD_FILESTAT_GET => "__WASI_RIGHT_FD_FILESTAT_GET", - __WASI_RIGHT_FD_FILESTAT_SET_SIZE => "__WASI_RIGHT_FD_FILESTAT_SET_SIZE", - __WASI_RIGHT_FD_FILESTAT_SET_TIMES => "__WASI_RIGHT_FD_FILESTAT_SET_TIMES", - __WASI_RIGHT_PATH_SYMLINK => "__WASI_RIGHT_PATH_SYMLINK", - __WASI_RIGHT_PATH_UNLINK_FILE => "__WASI_RIGHT_PATH_UNLINK_FILE", - __WASI_RIGHT_PATH_REMOVE_DIRECTORY => "__WASI_RIGHT_PATH_REMOVE_DIRECTORY", - __WASI_RIGHT_POLL_FD_READWRITE => "__WASI_RIGHT_POLL_FD_READWRITE", - __WASI_RIGHT_SOCK_SHUTDOWN => "__WASI_RIGHT_SOCK_SHUTDOWN", - _ => return None, - }) -} - -pub type __wasi_roflags_t = u16; -pub const __WASI_SOCK_RECV_DATA_TRUNCATED: u16 = 1 << 0; - -pub type __wasi_sdflags_t = u8; -pub const __WASI_SHUT_RD: u8 = 1 << 0; -pub const __WASI_SHUT_WR: u8 = 1 << 1; - -pub type __wasi_siflags_t = u16; - -pub type __wasi_signal_t = u8; -pub const __WASI_SIGHUP: u8 = 1; -pub const __WASI_SIGINT: u8 = 2; -pub const __WASI_SIGQUIT: u8 = 3; -pub const __WASI_SIGILL: u8 = 4; -pub const __WASI_SIGTRAP: u8 = 5; -pub const __WASI_SIGABRT: u8 = 6; -pub const __WASI_SIGBUS: u8 = 7; -pub const __WASI_SIGFPE: u8 = 8; -pub const __WASI_SIGKILL: u8 = 9; -pub const __WASI_SIGUSR1: u8 = 10; -pub const __WASI_SIGSEGV: u8 = 11; -pub const __WASI_SIGUSR2: u8 = 12; -pub const __WASI_SIGPIPE: u8 = 13; -pub const __WASI_SIGALRM: u8 = 14; -pub const __WASI_SIGTERM: u8 = 15; -pub const __WASI_SIGCHLD: u8 = 16; -pub const __WASI_SIGCONT: u8 = 17; -pub const __WASI_SIGSTOP: u8 = 18; -pub const __WASI_SIGTSTP: u8 = 19; -pub const __WASI_SIGTTIN: u8 = 20; -pub const __WASI_SIGTTOU: u8 = 21; -pub const __WASI_SIGURG: u8 = 22; -pub const __WASI_SIGXCPU: u8 = 23; -pub const __WASI_SIGXFSZ: u8 = 24; -pub const __WASI_SIGVTALRM: u8 = 25; -pub const __WASI_SIGPROF: u8 = 26; -pub const __WASI_SIGWINCH: u8 = 27; -pub const __WASI_SIGPOLL: u8 = 28; -pub const __WASI_SIGPWR: u8 = 29; -pub const __WASI_SIGSYS: u8 = 30; - -pub type __wasi_subclockflags_t = u16; -pub const __WASI_SUBSCRIPTION_CLOCK_ABSTIME: u16 = 1 << 0; - -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -#[repr(C)] -pub struct __wasi_subscription_clock_t { - pub clock_id: __wasi_clockid_t, - pub timeout: __wasi_timestamp_t, - pub precision: __wasi_timestamp_t, - pub flags: __wasi_subclockflags_t, -} - -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -#[repr(C)] -pub struct __wasi_subscription_fs_readwrite_t { - pub fd: __wasi_fd_t, -} - -#[derive(Copy, Clone)] -#[repr(C)] -pub union __wasi_subscription_u { - pub clock: __wasi_subscription_clock_t, - pub fd_readwrite: __wasi_subscription_fs_readwrite_t, -} - -#[derive(Copy, Clone)] -#[repr(C)] -pub struct __wasi_subscription_t { - pub userdata: __wasi_userdata_t, - pub type_: __wasi_eventtype_t, - pub u: __wasi_subscription_u, -} - -/// Safe Rust wrapper around `__wasi_subscription_t::type_` and `__wasi_subscription_t::u` -#[derive(Debug, Clone)] -pub enum EventType { - Clock(__wasi_subscription_clock_t), - Read(__wasi_subscription_fs_readwrite_t), - Write(__wasi_subscription_fs_readwrite_t), -} - -impl EventType { - pub fn raw_tag(&self) -> __wasi_eventtype_t { - match self { - EventType::Clock(_) => __WASI_EVENTTYPE_CLOCK, - EventType::Read(_) => __WASI_EVENTTYPE_FD_READ, - EventType::Write(_) => __WASI_EVENTTYPE_FD_WRITE, - } - } -} - -/// Safe Rust wrapper around `__wasi_subscription_t` -#[derive(Debug, Clone)] -pub struct WasiSubscription { - pub user_data: __wasi_userdata_t, - pub event_type: EventType, -} - -impl std::convert::TryFrom<__wasi_subscription_t> for WasiSubscription { - type Error = __wasi_errno_t; - - fn try_from(ws: __wasi_subscription_t) -> Result { - Ok(Self { - user_data: ws.userdata, - event_type: match ws.type_ { - __WASI_EVENTTYPE_CLOCK => EventType::Clock(unsafe { ws.u.clock }), - __WASI_EVENTTYPE_FD_READ => EventType::Read(unsafe { ws.u.fd_readwrite }), - __WASI_EVENTTYPE_FD_WRITE => EventType::Write(unsafe { ws.u.fd_readwrite }), - _ => return Err(__WASI_EINVAL), - }, - }) - } -} - -impl std::convert::TryFrom for __wasi_subscription_t { - type Error = __wasi_errno_t; - - fn try_from(ws: WasiSubscription) -> Result { - let (type_, u) = match ws.event_type { - EventType::Clock(c) => (__WASI_EVENTTYPE_CLOCK, __wasi_subscription_u { clock: c }), - EventType::Read(rw) => ( - __WASI_EVENTTYPE_FD_READ, - __wasi_subscription_u { fd_readwrite: rw }, - ), - EventType::Write(rw) => ( - __WASI_EVENTTYPE_FD_WRITE, - __wasi_subscription_u { fd_readwrite: rw }, - ), - _ => return Err(__WASI_EINVAL), - }; - - Ok(Self { - userdata: ws.user_data, - type_, - u, - }) - } -} - -impl std::fmt::Debug for __wasi_subscription_t { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.debug_struct("__wasi_subscription_t") - .field("userdata", &self.userdata) - .field("type", &eventtype_to_str(self.type_)) - .field( - "u", - match self.type_ { - __WASI_EVENTTYPE_CLOCK => unsafe { &self.u.clock }, - __WASI_EVENTTYPE_FD_READ | __WASI_EVENTTYPE_FD_WRITE => unsafe { - &self.u.fd_readwrite - }, - _ => &"INVALID EVENTTYPE", - }, - ) - .finish() - } -} - -unsafe impl ValueType for __wasi_subscription_t {} - -pub enum SubscriptionEnum { - Clock(__wasi_subscription_clock_t), - FdReadWrite(__wasi_subscription_fs_readwrite_t), -} - -impl __wasi_subscription_t { - pub fn tagged(&self) -> Option { - match self.type_ { - __WASI_EVENTTYPE_CLOCK => Some(SubscriptionEnum::Clock(unsafe { self.u.clock })), - __WASI_EVENTTYPE_FD_READ | __WASI_EVENTTYPE_FD_WRITE => { - Some(SubscriptionEnum::FdReadWrite(unsafe { - self.u.fd_readwrite - })) - } - _ => None, - } - } -} - -pub type __wasi_timestamp_t = u64; - -pub type __wasi_userdata_t = u64; - -pub type __wasi_whence_t = u8; -pub const __WASI_WHENCE_SET: u8 = 0; -pub const __WASI_WHENCE_CUR: u8 = 1; -pub const __WASI_WHENCE_END: u8 = 2; - -pub mod snapshot0 { - use serde::{Deserialize, Serialize}; - pub type __wasi_linkcount_t = u32; - use wasmer::ValueType; - - #[derive(Debug, Copy, Clone, PartialEq, Eq)] - #[repr(C)] - pub struct __wasi_subscription_clock_t { - pub userdata: super::__wasi_userdata_t, - pub clock_id: super::__wasi_clockid_t, - pub timeout: super::__wasi_timestamp_t, - pub precision: super::__wasi_timestamp_t, - pub flags: super::__wasi_subclockflags_t, - } - - #[derive(Copy, Clone)] - #[repr(C)] - pub union __wasi_subscription_u { - pub clock: __wasi_subscription_clock_t, - pub fd_readwrite: super::__wasi_subscription_fs_readwrite_t, - } - - #[derive(Copy, Clone)] - #[repr(C)] - pub struct __wasi_subscription_t { - pub userdata: super::__wasi_userdata_t, - pub type_: super::__wasi_eventtype_t, - pub u: __wasi_subscription_u, - } - - unsafe impl ValueType for __wasi_subscription_t {} - - pub type __wasi_whence_t = u8; - pub const __WASI_WHENCE_CUR: u8 = 0; - pub const __WASI_WHENCE_END: u8 = 1; - pub const __WASI_WHENCE_SET: u8 = 2; - - #[derive(Copy, Clone, PartialEq, Eq, Serialize, Deserialize)] - #[repr(C)] - pub struct __wasi_filestat_t { - pub st_dev: super::__wasi_device_t, - pub st_ino: super::__wasi_inode_t, - pub st_filetype: super::__wasi_filetype_t, - pub st_nlink: __wasi_linkcount_t, - pub st_size: super::__wasi_filesize_t, - pub st_atim: super::__wasi_timestamp_t, - pub st_mtim: super::__wasi_timestamp_t, - pub st_ctim: super::__wasi_timestamp_t, - } - - unsafe impl ValueType for __wasi_filestat_t {} - - impl std::fmt::Debug for __wasi_filestat_t { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let convert_ts_into_time_string = |ts| { - let tspec = - time::Timespec::new(ts as i64 / 1_000_000_000, (ts % 1_000_000_000) as i32); - let tm = time::at(tspec); - let out_time = tm.rfc822(); - format!("{} ({})", out_time, ts) - }; - f.debug_struct("__wasi_filestat_t") - .field("st_dev", &self.st_dev) - .field("st_ino", &self.st_ino) - .field( - "st_filetype", - &format!( - "{} ({})", - super::wasi_filetype_to_name(self.st_filetype), - self.st_filetype, - ), - ) - .field("st_nlink", &self.st_nlink) - .field("st_size", &self.st_size) - .field("st_atim", &convert_ts_into_time_string(self.st_atim)) - .field("st_mtim", &convert_ts_into_time_string(self.st_mtim)) - .field("st_ctim", &convert_ts_into_time_string(self.st_ctim)) - .finish() - } - } - - impl std::fmt::Debug for __wasi_subscription_t { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("__wasi_subscription_t") - .field("userdata", &self.userdata) - .field("type", &super::eventtype_to_str(self.type_)) - .field( - "u", - match self.type_ { - super::__WASI_EVENTTYPE_CLOCK => unsafe { &self.u.clock }, - super::__WASI_EVENTTYPE_FD_READ | super::__WASI_EVENTTYPE_FD_WRITE => unsafe { - &self.u.fd_readwrite - }, - _ => &"INVALID EVENTTYPE", - }, - ) - .finish() - } - } -} diff --git a/scripts/publish.py b/scripts/publish.py index 013d8ed6036..a5da852dcf6 100644 --- a/scripts/publish.py +++ b/scripts/publish.py @@ -43,7 +43,8 @@ "wasmer-compiler-llvm", "wasmer-compiler", "wasmer-engine", "wasmer-engine-universal", "wasmer-engine-dylib", "wasmer-engine-staticlib", "wasmer-types", "wasmer-derive"]), "wasmer-cache": set(["wasmer"]), - "wasmer-wasi": set(["wasmer"]), + "wasmer-wasi": set(["wasmer", "wasmer-wasi-types"]), + "wasmer-wasi-types": set(["wasmer"]), "wasmer-wasi-experimental-io-devices": set(["wasmer-wasi"]), "wasmer-emscripten": set(["wasmer"]), "wasmer-c-api": set(["wasmer", "wasmer-compiler", "wasmer-compiler-cranelift", "wasmer-compiler-singlepass", @@ -71,6 +72,7 @@ "wasmer-cache": "cache", "wasmer": "api", "wasmer-wasi": "wasi", + "wasmer-wasi-types": "wasi-types", "wasmer-emscripten": "emscripten", "wasmer-wasi-experimental-io-devices": "wasi-experimental-io-devices", "wasmer-c-api": "c-api", From 8d737450318bfcab53af019bfa88667f66454429 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Tue, 8 Jun 2021 15:19:05 +0200 Subject: [PATCH 2/5] doc(changelog) Add #2411. --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3b57cb3b4fd..d7b77b96b23 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ Looking for changes that affect our C API? See the [C API Changelog](lib/c-api/C ## 2.0.0-rc2 - 2020/06/03 ### Added +- [#2411](https://github.com/wasmerio/wasmer/pull/2411) Extract types from `wasi` to a new `wasi-types` crate. - [#2390](https://github.com/wasmerio/wasmer/pull/2390) Make `wasmer-vm` to compile on Windows 32bits. - [#2402](https://github.com/wasmerio/wasmer/pull/2402) Add more examples and more doctests for `wasmer-middlewares`. From cfd400853070667073818f5fa3f89c62bf21391a Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Thu, 10 Jun 2021 16:00:59 +0200 Subject: [PATCH 3/5] feat: `wasi-types` does not define `WasmPtr`. --- Cargo.lock | 2 +- lib/wasi-types/Cargo.toml | 2 +- lib/wasi-types/src/directory.rs | 2 +- lib/wasi-types/src/event.rs | 1 + lib/wasi-types/src/file.rs | 2 +- lib/wasi-types/src/io.rs | 7 +++---- lib/wasi-types/src/lib.rs | 2 -- lib/wasi-types/src/subscription.rs | 1 + lib/wasi-types/src/versions/snapshot0.rs | 2 +- lib/wasi/src/lib.rs | 4 +--- lib/{wasi-types => wasi}/src/ptr.rs | 2 +- lib/wasi/src/syscalls/mod.rs | 4 ++-- 12 files changed, 14 insertions(+), 17 deletions(-) rename lib/{wasi-types => wasi}/src/ptr.rs (97%) diff --git a/Cargo.lock b/Cargo.lock index d61f55c6ebc..8c0c1def3f8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2760,7 +2760,7 @@ dependencies = [ "byteorder", "serde", "time", - "wasmer", + "wasmer-types", ] [[package]] diff --git a/lib/wasi-types/Cargo.toml b/lib/wasi-types/Cargo.toml index 67974c60c18..3e1fe2773b2 100644 --- a/lib/wasi-types/Cargo.toml +++ b/lib/wasi-types/Cargo.toml @@ -11,7 +11,7 @@ readme = "README.md" edition = "2018" [dependencies] -wasmer = { path = "../api", version = "2.0.0-rc2" } +wasmer-types = { path = "../types", version = "2.0.0-rc2" } serde = { version = "1.0", features = ["derive"] } byteorder = "1.3" time = "0.1" \ No newline at end of file diff --git a/lib/wasi-types/src/directory.rs b/lib/wasi-types/src/directory.rs index 95aa2c043a9..9275951a20c 100644 --- a/lib/wasi-types/src/directory.rs +++ b/lib/wasi-types/src/directory.rs @@ -1,6 +1,6 @@ use crate::*; use std::mem; -use wasmer::ValueType; +use wasmer_types::ValueType; pub type __wasi_dircookie_t = u64; pub const __WASI_DIRCOOKIE_START: u64 = 0; diff --git a/lib/wasi-types/src/event.rs b/lib/wasi-types/src/event.rs index ad70ce0f0b6..0679f926929 100644 --- a/lib/wasi-types/src/event.rs +++ b/lib/wasi-types/src/event.rs @@ -1,5 +1,6 @@ use crate::*; use std::fmt; +use wasmer_types::ValueType; #[derive(Debug, Copy, Clone, PartialEq, Eq)] #[repr(C)] diff --git a/lib/wasi-types/src/file.rs b/lib/wasi-types/src/file.rs index 0a409ba546b..e79ed46029a 100644 --- a/lib/wasi-types/src/file.rs +++ b/lib/wasi-types/src/file.rs @@ -1,7 +1,7 @@ use crate::*; use serde::{Deserialize, Serialize}; use std::fmt; -use wasmer::ValueType; +use wasmer_types::ValueType; pub type __wasi_device_t = u64; diff --git a/lib/wasi-types/src/io.rs b/lib/wasi-types/src/io.rs index 76d229f9d12..e42ff0e1c38 100644 --- a/lib/wasi-types/src/io.rs +++ b/lib/wasi-types/src/io.rs @@ -1,10 +1,9 @@ -use crate::*; -use wasmer::ValueType; +use wasmer_types::ValueType; #[derive(Debug, Copy, Clone, PartialEq, Eq)] #[repr(C)] pub struct __wasi_ciovec_t { - pub buf: WasmPtr, + pub buf: u32, pub buf_len: u32, } @@ -13,7 +12,7 @@ unsafe impl ValueType for __wasi_ciovec_t {} #[derive(Debug, Copy, Clone, PartialEq, Eq)] #[repr(C)] pub struct __wasi_iovec_t { - pub buf: WasmPtr, + pub buf: u32, pub buf_len: u32, } diff --git a/lib/wasi-types/src/lib.rs b/lib/wasi-types/src/lib.rs index e19e1a2a432..f55de60f921 100644 --- a/lib/wasi-types/src/lib.rs +++ b/lib/wasi-types/src/lib.rs @@ -14,7 +14,6 @@ mod error; mod event; mod file; mod io; -mod ptr; mod signal; mod subscription; mod time; @@ -27,7 +26,6 @@ pub use error::*; pub use event::*; pub use file::*; pub use io::*; -pub use ptr::*; pub use signal::*; pub use subscription::*; pub use versions::*; diff --git a/lib/wasi-types/src/subscription.rs b/lib/wasi-types/src/subscription.rs index c8265bcc13a..bd7d3c2c85e 100644 --- a/lib/wasi-types/src/subscription.rs +++ b/lib/wasi-types/src/subscription.rs @@ -1,6 +1,7 @@ use crate::*; use std::convert::TryFrom; use std::fmt; +use wasmer_types::ValueType; pub type __wasi_subclockflags_t = u16; pub const __WASI_SUBSCRIPTION_CLOCK_ABSTIME: u16 = 1 << 0; diff --git a/lib/wasi-types/src/versions/snapshot0.rs b/lib/wasi-types/src/versions/snapshot0.rs index 8dd747d6058..b5d6af3ee64 100644 --- a/lib/wasi-types/src/versions/snapshot0.rs +++ b/lib/wasi-types/src/versions/snapshot0.rs @@ -1,7 +1,7 @@ use crate::*; use serde::{Deserialize, Serialize}; use std::fmt; -use wasmer::ValueType; +use wasmer_types::ValueType; pub type __wasi_linkcount_t = u32; diff --git a/lib/wasi/src/lib.rs b/lib/wasi/src/lib.rs index 9c595ecdbe7..181f485b982 100644 --- a/lib/wasi/src/lib.rs +++ b/lib/wasi/src/lib.rs @@ -14,9 +14,7 @@ #[macro_use] mod macros; -mod ptr { - pub use wasmer_wasi_types::{Array, WasmPtr}; -} +mod ptr; mod state; mod syscalls; mod utils; diff --git a/lib/wasi-types/src/ptr.rs b/lib/wasi/src/ptr.rs similarity index 97% rename from lib/wasi-types/src/ptr.rs rename to lib/wasi/src/ptr.rs index 87ad3b76a59..4d5ca86a8e0 100644 --- a/lib/wasi-types/src/ptr.rs +++ b/lib/wasi/src/ptr.rs @@ -1,7 +1,7 @@ //! This is a wrapper around the `WasmPtr` abstraction that returns __WASI_EFAULT //! if memory access failed -use crate::{__wasi_errno_t, __WASI_EFAULT}; +use crate::syscalls::types::{__wasi_errno_t, __WASI_EFAULT}; use std::{cell::Cell, fmt}; pub use wasmer::{Array, FromToNativeWasmType, Item, Memory, ValueType, WasmPtr as BaseWasmPtr}; diff --git a/lib/wasi/src/syscalls/mod.rs b/lib/wasi/src/syscalls/mod.rs index a8855221a68..58413a6933c 100644 --- a/lib/wasi/src/syscalls/mod.rs +++ b/lib/wasi/src/syscalls/mod.rs @@ -52,7 +52,7 @@ fn write_bytes_inner( let mut bytes_written = 0; for iov in iovs_arr_cell { let iov_inner = iov.get(); - let bytes = iov_inner.buf.deref(memory, 0, iov_inner.buf_len)?; + let bytes = WasmPtr::::new(iov_inner.buf).deref(memory, 0, iov_inner.buf_len)?; write_loc .write_all(&bytes.iter().map(|b_cell| b_cell.get()).collect::>()) .map_err(|_| __WASI_EIO)?; @@ -82,7 +82,7 @@ fn read_bytes( for iov in iovs_arr_cell { let iov_inner = iov.get(); - let bytes = iov_inner.buf.deref(memory, 0, iov_inner.buf_len)?; + let bytes = WasmPtr::::new(iov_inner.buf).deref(memory, 0, iov_inner.buf_len)?; let mut raw_bytes: &mut [u8] = unsafe { &mut *(bytes as *const [_] as *mut [_] as *mut [u8]) }; bytes_read += reader.read(raw_bytes).map_err(|_| __WASI_EIO)? as u32; From c32eb619ff0fc77c433dc5f7a63146c8a445a0e2 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Thu, 10 Jun 2021 16:06:49 +0200 Subject: [PATCH 4/5] chore: Remove unused function. --- lib/wasi/src/ptr.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/lib/wasi/src/ptr.rs b/lib/wasi/src/ptr.rs index 4d5ca86a8e0..7f739f27c19 100644 --- a/lib/wasi/src/ptr.rs +++ b/lib/wasi/src/ptr.rs @@ -83,9 +83,4 @@ impl WasmPtr { pub unsafe fn get_utf8_str(self, memory: &Memory, str_len: u32) -> Option<&str> { self.0.get_utf8_str(memory, str_len) } - - #[inline(always)] - pub fn get_utf8_string(self, memory: &Memory, str_len: u32) -> Option { - self.0.get_utf8_string(memory, str_len) - } } From a8d0e11a6f2c935c6ad897fcbcda8c128754067e Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Thu, 10 Jun 2021 16:45:22 +0200 Subject: [PATCH 5/5] chore: `wasmer-wasi-types` depends on `wasmer-types`. --- scripts/publish.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/publish.py b/scripts/publish.py index a5da852dcf6..9d9411fdc77 100644 --- a/scripts/publish.py +++ b/scripts/publish.py @@ -44,7 +44,7 @@ "wasmer-engine-dylib", "wasmer-engine-staticlib", "wasmer-types", "wasmer-derive"]), "wasmer-cache": set(["wasmer"]), "wasmer-wasi": set(["wasmer", "wasmer-wasi-types"]), - "wasmer-wasi-types": set(["wasmer"]), + "wasmer-wasi-types": set(["wasmer-types"]), "wasmer-wasi-experimental-io-devices": set(["wasmer-wasi"]), "wasmer-emscripten": set(["wasmer"]), "wasmer-c-api": set(["wasmer", "wasmer-compiler", "wasmer-compiler-cranelift", "wasmer-compiler-singlepass",