Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for the WASI ABI. #299

Merged
merged 92 commits into from
Apr 4, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
92 commits
Select commit Hold shift + click to select a range
be08154
Add wasi crate
lachlansneff Mar 28, 2019
0787d00
Add data support to import macro
lachlansneff Mar 28, 2019
e3a6b7c
Add skeleton for wasi abi
lachlansneff Mar 28, 2019
b7254ce
add stubs and dispatch
Mar 28, 2019
7b0992e
Instance now pulls state from the ImportObject
lachlansneff Mar 28, 2019
c045da3
Merge branch 'feature/wasi' of github.com:wasmerio/wasmer into featur…
lachlansneff Mar 28, 2019
94674e9
Add wasi state
lachlansneff Mar 28, 2019
bc863fc
hook up wasi to wasmer
Mar 28, 2019
72dd995
fix typo
Mar 28, 2019
dbc4176
Add env and args syscalls
lachlansneff Mar 28, 2019
256253a
Fix clippy lint
lachlansneff Mar 28, 2019
3c01c11
pass args and env vars to wasi
Mar 28, 2019
a69fdfe
implement wasi check
Mar 28, 2019
5c12fd0
fix test
Mar 28, 2019
e227b89
Merge #301
bors[bot] Mar 28, 2019
21304cb
Merge branch 'feature/wasi' into feature/hook-up-wasi-to-wasmer
MarkMcCaskey Mar 28, 2019
ce22818
add feature gate on import
Mar 28, 2019
3323c3c
Merge #300
bors[bot] Mar 28, 2019
bde6bdf
Add all wasi types
lachlansneff Mar 28, 2019
79133e5
Merge #303
bors[bot] Mar 28, 2019
aed9d3b
remove __wasi_ prefix
Mar 28, 2019
2982e6e
Merge #304
bors[bot] Mar 28, 2019
46f90d3
fix conditional compliation
Mar 28, 2019
9478ba7
actually fix it
Mar 28, 2019
72ec4ab
Merge #305
bors[bot] Mar 28, 2019
c45de22
Add helper types and half-ish of the wasi signatures
lachlansneff Mar 29, 2019
bd09343
add structure for cross-platform wasi syscall implementations
Mar 29, 2019
90db12e
Finish up signatures and converting function types
lachlansneff Mar 29, 2019
d9b89b4
Fix bug in deref of WasmPtr<T, Array>
lachlansneff Mar 29, 2019
39ccf40
Merge #306
bors[bot] Mar 29, 2019
ea27eff
keeep top level wasi calls that call out to platform-specific impls
Mar 29, 2019
d10d028
Merge branch 'feature/wasi' into feature/wasi-cross-platform-skeleton
MarkMcCaskey Mar 29, 2019
514432c
call wasi files correctly
Mar 29, 2019
b1030d3
Add prestat_t
lachlansneff Mar 29, 2019
4df5f02
Merge branch 'feature/wasi' of github.com:wasmerio/wasmer into featur…
lachlansneff Mar 29, 2019
23c09ac
add imports
Mar 29, 2019
48b5918
Merge branch 'master' into feature/wasi-fs
lachlansneff Mar 29, 2019
48d34d9
improve calling of platform-specific code and impl linux clock calls
Mar 29, 2019
de241a0
fix linux impl bugs
Mar 29, 2019
1f8b90b
probably actually fix linux for real though
Mar 29, 2019
28d9d1f
move linux impl to unix (it works on osx too!)
Mar 29, 2019
88212d3
implement random_get()
Mar 29, 2019
35fbf57
add pread on linux
Mar 29, 2019
5dcb95d
fix basic errors in linux impl
Mar 29, 2019
e7a5c01
fix backward enumerate
Mar 29, 2019
147d71a
implement ValueType for prestat_t
Mar 29, 2019
42e8523
impl ValueType for fdstat_t
Mar 29, 2019
5cee576
add some syscall skeletons; context switching
Mar 30, 2019
e156ea2
comment out write logic in linux fd_pread until design discussion
Mar 30, 2019
4108c8f
Merge pull request #307 from wasmerio/feature/wasi-cross-platform-ske…
MarkMcCaskey Apr 1, 2019
7addd92
add more stubs for fs calls
Apr 1, 2019
5b6856d
add lots of doc comments
Apr 1, 2019
68f1123
Add start of wasi fs
lachlansneff Apr 1, 2019
c12c7d5
Merge branch 'feature/wasi-fs' into feature/wasi
lachlansneff Apr 1, 2019
61dd2e1
add more doc comments
Apr 1, 2019
ce35e57
Change ValueType trait and add basic fs
lachlansneff Apr 1, 2019
23b1d1d
Merge branch 'feature/wasi' of github.com:wasmerio/wasmer into featur…
lachlansneff Apr 1, 2019
92ec719
Add wasi_try macro
lachlansneff Apr 1, 2019
2dd7ec8
fix it up
Apr 1, 2019
84dc20a
Merge branch 'feature/wasi' of github.com:wasmerio/wasmer into featur…
Apr 1, 2019
d164c7a
update wasi Cargo.toml
Apr 2, 2019
8bab9f1
init zbox first
lachlansneff Apr 2, 2019
287c81d
Misc fixes
lachlansneff Apr 2, 2019
6cec356
add debug lines to all wasi syscalls
Apr 2, 2019
4356293
get debug statements working; add some extra info
Apr 2, 2019
d421e91
implement some of fd_prestat_get
Apr 2, 2019
242f9f6
add hacked together impl of write for stdout and stderr
Apr 2, 2019
3a6e2c9
Change tagged and untagged methods
lachlansneff Apr 2, 2019
6278ced
implement fd_write for files
Apr 2, 2019
04a8073
Merge branch 'feature/wasi' of github.com:wasmerio/wasmer into featur…
Apr 2, 2019
a4547e3
update cursor in file when writing to it
Apr 2, 2019
0b9fc5a
add null termination to args for wasi
Apr 2, 2019
e61c03a
impl fd_read (untested)
Apr 2, 2019
2de5a5d
implement datasync
Apr 2, 2019
e180fd1
add set_rights syscall
Apr 2, 2019
fe4195f
impl set_flags on fd
Apr 2, 2019
697bdc7
add rights checking fn for future-proofing reasons
Apr 2, 2019
37371eb
implement most of fd_filestat_set_times
Apr 2, 2019
7d07b6f
impl fd_seek
Apr 2, 2019
dd7cfac
implement fd_tell
Apr 2, 2019
ce4676d
implement fd_renumber
Apr 2, 2019
f70b75e
kind of implement fd_pwrite
Apr 2, 2019
b80dd07
implement happy path of fd_open
Apr 3, 2019
7d728fc
implement path_filestat_get
Apr 3, 2019
d04d1bf
improve debug statements for arg syscalls
Apr 3, 2019
10696c4
clean up platform-specific syscall code
Apr 3, 2019
e9e7a33
fix warnings and let it build on windows
xmclark Apr 3, 2019
3b34ea6
Merge remote-tracking branch 'origin/feature/wasi' into feature/wasi
xmclark Apr 3, 2019
c1c99db
rename fs and fix (probable) bug in renumber syscall
Apr 4, 2019
207bd01
rename to destructor
xmclark Apr 4, 2019
2686322
Merge remote-tracking branch 'origin/feature/wasi' into feature/wasi
xmclark Apr 4, 2019
bbf663a
Merge branch 'master' into feature/wasi
xmclark Apr 4, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
422 changes: 223 additions & 199 deletions Cargo.lock

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,10 @@ wasmer-runtime-abi = { path = "lib/runtime-abi", optional = true }
wasmer-runtime-core = { path = "lib/runtime-core" }
wasmer-emscripten = { path = "lib/emscripten" }
wasmer-llvm-backend = { path = "lib/llvm-backend", optional = true }
wasmer-wasi = { path = "lib/wasi", optional = true }

[workspace]
members = ["lib/clif-backend", "lib/dynasm-backend", "lib/runtime", "lib/runtime-abi", "lib/runtime-core", "lib/emscripten", "lib/spectests", "lib/win-exception-handler", "lib/runtime-c-api", "lib/llvm-backend"]
members = ["lib/clif-backend", "lib/dynasm-backend", "lib/runtime", "lib/runtime-abi", "lib/runtime-core", "lib/emscripten", "lib/spectests", "lib/win-exception-handler", "lib/runtime-c-api", "lib/llvm-backend", "lib/wasi"]

[build-dependencies]
wabt = "0.7.2"
Expand All @@ -45,4 +46,5 @@ debug = ["wasmer-clif-backend/debug", "wasmer-runtime-core/debug"]
fast-tests = []
llvm = ["wasmer-llvm-backend"]
dynasm = ["wasmer-dynasm-backend"]
wasi = ["wasmer-wasi"]
vfs = ["wasmer-runtime-abi"]
29 changes: 26 additions & 3 deletions lib/runtime-core/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,6 @@ impl std::error::Error for LinkError {}
/// The main way to do this is `Instance.call`.
///
/// Comparing two `RuntimeError`s always evaluates to false.
#[derive(Debug)]
pub enum RuntimeError {
Trap { msg: Box<str> },
Exception { data: Box<[Value]> },
Expand All @@ -141,11 +140,27 @@ impl std::fmt::Display for RuntimeError {
RuntimeError::Exception { ref data } => {
write!(f, "Uncaught WebAssembly exception: {:?}", data)
}
RuntimeError::Panic { data: _ } => write!(f, "User-defined \"panic\""),
RuntimeError::Panic { data } => {
let msg = if let Some(s) = data.downcast_ref::<String>() {
s
} else if let Some(s) = data.downcast_ref::<&str>() {
s
} else {
"user-defined, opaque"
};

write!(f, "{}", msg)
}
}
}
}

impl std::fmt::Debug for RuntimeError {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{}", self)
}
}

impl std::error::Error for RuntimeError {}

/// This error type is produced by resolving a wasm function
Expand Down Expand Up @@ -197,7 +212,6 @@ impl std::error::Error for ResolveError {}
/// be the `CallError::Runtime(RuntimeError)` variant.
///
/// Comparing two `CallError`s always evaluates to false.
#[derive(Debug)]
pub enum CallError {
Resolve(ResolveError),
Runtime(RuntimeError),
Expand All @@ -218,6 +232,15 @@ impl std::fmt::Display for CallError {
}
}

impl std::fmt::Debug for CallError {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
CallError::Resolve(resolve_err) => write!(f, "ResolveError: {:?}", resolve_err),
CallError::Runtime(runtime_err) => write!(f, "RuntimeError: {:?}", runtime_err),
}
}
}

impl std::error::Error for CallError {}

/// This error type is produced when creating something,
Expand Down
18 changes: 18 additions & 0 deletions lib/runtime-core/src/import.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use hashbrown::{hash_map::Entry, HashMap};
use std::collections::VecDeque;
use std::{
cell::{Ref, RefCell},
ffi::c_void,
rc::Rc,
};

Expand Down Expand Up @@ -45,16 +46,32 @@ impl IsExport for Export {
/// ```
pub struct ImportObject {
map: Rc<RefCell<HashMap<String, Box<dyn LikeNamespace>>>>,
state_creator: Option<Rc<Fn() -> (*mut c_void, fn(*mut c_void))>>,
}

impl ImportObject {
/// Create a new `ImportObject`.
pub fn new() -> Self {
Self {
map: Rc::new(RefCell::new(HashMap::new())),
state_creator: None,
}
}

pub fn new_with_data<F>(state_creator: F) -> Self
where
F: Fn() -> (*mut c_void, fn(*mut c_void)) + 'static,
{
Self {
map: Rc::new(RefCell::new(HashMap::new())),
state_creator: Some(Rc::new(state_creator)),
}
}

pub(crate) fn call_state_creator(&self) -> Option<(*mut c_void, fn(*mut c_void))> {
self.state_creator.as_ref().map(|state_gen| state_gen())
}

/// Register anything that implements `LikeNamespace` as a namespace.
///
/// # Usage:
Expand Down Expand Up @@ -98,6 +115,7 @@ impl ImportObject {
pub fn clone_ref(&self) -> Self {
Self {
map: Rc::clone(&self.map),
state_creator: self.state_creator.clone(),
}
}

Expand Down
11 changes: 10 additions & 1 deletion lib/runtime-core/src/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,16 @@ impl Instance {
// Initialize the vm::Ctx in-place after the backing
// has been boxed.
unsafe {
*inner.vmctx = vm::Ctx::new(&mut inner.backing, &mut inner.import_backing, &module)
*inner.vmctx = match imports.call_state_creator() {
Some((data, dtor)) => vm::Ctx::new_with_data(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dtor? maybe destructor or finalizer?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, either of those is fine. dtor was just short and it's common in the c++ world.

&mut inner.backing,
&mut inner.import_backing,
&module,
data,
dtor,
),
None => vm::Ctx::new(&mut inner.backing, &mut inner.import_backing, &module),
};
};

let instance = Instance {
Expand Down
22 changes: 22 additions & 0 deletions lib/runtime-core/src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,13 @@ macro_rules! func {
/// },
/// };
///
/// let imports_with_state = imports! {
/// || (0 as _, |_a| {}),
/// "env" => {
/// "foo" => func!(foo),
/// },
/// };
///
/// fn foo(_: &mut Ctx, n: i32) -> i32 {
/// n
/// }
Expand All @@ -57,6 +64,21 @@ macro_rules! imports {
import_object.register($ns_name, ns);
})*

import_object
}};
($state_gen:expr, $( $ns_name:expr => $ns:tt, )* ) => {{
use $crate::{
import::{ImportObject, Namespace},
};

let mut import_object = ImportObject::new_with_data($state_gen);

$({
let ns = $crate::__imports_internal!($ns);

import_object.register($ns_name, ns);
})*

import_object
}};
}
Expand Down
56 changes: 16 additions & 40 deletions lib/runtime-core/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,19 @@ where
{
const TYPE: Type;
}

unsafe impl WasmExternType for i8 {
const TYPE: Type = Type::I32;
}
unsafe impl WasmExternType for u8 {
const TYPE: Type = Type::I32;
}
unsafe impl WasmExternType for i16 {
const TYPE: Type = Type::I32;
}
unsafe impl WasmExternType for u16 {
const TYPE: Type = Type::I32;
}
unsafe impl WasmExternType for i32 {
const TYPE: Type = Type::I32;
}
Expand Down Expand Up @@ -113,34 +126,15 @@ unsafe impl WasmExternType for f64 {
// fn swap(&self, other: Self::Primitive) -> Self::Primitive;
// }

pub enum ValueError {
BufferTooSmall,
}

pub trait ValueType: Copy
pub unsafe trait ValueType: Copy
where
Self: Sized,
{
fn into_le(self, buffer: &mut [u8]);
fn from_le(buffer: &[u8]) -> Result<Self, ValueError>;
}

macro_rules! convert_value_impl {
($t:ty) => {
impl ValueType for $t {
fn into_le(self, buffer: &mut [u8]) {
buffer[..mem::size_of::<Self>()].copy_from_slice(&self.to_le_bytes());
}
fn from_le(buffer: &[u8]) -> Result<Self, ValueError> {
if buffer.len() >= mem::size_of::<Self>() {
let mut array = [0u8; mem::size_of::<Self>()];
array.copy_from_slice(&buffer[..mem::size_of::<Self>()]);
Ok(Self::from_le_bytes(array))
} else {
Err(ValueError::BufferTooSmall)
}
}
}
unsafe impl ValueType for $t {}
};
( $($t:ty),* ) => {
$(
Expand All @@ -149,25 +143,7 @@ macro_rules! convert_value_impl {
};
}

convert_value_impl!(u8, i8, u16, i16, u32, i32, u64, i64);

impl ValueType for f32 {
fn into_le(self, buffer: &mut [u8]) {
self.to_bits().into_le(buffer);
}
fn from_le(buffer: &[u8]) -> Result<Self, ValueError> {
Ok(f32::from_bits(<u32 as ValueType>::from_le(buffer)?))
}
}

impl ValueType for f64 {
fn into_le(self, buffer: &mut [u8]) {
self.to_bits().into_le(buffer);
}
fn from_le(buffer: &[u8]) -> Result<Self, ValueError> {
Ok(f64::from_bits(<u64 as ValueType>::from_le(buffer)?))
}
}
convert_value_impl!(u8, i8, u16, i16, u32, i32, u64, i64, f32, f64);

#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq)]
pub enum ElementType {
Expand Down
6 changes: 3 additions & 3 deletions lib/runtime-core/src/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ pub struct Ctx {
module: *const ModuleInner,

pub data: *mut c_void,
pub data_finalizer: Option<extern "C" fn(data: *mut c_void)>,
pub data_finalizer: Option<fn(data: *mut c_void)>,
}

/// The internal context of the currently running WebAssembly instance.
Expand Down Expand Up @@ -100,7 +100,7 @@ impl Ctx {
import_backing: &mut ImportBacking,
module: &ModuleInner,
data: *mut c_void,
data_finalizer: extern "C" fn(*mut c_void),
data_finalizer: fn(*mut c_void),
) -> Self {
Self {
internal: InternalCtx {
Expand Down Expand Up @@ -481,7 +481,7 @@ mod vm_ctx_tests {
str: String,
}

extern "C" fn test_data_finalizer(data: *mut c_void) {
fn test_data_finalizer(data: *mut c_void) {
let test_data: &mut TestData = unsafe { &mut *(data as *mut TestData) };
assert_eq!(test_data.x, 10);
assert_eq!(test_data.y, true);
Expand Down
22 changes: 22 additions & 0 deletions lib/wasi/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[package]
name = "wasmer-wasi"
version = "0.2.1"
license = "MIT"
authors = ["The Wasmer Engineering Team <[email protected]>"]
repository = "https://github.com/wasmerio/wasmer"
edition = "2018"

[dependencies]
wasmer-runtime-core = { path = "../runtime-core", version = "0.2.1" }
libc = "0.2.50"
rand = "0.6.5"
# wasmer-runtime-abi = { path = "../runtime-abi" }
hashbrown = "0.1.8"
generational-arena = "0.2.2"
log = "0.4.6"
byteorder = "1.3.1"

[dependencies.zbox]
git = "https://github.com/wasmerio/zbox"
branch = "bundle-libsodium"
features = ["libsodium-bundled"]
Loading