Skip to content

Commit b06b9ec

Browse files
bors[bot]lachlansneffMark McCaskeyMarkMcCaskey
committed
Merge #299
299: Support for the WASI ABI. r=xmclark a=lachlansneff part of #297 Co-authored-by: Lachlan Sneff <[email protected]> Co-authored-by: Mark McCaskey <[email protected]> Co-authored-by: bors[bot] <bors[bot]@users.noreply.github.com> Co-authored-by: Mark McCaskey <[email protected]>
2 parents 0d8a190 + bbf663a commit b06b9ec

20 files changed

+2788
-260
lines changed

Diff for: Cargo.lock

+223-199
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: Cargo.toml

+3-1
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,10 @@ wasmer-runtime-abi = { path = "lib/runtime-abi", optional = true }
3030
wasmer-runtime-core = { path = "lib/runtime-core" }
3131
wasmer-emscripten = { path = "lib/emscripten" }
3232
wasmer-llvm-backend = { path = "lib/llvm-backend", optional = true }
33+
wasmer-wasi = { path = "lib/wasi", optional = true }
3334

3435
[workspace]
35-
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"]
36+
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"]
3637

3738
[build-dependencies]
3839
wabt = "0.7.2"
@@ -45,4 +46,5 @@ debug = ["wasmer-clif-backend/debug", "wasmer-runtime-core/debug"]
4546
fast-tests = []
4647
llvm = ["wasmer-llvm-backend"]
4748
dynasm = ["wasmer-dynasm-backend"]
49+
wasi = ["wasmer-wasi"]
4850
vfs = ["wasmer-runtime-abi"]

Diff for: lib/runtime-core/src/error.rs

+26-3
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,6 @@ impl std::error::Error for LinkError {}
119119
/// The main way to do this is `Instance.call`.
120120
///
121121
/// Comparing two `RuntimeError`s always evaluates to false.
122-
#[derive(Debug)]
123122
pub enum RuntimeError {
124123
Trap { msg: Box<str> },
125124
Exception { data: Box<[Value]> },
@@ -141,11 +140,27 @@ impl std::fmt::Display for RuntimeError {
141140
RuntimeError::Exception { ref data } => {
142141
write!(f, "Uncaught WebAssembly exception: {:?}", data)
143142
}
144-
RuntimeError::Panic { data: _ } => write!(f, "User-defined \"panic\""),
143+
RuntimeError::Panic { data } => {
144+
let msg = if let Some(s) = data.downcast_ref::<String>() {
145+
s
146+
} else if let Some(s) = data.downcast_ref::<&str>() {
147+
s
148+
} else {
149+
"user-defined, opaque"
150+
};
151+
152+
write!(f, "{}", msg)
153+
}
145154
}
146155
}
147156
}
148157

158+
impl std::fmt::Debug for RuntimeError {
159+
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
160+
write!(f, "{}", self)
161+
}
162+
}
163+
149164
impl std::error::Error for RuntimeError {}
150165

151166
/// This error type is produced by resolving a wasm function
@@ -197,7 +212,6 @@ impl std::error::Error for ResolveError {}
197212
/// be the `CallError::Runtime(RuntimeError)` variant.
198213
///
199214
/// Comparing two `CallError`s always evaluates to false.
200-
#[derive(Debug)]
201215
pub enum CallError {
202216
Resolve(ResolveError),
203217
Runtime(RuntimeError),
@@ -218,6 +232,15 @@ impl std::fmt::Display for CallError {
218232
}
219233
}
220234

235+
impl std::fmt::Debug for CallError {
236+
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
237+
match self {
238+
CallError::Resolve(resolve_err) => write!(f, "ResolveError: {:?}", resolve_err),
239+
CallError::Runtime(runtime_err) => write!(f, "RuntimeError: {:?}", runtime_err),
240+
}
241+
}
242+
}
243+
221244
impl std::error::Error for CallError {}
222245

223246
/// This error type is produced when creating something,

Diff for: lib/runtime-core/src/import.rs

+18
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use hashbrown::{hash_map::Entry, HashMap};
33
use std::collections::VecDeque;
44
use std::{
55
cell::{Ref, RefCell},
6+
ffi::c_void,
67
rc::Rc,
78
};
89

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

5052
impl ImportObject {
5153
/// Create a new `ImportObject`.
5254
pub fn new() -> Self {
5355
Self {
5456
map: Rc::new(RefCell::new(HashMap::new())),
57+
state_creator: None,
5558
}
5659
}
5760

61+
pub fn new_with_data<F>(state_creator: F) -> Self
62+
where
63+
F: Fn() -> (*mut c_void, fn(*mut c_void)) + 'static,
64+
{
65+
Self {
66+
map: Rc::new(RefCell::new(HashMap::new())),
67+
state_creator: Some(Rc::new(state_creator)),
68+
}
69+
}
70+
71+
pub(crate) fn call_state_creator(&self) -> Option<(*mut c_void, fn(*mut c_void))> {
72+
self.state_creator.as_ref().map(|state_gen| state_gen())
73+
}
74+
5875
/// Register anything that implements `LikeNamespace` as a namespace.
5976
///
6077
/// # Usage:
@@ -98,6 +115,7 @@ impl ImportObject {
98115
pub fn clone_ref(&self) -> Self {
99116
Self {
100117
map: Rc::clone(&self.map),
118+
state_creator: self.state_creator.clone(),
101119
}
102120
}
103121

Diff for: lib/runtime-core/src/instance.rs

+10-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,16 @@ impl Instance {
6363
// Initialize the vm::Ctx in-place after the backing
6464
// has been boxed.
6565
unsafe {
66-
*inner.vmctx = vm::Ctx::new(&mut inner.backing, &mut inner.import_backing, &module)
66+
*inner.vmctx = match imports.call_state_creator() {
67+
Some((data, dtor)) => vm::Ctx::new_with_data(
68+
&mut inner.backing,
69+
&mut inner.import_backing,
70+
&module,
71+
data,
72+
dtor,
73+
),
74+
None => vm::Ctx::new(&mut inner.backing, &mut inner.import_backing, &module),
75+
};
6776
};
6877

6978
let instance = Instance {

Diff for: lib/runtime-core/src/macros.rs

+22
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,13 @@ macro_rules! func {
3838
/// },
3939
/// };
4040
///
41+
/// let imports_with_state = imports! {
42+
/// || (0 as _, |_a| {}),
43+
/// "env" => {
44+
/// "foo" => func!(foo),
45+
/// },
46+
/// };
47+
///
4148
/// fn foo(_: &mut Ctx, n: i32) -> i32 {
4249
/// n
4350
/// }
@@ -57,6 +64,21 @@ macro_rules! imports {
5764
import_object.register($ns_name, ns);
5865
})*
5966

67+
import_object
68+
}};
69+
($state_gen:expr, $( $ns_name:expr => $ns:tt, )* ) => {{
70+
use $crate::{
71+
import::{ImportObject, Namespace},
72+
};
73+
74+
let mut import_object = ImportObject::new_with_data($state_gen);
75+
76+
$({
77+
let ns = $crate::__imports_internal!($ns);
78+
79+
import_object.register($ns_name, ns);
80+
})*
81+
6082
import_object
6183
}};
6284
}

Diff for: lib/runtime-core/src/types.rs

+16-40
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,19 @@ where
7777
{
7878
const TYPE: Type;
7979
}
80+
81+
unsafe impl WasmExternType for i8 {
82+
const TYPE: Type = Type::I32;
83+
}
84+
unsafe impl WasmExternType for u8 {
85+
const TYPE: Type = Type::I32;
86+
}
87+
unsafe impl WasmExternType for i16 {
88+
const TYPE: Type = Type::I32;
89+
}
90+
unsafe impl WasmExternType for u16 {
91+
const TYPE: Type = Type::I32;
92+
}
8093
unsafe impl WasmExternType for i32 {
8194
const TYPE: Type = Type::I32;
8295
}
@@ -113,34 +126,15 @@ unsafe impl WasmExternType for f64 {
113126
// fn swap(&self, other: Self::Primitive) -> Self::Primitive;
114127
// }
115128

116-
pub enum ValueError {
117-
BufferTooSmall,
118-
}
119-
120-
pub trait ValueType: Copy
129+
pub unsafe trait ValueType: Copy
121130
where
122131
Self: Sized,
123132
{
124-
fn into_le(self, buffer: &mut [u8]);
125-
fn from_le(buffer: &[u8]) -> Result<Self, ValueError>;
126133
}
127134

128135
macro_rules! convert_value_impl {
129136
($t:ty) => {
130-
impl ValueType for $t {
131-
fn into_le(self, buffer: &mut [u8]) {
132-
buffer[..mem::size_of::<Self>()].copy_from_slice(&self.to_le_bytes());
133-
}
134-
fn from_le(buffer: &[u8]) -> Result<Self, ValueError> {
135-
if buffer.len() >= mem::size_of::<Self>() {
136-
let mut array = [0u8; mem::size_of::<Self>()];
137-
array.copy_from_slice(&buffer[..mem::size_of::<Self>()]);
138-
Ok(Self::from_le_bytes(array))
139-
} else {
140-
Err(ValueError::BufferTooSmall)
141-
}
142-
}
143-
}
137+
unsafe impl ValueType for $t {}
144138
};
145139
( $($t:ty),* ) => {
146140
$(
@@ -149,25 +143,7 @@ macro_rules! convert_value_impl {
149143
};
150144
}
151145

152-
convert_value_impl!(u8, i8, u16, i16, u32, i32, u64, i64);
153-
154-
impl ValueType for f32 {
155-
fn into_le(self, buffer: &mut [u8]) {
156-
self.to_bits().into_le(buffer);
157-
}
158-
fn from_le(buffer: &[u8]) -> Result<Self, ValueError> {
159-
Ok(f32::from_bits(<u32 as ValueType>::from_le(buffer)?))
160-
}
161-
}
162-
163-
impl ValueType for f64 {
164-
fn into_le(self, buffer: &mut [u8]) {
165-
self.to_bits().into_le(buffer);
166-
}
167-
fn from_le(buffer: &[u8]) -> Result<Self, ValueError> {
168-
Ok(f64::from_bits(<u64 as ValueType>::from_le(buffer)?))
169-
}
170-
}
146+
convert_value_impl!(u8, i8, u16, i16, u32, i32, u64, i64, f32, f64);
171147

172148
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq)]
173149
pub enum ElementType {

Diff for: lib/runtime-core/src/vm.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ pub struct Ctx {
2525
module: *const ModuleInner,
2626

2727
pub data: *mut c_void,
28-
pub data_finalizer: Option<extern "C" fn(data: *mut c_void)>,
28+
pub data_finalizer: Option<fn(data: *mut c_void)>,
2929
}
3030

3131
/// The internal context of the currently running WebAssembly instance.
@@ -100,7 +100,7 @@ impl Ctx {
100100
import_backing: &mut ImportBacking,
101101
module: &ModuleInner,
102102
data: *mut c_void,
103-
data_finalizer: extern "C" fn(*mut c_void),
103+
data_finalizer: fn(*mut c_void),
104104
) -> Self {
105105
Self {
106106
internal: InternalCtx {
@@ -481,7 +481,7 @@ mod vm_ctx_tests {
481481
str: String,
482482
}
483483

484-
extern "C" fn test_data_finalizer(data: *mut c_void) {
484+
fn test_data_finalizer(data: *mut c_void) {
485485
let test_data: &mut TestData = unsafe { &mut *(data as *mut TestData) };
486486
assert_eq!(test_data.x, 10);
487487
assert_eq!(test_data.y, true);

Diff for: lib/wasi/Cargo.toml

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
[package]
2+
name = "wasmer-wasi"
3+
version = "0.2.1"
4+
license = "MIT"
5+
authors = ["The Wasmer Engineering Team <[email protected]>"]
6+
repository = "https://github.com/wasmerio/wasmer"
7+
edition = "2018"
8+
9+
[dependencies]
10+
wasmer-runtime-core = { path = "../runtime-core", version = "0.2.1" }
11+
libc = "0.2.50"
12+
rand = "0.6.5"
13+
# wasmer-runtime-abi = { path = "../runtime-abi" }
14+
hashbrown = "0.1.8"
15+
generational-arena = "0.2.2"
16+
log = "0.4.6"
17+
byteorder = "1.3.1"
18+
19+
[dependencies.zbox]
20+
git = "https://github.com/wasmerio/zbox"
21+
branch = "bundle-libsodium"
22+
features = ["libsodium-bundled"]

0 commit comments

Comments
 (0)