From 56a3a6d7ff8c265d7813b9dc153b95b58777c291 Mon Sep 17 00:00:00 2001 From: Manos Pitsidianakis Date: Fri, 24 Jun 2022 12:30:15 +0300 Subject: [PATCH 1/3] lib/c-api: update cbindgen dependency --- Cargo.lock | 68 +++++++++++++++++++++++++++++++++++++------- lib/c-api/Cargo.toml | 2 +- 2 files changed, 59 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6ed8a3404bd..26b7f0fb2b8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -149,7 +149,7 @@ dependencies = [ "bitflags", "cexpr", "clang-sys", - "clap", + "clap 2.34.0", "env_logger", "lazy_static", "lazycell", @@ -269,12 +269,12 @@ dependencies = [ [[package]] name = "cbindgen" -version = "0.19.0" +version = "0.24.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38728c31b994e4b849cf59feefb4a8bf26acd299ee0b92c9fb35bd14ad4b8dfa" +checksum = "a6358dedf60f4d9b8db43ad187391afe959746101346fe51bb978126bec61dfb" dependencies = [ - "clap", - "heck", + "clap 3.2.6", + "heck 0.4.0", "indexmap", "log", "proc-macro2", @@ -347,12 +347,36 @@ dependencies = [ "ansi_term", "atty", "bitflags", - "strsim", - "textwrap", + "strsim 0.8.0", + "textwrap 0.11.0", "unicode-width", "vec_map", ] +[[package]] +name = "clap" +version = "3.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f1fe12880bae935d142c8702d500c63a4e8634b6c3c57ad72bf978fc7b6249a" +dependencies = [ + "atty", + "bitflags", + "clap_lex", + "indexmap", + "strsim 0.10.0", + "termcolor", + "textwrap 0.15.0", +] + +[[package]] +name = "clap_lex" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87eba3c8c7f42ef17f6c659fc7416d0f4758cd3e58861ee63c5fa4a4dde649e4" +dependencies = [ + "os_str_bytes", +] + [[package]] name = "cmake" version = "0.1.48" @@ -530,7 +554,7 @@ checksum = "1604dafd25fba2fe2d5895a9da139f8dc9b319a5fe5354ca137cbbce4e178d10" dependencies = [ "atty", "cast", - "clap", + "clap 2.34.0", "criterion-plot", "csv", "itertools", @@ -1070,6 +1094,12 @@ dependencies = [ "unicode-segmentation", ] +[[package]] +name = "heck" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" + [[package]] name = "hermit-abi" version = "0.1.19" @@ -1486,6 +1516,12 @@ dependencies = [ "web-sys", ] +[[package]] +name = "os_str_bytes" +version = "6.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21326818e99cfe6ce1e524c2a805c189a99b5ae555a35d19f9a284b427d86afa" + [[package]] name = "output_vt100" version = "0.1.3" @@ -2237,13 +2273,19 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + [[package]] name = "structopt" version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c6b5c64445ba8094a6ab0c3cd2ad323e07171012d9c98b0b15651daf1787a10" dependencies = [ - "clap", + "clap 2.34.0", "lazy_static", "structopt-derive", ] @@ -2254,7 +2296,7 @@ version = "0.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0" dependencies = [ - "heck", + "heck 0.3.3", "proc-macro-error", "proc-macro2", "quote", @@ -2371,6 +2413,12 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "textwrap" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" + [[package]] name = "thiserror" version = "1.0.31" diff --git a/lib/c-api/Cargo.toml b/lib/c-api/Cargo.toml index 1059fdb2261..5aade61c2c0 100644 --- a/lib/c-api/Cargo.toml +++ b/lib/c-api/Cargo.toml @@ -85,4 +85,4 @@ jit = ["universal"] #emscripten = ["wasmer-emscripten"] [build-dependencies] -cbindgen = "0.19" +cbindgen = "0.24" From 07e817be2b27e04e26b69637364ed1e0f5783c2a Mon Sep 17 00:00:00 2001 From: Manos Pitsidianakis Date: Thu, 23 Jun 2022 13:51:26 +0300 Subject: [PATCH 2/3] Port C API to new Context API --- lib/api/src/sys/context.rs | 8 + lib/api/src/sys/externals/mod.rs | 5 +- lib/c-api/src/wasm_c_api/context.rs | 40 +++++ .../src/wasm_c_api/externals/function.rs | 142 ++++++------------ lib/c-api/src/wasm_c_api/externals/global.rs | 71 ++++++--- lib/c-api/src/wasm_c_api/externals/memory.rs | 62 +++++--- lib/c-api/src/wasm_c_api/externals/mod.rs | 69 ++++++++- lib/c-api/src/wasm_c_api/externals/table.rs | 17 ++- lib/c-api/src/wasm_c_api/instance.rs | 34 ++++- lib/c-api/src/wasm_c_api/mod.rs | 5 + lib/c-api/src/wasm_c_api/store.rs | 67 ++++++++- lib/c-api/src/wasm_c_api/types/function.rs | 7 +- lib/c-api/src/wasm_c_api/types/value.rs | 42 +++--- .../unstable/middlewares/metering.rs | 26 +++- lib/c-api/src/wasm_c_api/unstable/wasi.rs | 15 +- lib/c-api/src/wasm_c_api/value.rs | 34 ++--- lib/c-api/src/wasm_c_api/wasi/mod.rs | 24 +-- lib/c-api/tests/wasm-c-api/example/callback.c | 22 +-- .../tests/wasm-c-api/example/callback.cc | 32 ++-- lib/c-api/tests/wasm-c-api/example/global.cc | 44 +++--- lib/c-api/tests/wasm-c-api/example/hostref.cc | 32 ++-- lib/c-api/tests/wasm-c-api/example/memory.cc | 12 +- lib/c-api/tests/wasm-c-api/example/multi.cc | 18 +-- lib/c-api/tests/wasm-c-api/example/table.cc | 44 +++--- lib/c-api/tests/wasm-c-api/example/threads.cc | 14 +- lib/c-api/tests/wasm-c-api/example/trap.c | 10 +- lib/c-api/tests/wasm-c-api/include/wasm.h | 10 +- lib/c-api/tests/wasm-c-api/include/wasm.hh | 140 ++++++++--------- lib/c-api/tests/wasm-c-api/src/wasm-c.cc | 8 - lib/cli/src/commands/run.rs | 4 +- lib/cli/src/commands/run/wasi.rs | 4 +- 31 files changed, 648 insertions(+), 414 deletions(-) create mode 100644 lib/c-api/src/wasm_c_api/context.rs diff --git a/lib/api/src/sys/context.rs b/lib/api/src/sys/context.rs index 4289b818647..1168fe8049f 100644 --- a/lib/api/src/sys/context.rs +++ b/lib/api/src/sys/context.rs @@ -65,6 +65,14 @@ impl Context { pub fn store(&self) -> &Store { &self.inner.store } + + /// For use with the C API + /// # Safety + /// + /// This is unsafe. + pub unsafe fn transmute_data(&mut self) -> &mut Context { + core::mem::transmute::<&mut Self, &mut Context>(self) + } } /// A temporary handle to a [`Context`]. diff --git a/lib/api/src/sys/externals/mod.rs b/lib/api/src/sys/externals/mod.rs index e0e7d91235f..7625f7ca206 100644 --- a/lib/api/src/sys/externals/mod.rs +++ b/lib/api/src/sys/externals/mod.rs @@ -44,7 +44,7 @@ impl Extern { } /// Create an `Extern` from an `wasmer_engine::Export`. - pub(crate) fn from_vm_extern(ctx: &mut impl AsContextMut, vm_extern: VMExtern) -> Self { + pub fn from_vm_extern(ctx: &mut impl AsContextMut, vm_extern: VMExtern) -> Self { match vm_extern { VMExtern::Function(f) => Self::Function(Function::from_vm_extern(ctx, f)), VMExtern::Memory(m) => Self::Memory(Memory::from_vm_extern(ctx, m)), @@ -63,7 +63,8 @@ impl Extern { } } - pub(crate) fn to_vm_extern(&self) -> VMExtern { + /// To `VMExtern`. + pub fn to_vm_extern(&self) -> VMExtern { match self { Self::Function(f) => f.to_vm_extern(), Self::Global(g) => g.to_vm_extern(), diff --git a/lib/c-api/src/wasm_c_api/context.rs b/lib/c-api/src/wasm_c_api/context.rs new file mode 100644 index 00000000000..fbd6997051d --- /dev/null +++ b/lib/c-api/src/wasm_c_api/context.rs @@ -0,0 +1,40 @@ +use crate::wasm_c_api::store::wasm_store_t; +use libc::c_void; +use wasmer_api::Context; + +/// Opaque type representing a WebAssembly context. +#[allow(non_camel_case_types)] +pub struct wasm_context_t { + pub(crate) inner: Context<*mut c_void>, +} + +impl core::fmt::Debug for wasm_context_t { + fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(fmt, "wasm_context_t") + } +} + +/// Creates a new WebAssembly Context given a specific [engine][super::engine]. +/// +/// # Example +/// +/// See the module's documentation. +#[no_mangle] +pub unsafe extern "C" fn wasm_context_new( + store: Option<&wasm_store_t>, + data: *mut c_void, +) -> Option> { + let store = store?; + + Some(Box::new(wasm_context_t { + inner: Context::new(&store.inner, data), + })) +} + +/// Deletes a WebAssembly context. +/// +/// # Example +/// +/// See the module's documentation. +#[no_mangle] +pub unsafe extern "C" fn wasm_context_delete(_context: Option>) {} diff --git a/lib/c-api/src/wasm_c_api/externals/function.rs b/lib/c-api/src/wasm_c_api/externals/function.rs index 97576e39676..f5daa91acc9 100644 --- a/lib/c-api/src/wasm_c_api/externals/function.rs +++ b/lib/c-api/src/wasm_c_api/externals/function.rs @@ -1,13 +1,15 @@ +use super::super::context::wasm_context_t; use super::super::store::wasm_store_t; use super::super::trap::wasm_trap_t; use super::super::types::{wasm_functype_t, wasm_valkind_enum}; use super::super::value::{wasm_val_inner, wasm_val_t, wasm_val_vec_t}; use super::CApiExternTag; +use std::cell::RefCell; use std::convert::TryInto; use std::ffi::c_void; use std::mem::MaybeUninit; -use std::sync::{Arc, Mutex}; -use wasmer_api::{Function, RuntimeError, Val}; +use std::rc::Rc; +use wasmer_api::{Function, RuntimeError, Value}; #[derive(Debug, Clone)] #[allow(non_camel_case_types)] @@ -15,6 +17,7 @@ use wasmer_api::{Function, RuntimeError, Val}; pub struct wasm_func_t { pub(crate) tag: CApiExternTag, pub(crate) inner: Box, + pub(crate) context: Option>>, } impl wasm_func_t { @@ -22,6 +25,7 @@ impl wasm_func_t { Self { tag: CApiExternTag::Function, inner: Box::new(function), + context: None, } } } @@ -48,91 +52,19 @@ pub unsafe extern "C" fn wasm_func_new( function_type: Option<&wasm_functype_t>, callback: Option, ) -> Option> { - let store = store?; let function_type = function_type?; let callback = callback?; - - let func_sig = &function_type.inner().function_type; - let num_rets = func_sig.results().len(); - let inner_callback = move |args: &[Val]| -> Result, RuntimeError> { - let processed_args: wasm_val_vec_t = args - .iter() - .map(TryInto::try_into) - .collect::, _>>() - .expect("Argument conversion failed") - .into(); - - let mut results: wasm_val_vec_t = vec![ - wasm_val_t { - kind: wasm_valkind_enum::WASM_I64 as _, - of: wasm_val_inner { int64_t: 0 }, - }; - num_rets - ] - .into(); - - let trap = callback(&processed_args, &mut results); - - if let Some(trap) = trap { - return Err(trap.inner); - } - - let processed_results = results - .take() - .into_iter() - .map(TryInto::try_into) - .collect::, _>>() - .expect("Result conversion failed"); - - Ok(processed_results) - }; - let function = Function::new(&store.inner, func_sig, inner_callback); - - Some(Box::new(wasm_func_t::new(function))) -} - -#[no_mangle] -pub unsafe extern "C" fn wasm_func_new_with_env( - store: Option<&wasm_store_t>, - function_type: Option<&wasm_functype_t>, - callback: Option, - env: *mut c_void, - env_finalizer: Option, -) -> Option> { let store = store?; - let function_type = function_type?; - let callback = callback?; + if store.context.is_none() { + crate::error::update_last_error(wasm_store_t::CTX_ERR_STR); + } + let mut ctx = store.context.as_ref()?.borrow_mut(); let func_sig = &function_type.inner().function_type; let num_rets = func_sig.results().len(); - - #[derive(Clone)] - #[repr(C)] - struct WrapperEnv { - env: *mut c_void, - env_finalizer: Arc>>, - } - - impl wasmer_api::WasmerEnv for WrapperEnv {} - - // Only relevant when using multiple threads in the C API; - // Synchronization will be done via the C API / on the C side. - unsafe impl Send for WrapperEnv {} - unsafe impl Sync for WrapperEnv {} - - impl Drop for WrapperEnv { - fn drop(&mut self) { - if let Ok(mut guard) = self.env_finalizer.lock() { - if Arc::strong_count(&self.env_finalizer) == 1 { - if let Some(env_finalizer) = guard.take() { - unsafe { (env_finalizer)(self.env as _) }; - } - } - } - } - } - - let trampoline = move |env: &WrapperEnv, args: &[Val]| -> Result, RuntimeError> { + let inner_callback = move |_ctx: wasmer_api::ContextMut<'_, *mut c_void>, + args: &[Value]| + -> Result, RuntimeError> { let processed_args: wasm_val_vec_t = args .iter() .map(TryInto::try_into) @@ -149,7 +81,7 @@ pub unsafe extern "C" fn wasm_func_new_with_env( ] .into(); - let trap = callback(env.env, &processed_args, &mut results); + let trap = callback(&processed_args, &mut results); if let Some(trap) = trap { return Err(trap.inner); @@ -159,23 +91,17 @@ pub unsafe extern "C" fn wasm_func_new_with_env( .take() .into_iter() .map(TryInto::try_into) - .collect::, _>>() + .collect::, _>>() .expect("Result conversion failed"); Ok(processed_results) }; + let function = Function::new(&mut ctx.inner, func_sig, inner_callback); + drop(ctx); + let mut retval = Box::new(wasm_func_t::new(function)); + retval.context = store.context.clone(); - let function = Function::new_with_env( - &store.inner, - func_sig, - WrapperEnv { - env, - env_finalizer: Arc::new(Mutex::new(env_finalizer)), - }, - trampoline, - ); - - Some(Box::new(wasm_func_t::new(function))) + Some(retval) } #[no_mangle] @@ -194,16 +120,20 @@ pub unsafe extern "C" fn wasm_func_call( ) -> Option> { let func = func?; let args = args?; + if func.context.is_none() { + crate::error::update_last_error(wasm_store_t::CTX_ERR_STR); + } + let mut ctx = func.context.as_ref()?.borrow_mut(); let params = args .as_slice() .iter() .cloned() .map(TryInto::try_into) - .collect::, _>>() + .collect::, _>>() .expect("Arguments conversion failed"); - match func.inner.call(¶ms) { + match func.inner.call(&mut ctx.inner, ¶ms) { Ok(wasm_results) => { for (slot, val) in results .as_uninit_slice() @@ -221,17 +151,31 @@ pub unsafe extern "C" fn wasm_func_call( #[no_mangle] pub unsafe extern "C" fn wasm_func_param_arity(func: &wasm_func_t) -> usize { - func.inner.ty().params().len() + let ctx = func + .context + .as_ref() + .expect(wasm_store_t::CTX_ERR_STR) + .borrow(); + func.inner.ty(&ctx.inner).params().len() } #[no_mangle] pub unsafe extern "C" fn wasm_func_result_arity(func: &wasm_func_t) -> usize { - func.inner.ty().results().len() + let ctx = func + .context + .as_ref() + .expect(wasm_store_t::CTX_ERR_STR) + .borrow(); + func.inner.ty(&ctx.inner).results().len() } #[no_mangle] pub extern "C" fn wasm_func_type(func: Option<&wasm_func_t>) -> Option> { let func = func?; + if func.context.is_none() { + crate::error::update_last_error(wasm_store_t::CTX_ERR_STR); + } + let ctx = func.context.as_ref()?.borrow(); - Some(Box::new(wasm_functype_t::new(func.inner.ty().clone()))) + Some(Box::new(wasm_functype_t::new(func.inner.ty(&ctx.inner)))) } diff --git a/lib/c-api/src/wasm_c_api/externals/global.rs b/lib/c-api/src/wasm_c_api/externals/global.rs index 02dd9ee49de..899a5d118d7 100644 --- a/lib/c-api/src/wasm_c_api/externals/global.rs +++ b/lib/c-api/src/wasm_c_api/externals/global.rs @@ -1,10 +1,13 @@ +use super::super::context::wasm_context_t; use super::super::store::wasm_store_t; use super::super::types::wasm_globaltype_t; use super::super::value::wasm_val_t; use super::CApiExternTag; use crate::error::update_last_error; +use std::cell::RefCell; use std::convert::TryInto; -use wasmer_api::{Global, Val}; +use std::rc::Rc; +use wasmer_api::{Global, Value}; #[allow(non_camel_case_types)] #[repr(C)] @@ -12,6 +15,7 @@ use wasmer_api::{Global, Val}; pub struct wasm_global_t { pub(crate) tag: CApiExternTag, pub(crate) inner: Box, + pub(crate) context: Option>>, } impl wasm_global_t { @@ -19,6 +23,7 @@ impl wasm_global_t { Self { tag: CApiExternTag::Global, inner: Box::new(global), + context: None, } } } @@ -29,20 +34,25 @@ pub unsafe extern "C" fn wasm_global_new( global_type: Option<&wasm_globaltype_t>, val: Option<&wasm_val_t>, ) -> Option> { - let store = store?; let global_type = global_type?; + let store = store?; + if store.context.is_none() { + crate::error::update_last_error(wasm_store_t::CTX_ERR_STR); + } + let mut ctx = store.context.as_ref()?.borrow_mut(); let val = val?; let global_type = &global_type.inner().global_type; let wasm_val = val.try_into().ok()?; - let store = &store.inner; let global = if global_type.mutability.is_mutable() { - Global::new_mut(store, wasm_val) + Global::new_mut(&mut ctx.inner, wasm_val) } else { - Global::new(store, wasm_val) + Global::new(&mut ctx.inner, wasm_val) }; + let mut retval = Box::new(wasm_global_t::new(global)); + retval.context = store.context.clone(); - Some(Box::new(wasm_global_t::new(global))) + Some(retval) } #[no_mangle] @@ -60,32 +70,47 @@ pub unsafe extern "C" fn wasm_global_get( // own out: &mut wasm_val_t, ) { - let value = global.inner.get(); - *out = value.try_into().unwrap(); + match global.context.as_ref() { + Some(ctx) => { + let value = global.inner.get(&mut ctx.borrow_mut().inner); + *out = value.try_into().unwrap(); + } + None => { + crate::error::update_last_error(wasm_store_t::CTX_ERR_STR); + } + } } /// Note: This function returns nothing by design but it can raise an /// error if setting a new value fails. #[no_mangle] pub unsafe extern "C" fn wasm_global_set(global: &mut wasm_global_t, val: &wasm_val_t) { - let value: Val = val.try_into().unwrap(); + match global.context.as_ref() { + Some(ctx) => { + let value: Value = val.try_into().unwrap(); - if let Err(e) = global.inner.set(value) { - update_last_error(e); + if let Err(e) = global.inner.set(&mut ctx.borrow_mut().inner, value) { + update_last_error(e); + } + } + None => { + crate::error::update_last_error(wasm_store_t::CTX_ERR_STR); + } } } #[no_mangle] -pub unsafe extern "C" fn wasm_global_same( - wasm_global1: &wasm_global_t, - wasm_global2: &wasm_global_t, -) -> bool { - wasm_global1.inner.same(&wasm_global2.inner) -} - -#[no_mangle] -pub extern "C" fn wasm_global_type(global: &wasm_global_t) -> Box { - Box::new(wasm_globaltype_t::new(*global.inner.ty())) +pub extern "C" fn wasm_global_type( + global: Option<&wasm_global_t>, +) -> Option> { + let global = global?; + if global.context.is_none() { + crate::error::update_last_error(wasm_store_t::CTX_ERR_STR); + } + let ctx = global.context.as_ref()?.borrow(); + Some(Box::new(wasm_globaltype_t::new( + global.inner.ty(&ctx.inner), + ))) } #[cfg(test)] @@ -100,6 +125,8 @@ mod tests { int main() { wasm_engine_t* engine = wasm_engine_new(); wasm_store_t* store = wasm_store_new(engine); + wasm_context_t* ctx = wasm_context_new(store, 0); + wasm_store_context_set(store, ctx); wasm_val_t forty_two = WASM_F32_VAL(42); wasm_val_t forty_three = WASM_F32_VAL(43); @@ -132,6 +159,8 @@ mod tests { int main() { wasm_engine_t* engine = wasm_engine_new(); wasm_store_t* store = wasm_store_new(engine); + wasm_context_t* ctx = wasm_context_new(store, 0); + wasm_store_context_set(store, ctx); wasm_byte_vec_t wat; wasmer_byte_vec_new_from_string(&wat, "(module (global $global (export \"global\") f32 (f32.const 1)))"); diff --git a/lib/c-api/src/wasm_c_api/externals/memory.rs b/lib/c-api/src/wasm_c_api/externals/memory.rs index 2e82455436f..e546f67f7a6 100644 --- a/lib/c-api/src/wasm_c_api/externals/memory.rs +++ b/lib/c-api/src/wasm_c_api/externals/memory.rs @@ -1,6 +1,9 @@ +use super::super::context::wasm_context_t; use super::super::store::wasm_store_t; use super::super::types::wasm_memorytype_t; use super::CApiExternTag; +use std::cell::RefCell; +use std::rc::Rc; use wasmer_api::{Memory, Pages}; #[allow(non_camel_case_types)] @@ -9,6 +12,7 @@ use wasmer_api::{Memory, Pages}; pub struct wasm_memory_t { pub(crate) tag: CApiExternTag, pub(crate) inner: Box, + pub(crate) context: Option>>, } impl wasm_memory_t { @@ -16,6 +20,7 @@ impl wasm_memory_t { Self { tag: CApiExternTag::Memory, inner: Box::new(memory), + context: None, } } } @@ -25,13 +30,18 @@ pub unsafe extern "C" fn wasm_memory_new( store: Option<&wasm_store_t>, memory_type: Option<&wasm_memorytype_t>, ) -> Option> { - let store = store?; let memory_type = memory_type?; + let store = store?; + if store.context.is_none() { + crate::error::update_last_error(wasm_store_t::CTX_ERR_STR); + } + let mut ctx = store.context.as_ref()?.borrow_mut(); let memory_type = memory_type.inner().memory_type; - let memory = c_try!(Memory::new(&store.inner, memory_type)); - - Some(Box::new(wasm_memory_t::new(memory))) + let memory = c_try!(Memory::new(&mut ctx.inner, memory_type)); + let mut retval = Box::new(wasm_memory_t::new(memory)); + retval.context = store.context.clone(); + Some(retval) } #[no_mangle] @@ -48,38 +58,56 @@ pub unsafe extern "C" fn wasm_memory_type( memory: Option<&wasm_memory_t>, ) -> Option> { let memory = memory?; + if memory.context.is_none() { + crate::error::update_last_error(wasm_store_t::CTX_ERR_STR); + } + let ctx = memory.context.as_ref()?.borrow(); - Some(Box::new(wasm_memorytype_t::new(memory.inner.ty()))) + Some(Box::new(wasm_memorytype_t::new( + memory.inner.ty(&ctx.inner), + ))) } // get a raw pointer into bytes #[no_mangle] pub unsafe extern "C" fn wasm_memory_data(memory: &mut wasm_memory_t) -> *mut u8 { - memory.inner.data_ptr() + let ctx = memory + .context + .as_ref() + .expect(wasm_store_t::CTX_ERR_STR) + .borrow(); + memory.inner.data_ptr(&ctx.inner) } // size in bytes #[no_mangle] pub unsafe extern "C" fn wasm_memory_data_size(memory: &wasm_memory_t) -> usize { - memory.inner.size().bytes().0 + let ctx = memory + .context + .as_ref() + .expect(wasm_store_t::CTX_ERR_STR) + .borrow(); + memory.inner.size(&ctx.inner).bytes().0 } // size in pages #[no_mangle] pub unsafe extern "C" fn wasm_memory_size(memory: &wasm_memory_t) -> u32 { - memory.inner.size().0 as _ + let ctx = memory + .context + .as_ref() + .expect(wasm_store_t::CTX_ERR_STR) + .borrow(); + memory.inner.size(&ctx.inner).0 as _ } // delta is in pages #[no_mangle] pub unsafe extern "C" fn wasm_memory_grow(memory: &mut wasm_memory_t, delta: u32) -> bool { - memory.inner.grow(Pages(delta)).is_ok() -} - -#[no_mangle] -pub unsafe extern "C" fn wasm_memory_same( - wasm_memory1: &wasm_memory_t, - wasm_memory2: &wasm_memory_t, -) -> bool { - wasm_memory1.inner.same(&wasm_memory2.inner) + let mut ctx = memory + .context + .as_ref() + .expect(wasm_store_t::CTX_ERR_STR) + .borrow_mut(); + memory.inner.grow(&mut ctx.inner, Pages(delta)).is_ok() } diff --git a/lib/c-api/src/wasm_c_api/externals/mod.rs b/lib/c-api/src/wasm_c_api/externals/mod.rs index ebad45c9637..09d190c997f 100644 --- a/lib/c-api/src/wasm_c_api/externals/mod.rs +++ b/lib/c-api/src/wasm_c_api/externals/mod.rs @@ -3,10 +3,14 @@ mod global; mod memory; mod table; +use super::context::wasm_context_t; +use super::store::wasm_store_t; pub use function::*; pub use global::*; pub use memory::*; +use std::cell::RefCell; use std::mem::{self, ManuallyDrop}; +use std::rc::Rc; pub use table::*; use wasmer_api::{Extern, ExternType}; @@ -79,12 +83,63 @@ impl wasm_extern_t { pub(crate) fn ty(&self) -> ExternType { match self.get_tag() { - CApiExternTag::Function => { - ExternType::Function(unsafe { self.inner.function.inner.ty().clone() }) - } - CApiExternTag::Memory => ExternType::Memory(unsafe { self.inner.memory.inner.ty() }), - CApiExternTag::Global => ExternType::Global(unsafe { *self.inner.global.inner.ty() }), - CApiExternTag::Table => ExternType::Table(unsafe { *self.inner.table.inner.ty() }), + CApiExternTag::Function => unsafe { + let ctx = self + .inner + .function + .context + .as_ref() + .expect(wasm_store_t::CTX_ERR_STR) + .borrow(); + ExternType::Function(self.inner.function.inner.ty(&ctx.inner)) + }, + CApiExternTag::Memory => unsafe { + let ctx = self + .inner + .memory + .context + .as_ref() + .expect(wasm_store_t::CTX_ERR_STR) + .borrow(); + ExternType::Memory(self.inner.memory.inner.ty(&ctx.inner)) + }, + CApiExternTag::Global => unsafe { + let ctx = self + .inner + .global + .context + .as_ref() + .expect(wasm_store_t::CTX_ERR_STR) + .borrow(); + ExternType::Global(self.inner.global.inner.ty(&ctx.inner)) + }, + CApiExternTag::Table => unsafe { + let ctx = self + .inner + .table + .context + .as_ref() + .expect(wasm_store_t::CTX_ERR_STR) + .borrow(); + ExternType::Table(self.inner.table.inner.ty(&ctx.inner)) + }, + } + } + + pub(crate) fn set_context(&mut self, new_val: Option>>) { + match self.get_tag() { + CApiExternTag::Function => unsafe { + (*self.inner.function).context = new_val; + }, + CApiExternTag::Memory => unsafe { + (*self.inner.memory).context = new_val; + }, + CApiExternTag::Global => unsafe { + (*self.inner.global).context = new_val; + }, + CApiExternTag::Table => unsafe { + (*self.inner.table).context = new_val; + }, } } } @@ -265,6 +320,8 @@ mod tests { int main() { wasm_engine_t* engine = wasm_engine_new(); wasm_store_t* store = wasm_store_new(engine); + wasm_context_t* ctx = wasm_context_new(store, 0); + wasm_store_context_set(store, ctx); wasm_byte_vec_t wat; wasmer_byte_vec_new_from_string( diff --git a/lib/c-api/src/wasm_c_api/externals/table.rs b/lib/c-api/src/wasm_c_api/externals/table.rs index e5d02d6c048..c45ee56b957 100644 --- a/lib/c-api/src/wasm_c_api/externals/table.rs +++ b/lib/c-api/src/wasm_c_api/externals/table.rs @@ -1,6 +1,9 @@ +use super::super::context::wasm_context_t; use super::super::store::wasm_store_t; use super::super::types::{wasm_ref_t, wasm_table_size_t, wasm_tabletype_t}; use super::CApiExternTag; +use std::cell::RefCell; +use std::rc::Rc; use wasmer_api::Table; #[allow(non_camel_case_types)] @@ -9,6 +12,7 @@ use wasmer_api::Table; pub struct wasm_table_t { pub(crate) tag: CApiExternTag, pub(crate) inner: Box, + pub(crate) context: Option>>, } impl wasm_table_t { @@ -16,6 +20,7 @@ impl wasm_table_t { Self { tag: CApiExternTag::Table, inner: Box::new(table), + context: None, } } } @@ -38,14 +43,14 @@ pub unsafe extern "C" fn wasm_table_copy(table: &wasm_table_t) -> Box bool { - table1.inner.same(&table2.inner) -} - #[no_mangle] pub unsafe extern "C" fn wasm_table_size(table: &wasm_table_t) -> usize { - table.inner.size() as _ + let ctx = table + .context + .as_ref() + .expect(wasm_store_t::CTX_ERR_STR) + .borrow(); + table.inner.size(&ctx.inner) as _ } #[no_mangle] diff --git a/lib/c-api/src/wasm_c_api/instance.rs b/lib/c-api/src/wasm_c_api/instance.rs index 3912a092678..7e1fa6ed831 100644 --- a/lib/c-api/src/wasm_c_api/instance.rs +++ b/lib/c-api/src/wasm_c_api/instance.rs @@ -1,7 +1,10 @@ -use super::externals::wasm_extern_vec_t; +use super::context::wasm_context_t; +use super::externals::{wasm_extern_t, wasm_extern_vec_t}; use super::module::wasm_module_t; use super::store::wasm_store_t; use super::trap::wasm_trap_t; +use std::cell::RefCell; +use std::rc::Rc; use std::sync::Arc; use wasmer_api::{Extern, Instance, InstantiationError}; @@ -9,6 +12,7 @@ use wasmer_api::{Extern, Instance, InstantiationError}; #[allow(non_camel_case_types)] pub struct wasm_instance_t { pub(crate) inner: Arc, + pub(crate) context: Option>>, } /// Creates a new instance from a WebAssembly module and a @@ -36,11 +40,16 @@ pub struct wasm_instance_t { /// See the module's documentation. #[no_mangle] pub unsafe extern "C" fn wasm_instance_new( - _store: Option<&wasm_store_t>, + store: Option<&wasm_store_t>, module: Option<&wasm_module_t>, imports: Option<&wasm_extern_vec_t>, trap: Option<&mut *mut wasm_trap_t>, ) -> Option> { + let store = store?; + if store.context.is_none() { + crate::error::update_last_error(wasm_store_t::CTX_ERR_STR); + } + let mut ctx = store.context.as_ref()?.borrow_mut(); let module = module?; let imports = imports?; @@ -54,7 +63,7 @@ pub unsafe extern "C" fn wasm_instance_new( .take(module_import_count) .collect::>(); - let instance = match Instance::new_by_index(wasm_module, &externs) { + let instance = match Instance::new_by_index(&mut ctx.inner, wasm_module, &externs) { Ok(instance) => Arc::new(instance), Err(InstantiationError::Link(link_error)) => { @@ -78,14 +87,17 @@ pub unsafe extern "C" fn wasm_instance_new( return None; } - Err(InstantiationError::HostEnvInitialization(error)) => { - crate::error::update_last_error(error); + Err(e @ InstantiationError::BadContext) => { + crate::error::update_last_error(e); return None; } }; - Some(Box::new(wasm_instance_t { inner: instance })) + Some(Box::new(wasm_instance_t { + inner: instance, + context: store.context.clone(), + })) } /// Deletes an instance. @@ -110,6 +122,8 @@ pub unsafe extern "C" fn wasm_instance_delete(_instance: Option>> = instance .exports .iter() .map(|(_name, r#extern)| Some(Box::new(r#extern.clone().into()))) .collect(); + for ex in extern_vec.iter_mut().flatten() { + ex.set_context(original_instance.context.clone()); + } out.set_buffer(extern_vec); } @@ -222,6 +240,8 @@ mod tests { // Create the engine and the store. wasm_engine_t* engine = wasm_engine_new(); wasm_store_t* store = wasm_store_new(engine); + wasm_context_t* ctx = wasm_context_new(store, 0); + wasm_store_context_set(store, ctx); // Create a WebAssembly module from a WAT definition. wasm_byte_vec_t wat; diff --git a/lib/c-api/src/wasm_c_api/mod.rs b/lib/c-api/src/wasm_c_api/mod.rs index 1732669db6c..26fbd5f991b 100644 --- a/lib/c-api/src/wasm_c_api/mod.rs +++ b/lib/c-api/src/wasm_c_api/mod.rs @@ -21,6 +21,9 @@ //! Every module comes with examples and entry points to guide the //! discovery of this API. +/// `Context`. +mod context; + /// Private Rust macros. #[macro_use] mod macros; @@ -89,6 +92,8 @@ pub mod externals; /// // Create the engine and the store. /// wasm_engine_t* engine = wasm_engine_new(); /// wasm_store_t* store = wasm_store_new(engine); +/// wasm_context_t* ctx = wasm_context_new(store, 0); +/// wasm_store_context_set(store, ctx); /// /// // Create a WebAssembly module from a WAT definition. /// wasm_byte_vec_t wat; diff --git a/lib/c-api/src/wasm_c_api/store.rs b/lib/c-api/src/wasm_c_api/store.rs index 40d35007c10..fe5eb89de21 100644 --- a/lib/c-api/src/wasm_c_api/store.rs +++ b/lib/c-api/src/wasm_c_api/store.rs @@ -1,10 +1,20 @@ +use super::context::wasm_context_t; use super::engine::wasm_engine_t; +use libc::c_void; +use std::cell::RefCell; +use std::rc::Rc; use wasmer_api::Store; /// Opaque type representing a WebAssembly store. #[allow(non_camel_case_types)] pub struct wasm_store_t { pub(crate) inner: Store, + pub(crate) context: Option>>, +} + +impl wasm_store_t { + pub(crate) const CTX_ERR_STR: &'static str = + "store used without a Context set; use wasm_store_context_set() after initializing your store."; } /// Creates a new WebAssembly store given a specific [engine][super::engine]. @@ -19,7 +29,62 @@ pub unsafe extern "C" fn wasm_store_new( let engine = engine?; let store = Store::new_with_engine(&*engine.inner); - Some(Box::new(wasm_store_t { inner: store })) + Some(Box::new(wasm_store_t { + inner: store, + context: None, + })) +} + +/// Sets the context for this WebAssembly store. +/// +/// # Example +/// +/// See the module's documentation. +#[no_mangle] +pub unsafe extern "C" fn wasm_store_context_set( + store: Option<&mut wasm_store_t>, + context: Option>, +) { + let _result = (move |store: Option<&mut wasm_store_t>, + context: Option>| + -> Option<()> { + let mut store = store?; + let context = context?; + store.context = Some(Rc::new(RefCell::new(*context))); + Some(()) + })(store, context); +} + +/// Get the value of Context data. +/// +/// # Example +/// +/// See the module's documentation. +#[no_mangle] +pub unsafe extern "C" fn wasm_store_data_get(store: &wasm_store_t) -> *mut c_void { + *store + .context + .as_ref() + .expect(wasm_store_t::CTX_ERR_STR) + .borrow() + .inner + .data() +} + +/// Set the value of Context data. +/// +/// # Example +/// +/// See the module's documentation. +#[no_mangle] +pub unsafe extern "C" fn wasm_store_data_set(store: &mut wasm_store_t, new_val: *mut c_void) { + *store + .context + .as_mut() + .expect(wasm_store_t::CTX_ERR_STR) + .borrow_mut() + .inner + .data_mut() = new_val; } /// Deletes a WebAssembly store. diff --git a/lib/c-api/src/wasm_c_api/types/function.rs b/lib/c-api/src/wasm_c_api/types/function.rs index a3ff1f6bdd7..52d10d54c55 100644 --- a/lib/c-api/src/wasm_c_api/types/function.rs +++ b/lib/c-api/src/wasm_c_api/types/function.rs @@ -1,6 +1,7 @@ use super::{wasm_externtype_t, wasm_valtype_vec_t, WasmExternType}; use std::fmt; -use wasmer_api::{ExternType, FunctionType, ValType}; +use wasmer_api::{ExternType, FunctionType}; +use wasmer_types::Type; pub(crate) struct WasmFunctionType { pub(crate) function_type: FunctionType, @@ -76,12 +77,12 @@ pub unsafe extern "C" fn wasm_functype_new( let params = params?; let results = results?; - let params_as_valtype: Vec = params + let params_as_valtype: Vec = params .take() .into_iter() .map(|val| val.as_ref().unwrap().as_ref().into()) .collect::>(); - let results_as_valtype: Vec = results + let results_as_valtype: Vec = results .take() .into_iter() .map(|val| val.as_ref().unwrap().as_ref().into()) diff --git a/lib/c-api/src/wasm_c_api/types/value.rs b/lib/c-api/src/wasm_c_api/types/value.rs index 4e48dddae6e..ae2189c3117 100644 --- a/lib/c-api/src/wasm_c_api/types/value.rs +++ b/lib/c-api/src/wasm_c_api/types/value.rs @@ -1,6 +1,6 @@ use super::super::value::wasm_valkind_t; use std::convert::TryInto; -use wasmer_api::ValType; +use wasmer_api::Type; #[allow(non_camel_case_types)] #[derive(Debug, Clone, Copy, PartialEq, Eq)] @@ -14,30 +14,30 @@ pub enum wasm_valkind_enum { WASM_FUNCREF = 129, } -impl From for wasm_valkind_enum { - fn from(other: ValType) -> Self { +impl From for wasm_valkind_enum { + fn from(other: Type) -> Self { match other { - ValType::I32 => Self::WASM_I32, - ValType::I64 => Self::WASM_I64, - ValType::F32 => Self::WASM_F32, - ValType::F64 => Self::WASM_F64, - ValType::V128 => todo!("no v128 type in Wasm C API yet!"), - ValType::ExternRef => Self::WASM_ANYREF, - ValType::FuncRef => Self::WASM_FUNCREF, + Type::I32 => Self::WASM_I32, + Type::I64 => Self::WASM_I64, + Type::F32 => Self::WASM_F32, + Type::F64 => Self::WASM_F64, + Type::V128 => todo!("no v128 type in Wasm C API yet!"), + Type::ExternRef => Self::WASM_ANYREF, + Type::FuncRef => Self::WASM_FUNCREF, } } } -impl From for ValType { +impl From for Type { fn from(other: wasm_valkind_enum) -> Self { use wasm_valkind_enum::*; match other { - WASM_I32 => ValType::I32, - WASM_I64 => ValType::I64, - WASM_F32 => ValType::F32, - WASM_F64 => ValType::F64, - WASM_ANYREF => ValType::ExternRef, - WASM_FUNCREF => ValType::FuncRef, + WASM_I32 => Type::I32, + WASM_I64 => Type::I64, + WASM_F32 => Type::F32, + WASM_F64 => Type::F64, + WASM_ANYREF => Type::ExternRef, + WASM_FUNCREF => Type::FuncRef, } } } @@ -58,20 +58,20 @@ impl Default for wasm_valtype_t { wasm_declare_boxed_vec!(valtype); -impl From for ValType { +impl From for Type { fn from(other: wasm_valtype_t) -> Self { (&other).into() } } -impl From<&wasm_valtype_t> for ValType { +impl From<&wasm_valtype_t> for Type { fn from(other: &wasm_valtype_t) -> Self { other.valkind.into() } } -impl From for wasm_valtype_t { - fn from(other: ValType) -> Self { +impl From for wasm_valtype_t { + fn from(other: Type) -> Self { Self { valkind: other.into(), } diff --git a/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs b/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs index cf64aed6aa2..bc4eb715470 100644 --- a/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs +++ b/lib/c-api/src/wasm_c_api/unstable/middlewares/metering.rs @@ -45,6 +45,8 @@ //! // Create the engine and the store based on the configuration. //! wasm_engine_t* engine = wasm_engine_new_with_config(config); //! wasm_store_t* store = wasm_store_new(engine); +//! wasm_context_t* ctx = wasm_context_new(store, 0); +//! wasm_store_context_set(store, ctx); //! //! // Create the new WebAssembly module. //! wasm_byte_vec_t wat; @@ -132,6 +134,7 @@ //! ``` use super::super::super::instance::wasm_instance_t; +use super::super::super::store::wasm_store_t; use super::super::parser::operator::wasmer_parser_operator_t; use super::wasmer_middleware_t; use std::sync::Arc; @@ -202,7 +205,12 @@ pub extern "C" fn wasmer_metering_delete(_metering: Option u64 { - match get_remaining_points(&instance.inner) { + let mut ctx = instance + .context + .as_ref() + .expect(wasm_store_t::CTX_ERR_STR) + .borrow_mut(); + match get_remaining_points(&mut ctx.inner, &instance.inner) { MeteringPoints::Remaining(value) => value, MeteringPoints::Exhausted => std::u64::MAX, } @@ -215,8 +223,13 @@ pub extern "C" fn wasmer_metering_get_remaining_points(instance: &wasm_instance_ /// See module's documentation. #[no_mangle] pub extern "C" fn wasmer_metering_points_are_exhausted(instance: &wasm_instance_t) -> bool { + let mut ctx = instance + .context + .as_ref() + .expect(wasm_store_t::CTX_ERR_STR) + .borrow_mut(); matches!( - get_remaining_points(&instance.inner), + get_remaining_points(&mut ctx.inner, &instance.inner), MeteringPoints::Exhausted, ) } @@ -258,6 +271,8 @@ pub extern "C" fn wasmer_metering_points_are_exhausted(instance: &wasm_instance_ /// wasm_engine_t* engine = wasm_engine_new_with_config(config); /// /// wasm_store_t* store = wasm_store_new(engine); +/// wasm_context_t* ctx = wasm_context_new(store, 0); +/// wasm_store_context_set(store, ctx); /// /// // Create the module and instantiate it. /// wasm_byte_vec_t wat; @@ -295,7 +310,12 @@ pub extern "C" fn wasmer_metering_points_are_exhausted(instance: &wasm_instance_ /// ``` #[no_mangle] pub extern "C" fn wasmer_metering_set_remaining_points(instance: &wasm_instance_t, new_limit: u64) { - set_remaining_points(&instance.inner, new_limit); + let mut ctx = instance + .context + .as_ref() + .expect(wasm_store_t::CTX_ERR_STR) + .borrow_mut(); + set_remaining_points(&mut ctx.inner, &instance.inner, new_limit); } /// Transforms a [`wasmer_metering_t`] into a generic diff --git a/lib/c-api/src/wasm_c_api/unstable/wasi.rs b/lib/c-api/src/wasm_c_api/unstable/wasi.rs index 793db9ce079..0abbf923267 100644 --- a/lib/c-api/src/wasm_c_api/unstable/wasi.rs +++ b/lib/c-api/src/wasm_c_api/unstable/wasi.rs @@ -5,7 +5,7 @@ use super::super::{ externals::wasm_extern_t, module::wasm_module_t, store::wasm_store_t, types::wasm_name_t, wasi::wasi_env_t, }; -use wasmer_api::{Exportable, Extern}; +use wasmer_api::{AsContextMut, Extern}; use wasmer_wasi::{generate_import_object_from_ctx, get_wasi_version}; /// Unstable non-standard type wrapping `wasm_extern_t` with the @@ -162,15 +162,18 @@ fn wasi_get_unordered_imports_inner( imports: &mut wasmer_named_extern_vec_t, ) -> Option<()> { let store = store?; + if store.context.is_none() { + crate::error::update_last_error(wasm_store_t::CTX_ERR_STR); + } + let mut ctx = store.context.as_ref()?.borrow_mut(); let module = module?; - let wasi_env = wasi_env?; - - let store = &store.inner; + let _wasi_env = wasi_env?; let version = c_try!(get_wasi_version(&module.inner, false) .ok_or("could not detect a WASI version on the given module")); - let import_object = generate_import_object_from_ctx(store, wasi_env.inner.clone(), version); + let inner = unsafe { ctx.inner.transmute_data::() }; + let import_object = generate_import_object_from_ctx(&mut inner.as_context_mut(), version); imports.set_buffer( import_object @@ -178,7 +181,7 @@ fn wasi_get_unordered_imports_inner( .map(|((module, name), extern_)| { let module = module.into(); let name = name.into(); - let extern_inner = Extern::from_vm_export(store, extern_.to_vm_extern()); + let extern_inner = Extern::from_vm_extern(&mut ctx.inner, extern_.to_vm_extern()); Some(Box::new(wasmer_named_extern_t { module, diff --git a/lib/c-api/src/wasm_c_api/value.rs b/lib/c-api/src/wasm_c_api/value.rs index bb64140aa9a..db07a813b4c 100644 --- a/lib/c-api/src/wasm_c_api/value.rs +++ b/lib/c-api/src/wasm_c_api/value.rs @@ -1,7 +1,7 @@ use super::types::{wasm_ref_t, wasm_valkind_enum}; use crate::error::update_last_error; use std::convert::{TryFrom, TryInto}; -use wasmer_api::Val; +use wasmer_api::Value; /// Represents the kind of values. The variants of this C enum is /// defined in `wasm.h` to list the following: @@ -187,7 +187,7 @@ impl TryFrom for wasm_valkind_enum { } } -impl TryFrom for Val { +impl TryFrom for Value { type Error = &'static str; fn try_from(item: wasm_val_t) -> Result { @@ -195,52 +195,52 @@ impl TryFrom for Val { } } -impl TryFrom<&wasm_val_t> for Val { +impl TryFrom<&wasm_val_t> for Value { type Error = &'static str; fn try_from(item: &wasm_val_t) -> Result { Ok(match item.kind.try_into()? { - wasm_valkind_enum::WASM_I32 => Val::I32(unsafe { item.of.int32_t }), - wasm_valkind_enum::WASM_I64 => Val::I64(unsafe { item.of.int64_t }), - wasm_valkind_enum::WASM_F32 => Val::F32(unsafe { item.of.float32_t }), - wasm_valkind_enum::WASM_F64 => Val::F64(unsafe { item.of.float64_t }), + wasm_valkind_enum::WASM_I32 => Value::I32(unsafe { item.of.int32_t }), + wasm_valkind_enum::WASM_I64 => Value::I64(unsafe { item.of.int64_t }), + wasm_valkind_enum::WASM_F32 => Value::F32(unsafe { item.of.float32_t }), + wasm_valkind_enum::WASM_F64 => Value::F64(unsafe { item.of.float64_t }), wasm_valkind_enum::WASM_ANYREF => return Err("ANYREF not supported at this time"), wasm_valkind_enum::WASM_FUNCREF => return Err("FUNCREF not supported at this time"), }) } } -impl TryFrom for wasm_val_t { +impl TryFrom for wasm_val_t { type Error = &'static str; - fn try_from(item: Val) -> Result { + fn try_from(item: Value) -> Result { wasm_val_t::try_from(&item) } } -impl TryFrom<&Val> for wasm_val_t { +impl TryFrom<&Value> for wasm_val_t { type Error = &'static str; - fn try_from(item: &Val) -> Result { + fn try_from(item: &Value) -> Result { Ok(match *item { - Val::I32(v) => wasm_val_t { + Value::I32(v) => wasm_val_t { of: wasm_val_inner { int32_t: v }, kind: wasm_valkind_enum::WASM_I32 as _, }, - Val::I64(v) => wasm_val_t { + Value::I64(v) => wasm_val_t { of: wasm_val_inner { int64_t: v }, kind: wasm_valkind_enum::WASM_I64 as _, }, - Val::F32(v) => wasm_val_t { + Value::F32(v) => wasm_val_t { of: wasm_val_inner { float32_t: v }, kind: wasm_valkind_enum::WASM_F32 as _, }, - Val::F64(v) => wasm_val_t { + Value::F64(v) => wasm_val_t { of: wasm_val_inner { float64_t: v }, kind: wasm_valkind_enum::WASM_F64 as _, }, - Val::V128(_) => return Err("128bit SIMD types not yet supported in Wasm C API"), - _ => todo!("Handle these values in TryFrom for wasm_val_t"), + Value::V128(_) => return Err("128bit SIMD types not yet supported in Wasm C API"), + _ => todo!("Handle these values in TryFrom for wasm_val_t"), }) } } diff --git a/lib/c-api/src/wasm_c_api/wasi/mod.rs b/lib/c-api/src/wasm_c_api/wasi/mod.rs index 3aa36fb48d0..1e7dc61a0b7 100644 --- a/lib/c-api/src/wasm_c_api/wasi/mod.rs +++ b/lib/c-api/src/wasm_c_api/wasi/mod.rs @@ -14,7 +14,7 @@ use std::convert::TryFrom; use std::ffi::CStr; use std::os::raw::c_char; use std::slice; -use wasmer_api::{Exportable, Extern}; +use wasmer_api::{AsContextMut, Extern}; use wasmer_wasi::{ generate_import_object_from_ctx, get_wasi_version, Pipe, WasiEnv, WasiFile, WasiState, WasiStateBuilder, WasiVersion, @@ -322,28 +322,28 @@ pub unsafe extern "C" fn wasi_get_wasi_version(module: &wasm_module_t) -> wasi_v pub unsafe extern "C" fn wasi_get_imports( store: Option<&wasm_store_t>, module: Option<&wasm_module_t>, - wasi_env: Option<&wasi_env_t>, imports: &mut wasm_extern_vec_t, ) -> bool { - wasi_get_imports_inner(store, module, wasi_env, imports).is_some() + wasi_get_imports_inner(store, module, imports).is_some() } fn wasi_get_imports_inner( store: Option<&wasm_store_t>, module: Option<&wasm_module_t>, - wasi_env: Option<&wasi_env_t>, imports: &mut wasm_extern_vec_t, ) -> Option<()> { let store = store?; + if store.context.is_none() { + crate::error::update_last_error(wasm_store_t::CTX_ERR_STR); + } + let mut ctx = store.context.as_ref()?.borrow_mut(); let module = module?; - let wasi_env = wasi_env?; - - let store = &store.inner; let version = c_try!(get_wasi_version(&module.inner, false) .ok_or("could not detect a WASI version on the given module")); - let import_object = generate_import_object_from_ctx(store, wasi_env.inner.clone(), version); + let inner = unsafe { ctx.inner.transmute_data::() }; + let import_object = generate_import_object_from_ctx(&mut inner.as_context_mut(), version); imports.set_buffer(c_try!(module .inner @@ -358,7 +358,7 @@ fn wasi_get_imports_inner( import_type.name() ) })?; - let inner = Extern::from_vm_export(store, ext.to_vm_extern()); + let inner = Extern::from_vm_extern(&mut ctx.inner, ext.to_vm_extern()); Ok(Some(Box::new(inner.into()))) }) @@ -388,6 +388,7 @@ mod tests { int main() { wasm_engine_t* engine = wasm_engine_new(); wasm_store_t* store = wasm_store_new(engine); + wasm_context_t* ctx = wasm_context_new(store, 0); wasm_byte_vec_t wat; wasmer_byte_vec_new_from_string(&wat, "(module (import \"wasi_unstable\" \"args_get\" (func (param i32 i32) (result i32))))"); @@ -402,6 +403,7 @@ mod tests { wasm_module_delete(module); wasm_byte_vec_delete(&wasm); wasm_byte_vec_delete(&wat); + wasm_context_delete(ctx); wasm_store_delete(store); wasm_engine_delete(engine); @@ -419,6 +421,7 @@ mod tests { int main() { wasm_engine_t* engine = wasm_engine_new(); wasm_store_t* store = wasm_store_new(engine); + wasm_context_t* ctx = wasm_context_new(store, 0); wasm_byte_vec_t wat; wasmer_byte_vec_new_from_string(&wat, "(module (import \"wasi_snapshot_preview1\" \"args_get\" (func (param i32 i32) (result i32))))"); @@ -433,6 +436,7 @@ mod tests { wasm_module_delete(module); wasm_byte_vec_delete(&wasm); wasm_byte_vec_delete(&wat); + wasm_context_delete(ctx); wasm_store_delete(store); wasm_engine_delete(engine); @@ -450,6 +454,7 @@ mod tests { int main() { wasm_engine_t* engine = wasm_engine_new(); wasm_store_t* store = wasm_store_new(engine); + wasm_context_t* ctx = wasm_context_new(store, 0); wasm_byte_vec_t wat; wasmer_byte_vec_new_from_string(&wat, "(module (import \"wasi_snpsht_prvw1\" \"args_get\" (func (param i32 i32) (result i32))))"); @@ -464,6 +469,7 @@ mod tests { wasm_module_delete(module); wasm_byte_vec_delete(&wasm); wasm_byte_vec_delete(&wat); + wasm_context_delete(ctx); wasm_store_delete(store); wasm_engine_delete(engine); diff --git a/lib/c-api/tests/wasm-c-api/example/callback.c b/lib/c-api/tests/wasm-c-api/example/callback.c index 2fddb1634ff..64f3d49f499 100644 --- a/lib/c-api/tests/wasm-c-api/example/callback.c +++ b/lib/c-api/tests/wasm-c-api/example/callback.c @@ -7,6 +7,8 @@ #define own +wasm_store_t* global_store = NULL; + // Print a Wasm value void wasm_val_print(wasm_val_t val) { switch (val.kind) { @@ -48,9 +50,9 @@ own wasm_trap_t* print_callback( // A function closure. own wasm_trap_t* closure_callback( - void* env, const wasm_val_vec_t* args, wasm_val_vec_t* results + const wasm_val_vec_t* args, wasm_val_vec_t* results ) { - int i = *(int*)env; + int i = *(int*) wasm_store_data_get(global_store); printf("Calling back closure...\n"); printf("> %d\n", i); @@ -64,7 +66,10 @@ int main(int argc, const char* argv[]) { // Initialize. printf("Initializing...\n"); wasm_engine_t* engine = wasm_engine_new(); - wasm_store_t* store = wasm_store_new(engine); + global_store = wasm_store_new(engine); + int i = 42; + wasm_context_t* ctx = wasm_context_new(global_store, &i); + wasm_store_context_set(global_store, ctx); // Load binary. printf("Loading binary...\n"); @@ -86,7 +91,7 @@ int main(int argc, const char* argv[]) { // Compile. printf("Compiling module...\n"); - own wasm_module_t* module = wasm_module_new(store, &binary); + own wasm_module_t* module = wasm_module_new(global_store, &binary); if (!module) { printf("> Error compiling module!\n"); return 1; @@ -97,11 +102,10 @@ int main(int argc, const char* argv[]) { // Create external print functions. printf("Creating callback...\n"); own wasm_functype_t* print_type = wasm_functype_new_1_1(wasm_valtype_new_i32(), wasm_valtype_new_i32()); - own wasm_func_t* print_func = wasm_func_new(store, print_type, print_callback); + own wasm_func_t* print_func = wasm_func_new(global_store, print_type, print_callback); - int i = 42; own wasm_functype_t* closure_type = wasm_functype_new_0_1(wasm_valtype_new_i32()); - own wasm_func_t* closure_func = wasm_func_new_with_env(store, closure_type, closure_callback, &i, NULL); + own wasm_func_t* closure_func = wasm_func_new(global_store, closure_type, closure_callback); wasm_functype_delete(print_type); wasm_functype_delete(closure_type); @@ -113,7 +117,7 @@ int main(int argc, const char* argv[]) { }; wasm_extern_vec_t imports = WASM_ARRAY_VEC(externs); own wasm_instance_t* instance = - wasm_instance_new(store, module, &imports, NULL); + wasm_instance_new(global_store, module, &imports, NULL); if (!instance) { printf("> Error instantiating module!\n"); return 1; @@ -158,7 +162,7 @@ int main(int argc, const char* argv[]) { // Shut down. printf("Shutting down...\n"); - wasm_store_delete(store); + wasm_store_delete(global_store); wasm_engine_delete(engine); // All done. diff --git a/lib/c-api/tests/wasm-c-api/example/callback.cc b/lib/c-api/tests/wasm-c-api/example/callback.cc index 957629cabc8..27c1b6545d3 100644 --- a/lib/c-api/tests/wasm-c-api/example/callback.cc +++ b/lib/c-api/tests/wasm-c-api/example/callback.cc @@ -7,22 +7,22 @@ #include "wasm.hh" // Print a Wasm value -auto operator<<(std::ostream& out, const wasm::Val& val) -> std::ostream& { +auto operator<<(std::ostream& out, const wasm::Value& val) -> std::ostream& { switch (val.kind()) { - case wasm::ValKind::I32: { + case wasm::ValueKind::I32: { out << val.i32(); } break; - case wasm::ValKind::I64: { + case wasm::ValueKind::I64: { out << val.i64(); } break; - case wasm::ValKind::F32: { + case wasm::ValueKind::F32: { out << val.f32(); } break; - case wasm::ValKind::F64: { + case wasm::ValueKind::F64: { out << val.f64(); } break; - case wasm::ValKind::ANYREF: - case wasm::ValKind::FUNCREF: { + case wasm::ValueKind::ANYREF: + case wasm::ValueKind::FUNCREF: { if (val.ref() == nullptr) { out << "null"; } else { @@ -35,7 +35,7 @@ auto operator<<(std::ostream& out, const wasm::Val& val) -> std::ostream& { // A function to be called from Wasm code. auto print_callback( - const wasm::vec& args, wasm::vec& results + const wasm::vec& args, wasm::vec& results ) -> wasm::own { std::cout << "Calling back..." << std::endl << "> " << args[0] << std::endl; results[0] = args[0].copy(); @@ -45,12 +45,12 @@ auto print_callback( // A function closure. auto closure_callback( - void* env, const wasm::vec& args, wasm::vec& results + void* env, const wasm::vec& args, wasm::vec& results ) -> wasm::own { auto i = *reinterpret_cast(env); std::cout << "Calling back closure..." << std::endl; std::cout << "> " << i << std::endl; - results[0] = wasm::Val::i32(static_cast(i)); + results[0] = wasm::Value::i32(static_cast(i)); return nullptr; } @@ -87,8 +87,8 @@ void run() { // Create external print functions. std::cout << "Creating callback..." << std::endl; auto print_type = wasm::FuncType::make( - wasm::ownvec::make(wasm::ValType::make(wasm::ValKind::I32)), - wasm::ownvec::make(wasm::ValType::make(wasm::ValKind::I32)) + wasm::ownvec::make(wasm::ValueType::make(wasm::ValueKind::I32)), + wasm::ownvec::make(wasm::ValueType::make(wasm::ValueKind::I32)) ); auto print_func = wasm::Func::make(store, print_type.get(), print_callback); @@ -96,8 +96,8 @@ void run() { std::cout << "Creating closure..." << std::endl; int i = 42; auto closure_type = wasm::FuncType::make( - wasm::ownvec::make(), - wasm::ownvec::make(wasm::ValType::make(wasm::ValKind::I32)) + wasm::ownvec::make(), + wasm::ownvec::make(wasm::ValueType::make(wasm::ValueKind::I32)) ); auto closure_func = wasm::Func::make(store, closure_type.get(), closure_callback, &i); @@ -122,8 +122,8 @@ void run() { // Call. std::cout << "Calling export..." << std::endl; - auto args = wasm::vec::make(wasm::Val::i32(3), wasm::Val::i32(4)); - auto results = wasm::vec::make_uninitialized(1); + auto args = wasm::vec::make(wasm::Value::i32(3), wasm::Value::i32(4)); + auto results = wasm::vec::make_uninitialized(1); if (run_func->call(args, results)) { std::cout << "> Error calling function!" << std::endl; exit(1); diff --git a/lib/c-api/tests/wasm-c-api/example/global.cc b/lib/c-api/tests/wasm-c-api/example/global.cc index 178eb61f8b7..a1770ef82d1 100644 --- a/lib/c-api/tests/wasm-c-api/example/global.cc +++ b/lib/c-api/tests/wasm-c-api/example/global.cc @@ -31,9 +31,9 @@ void check(T actual, U expected) { } } -auto call(const wasm::Func* func) -> wasm::Val { - auto args = wasm::vec::make(); - auto results = wasm::vec::make_uninitialized(1); +auto call(const wasm::Func* func) -> wasm::Value { + auto args = wasm::vec::make(); + auto results = wasm::vec::make_uninitialized(1); if (func->call(args, results)) { std::cout << "> Error calling function!" << std::endl; exit(1); @@ -41,9 +41,9 @@ auto call(const wasm::Func* func) -> wasm::Val { return results[0].copy(); } -void call(const wasm::Func* func, wasm::Val&& arg) { - auto args = wasm::vec::make(std::move(arg)); - auto results = wasm::vec::make(); +void call(const wasm::Func* func, wasm::Value&& arg) { + auto args = wasm::vec::make(std::move(arg)); + auto results = wasm::vec::make(); if (func->call(args, results)) { std::cout << "> Error calling function!" << std::endl; exit(1); @@ -83,17 +83,17 @@ void run() { // Create external globals. std::cout << "Creating globals..." << std::endl; auto const_f32_type = wasm::GlobalType::make( - wasm::ValType::make(wasm::ValKind::F32), wasm::Mutability::CONST); + wasm::ValueType::make(wasm::ValueKind::F32), wasm::Mutability::CONST); auto const_i64_type = wasm::GlobalType::make( - wasm::ValType::make(wasm::ValKind::I64), wasm::Mutability::CONST); + wasm::ValueType::make(wasm::ValueKind::I64), wasm::Mutability::CONST); auto var_f32_type = wasm::GlobalType::make( - wasm::ValType::make(wasm::ValKind::F32), wasm::Mutability::VAR); + wasm::ValueType::make(wasm::ValueKind::F32), wasm::Mutability::VAR); auto var_i64_type = wasm::GlobalType::make( - wasm::ValType::make(wasm::ValKind::I64), wasm::Mutability::VAR); - auto const_f32_import = wasm::Global::make(store, const_f32_type.get(), wasm::Val::f32(1)); - auto const_i64_import = wasm::Global::make(store, const_i64_type.get(), wasm::Val::i64(2)); - auto var_f32_import = wasm::Global::make(store, var_f32_type.get(), wasm::Val::f32(3)); - auto var_i64_import = wasm::Global::make(store, var_i64_type.get(), wasm::Val::i64(4)); + wasm::ValueType::make(wasm::ValueKind::I64), wasm::Mutability::VAR); + auto const_f32_import = wasm::Global::make(store, const_f32_type.get(), wasm::Value::f32(1)); + auto const_i64_import = wasm::Global::make(store, const_i64_type.get(), wasm::Value::i64(2)); + auto var_f32_import = wasm::Global::make(store, var_f32_type.get(), wasm::Value::f32(3)); + auto var_i64_import = wasm::Global::make(store, var_i64_type.get(), wasm::Value::i64(4)); // Instantiate. std::cout << "Instantiating module..." << std::endl; @@ -154,10 +154,10 @@ void run() { check(call(get_var_i64_export).i64(), 8); // Modify variables through API and check again. - var_f32_import->set(wasm::Val::f32(33)); - var_i64_import->set(wasm::Val::i64(34)); - var_f32_export->set(wasm::Val::f32(37)); - var_i64_export->set(wasm::Val::i64(38)); + var_f32_import->set(wasm::Value::f32(33)); + var_i64_import->set(wasm::Value::i64(34)); + var_f32_export->set(wasm::Value::f32(37)); + var_i64_export->set(wasm::Value::i64(38)); check(var_f32_import->get().f32(), 33); check(var_i64_import->get().i64(), 34); @@ -170,10 +170,10 @@ void run() { check(call(get_var_i64_export).i64(), 38); // Modify variables through calls and check again. - call(set_var_f32_import, wasm::Val::f32(73)); - call(set_var_i64_import, wasm::Val::i64(74)); - call(set_var_f32_export, wasm::Val::f32(77)); - call(set_var_i64_export, wasm::Val::i64(78)); + call(set_var_f32_import, wasm::Value::f32(73)); + call(set_var_i64_import, wasm::Value::i64(74)); + call(set_var_f32_export, wasm::Value::f32(77)); + call(set_var_i64_export, wasm::Value::i64(78)); check(var_f32_import->get().f32(), 73); check(var_i64_import->get().i64(), 74); diff --git a/lib/c-api/tests/wasm-c-api/example/hostref.cc b/lib/c-api/tests/wasm-c-api/example/hostref.cc index 09c239e0c91..f9747b91060 100644 --- a/lib/c-api/tests/wasm-c-api/example/hostref.cc +++ b/lib/c-api/tests/wasm-c-api/example/hostref.cc @@ -9,7 +9,7 @@ // A function to be called from Wasm code. auto callback( - const wasm::vec& args, wasm::vec& results + const wasm::vec& args, wasm::vec& results ) -> wasm::own { std::cout << "Calling back..." << std::endl; std::cout << "> " << (args[0].ref() ? args[0].ref()->get_host_info() : nullptr) << std::endl; @@ -45,8 +45,8 @@ auto get_export_table(wasm::ownvec& exports, size_t i) -> wasm::Ta void call_r_v(const wasm::Func* func, const wasm::Ref* ref) { std::cout << "call_r_v... " << std::flush; - auto args = wasm::vec::make(wasm::Val::ref(ref ? ref->copy() : wasm::own())); - auto results = wasm::vec::make(); + auto args = wasm::vec::make(wasm::Value::ref(ref ? ref->copy() : wasm::own())); + auto results = wasm::vec::make(); if (func->call(args, results)) { std::cout << "> Error calling function!" << std::endl; exit(1); @@ -56,8 +56,8 @@ void call_r_v(const wasm::Func* func, const wasm::Ref* ref) { auto call_v_r(const wasm::Func* func) -> wasm::own { std::cout << "call_v_r... " << std::flush; - auto args = wasm::vec::make(); - auto results = wasm::vec::make_uninitialized(1); + auto args = wasm::vec::make(); + auto results = wasm::vec::make_uninitialized(1); if (func->call(args, results)) { std::cout << "> Error calling function!" << std::endl; exit(1); @@ -68,8 +68,8 @@ auto call_v_r(const wasm::Func* func) -> wasm::own { auto call_r_r(const wasm::Func* func, const wasm::Ref* ref) -> wasm::own { std::cout << "call_r_r... " << std::flush; - auto args = wasm::vec::make(wasm::Val::ref(ref ? ref->copy() : wasm::own())); - auto results = wasm::vec::make_uninitialized(1); + auto args = wasm::vec::make(wasm::Value::ref(ref ? ref->copy() : wasm::own())); + auto results = wasm::vec::make_uninitialized(1); if (func->call(args, results)) { std::cout << "> Error calling function!" << std::endl; exit(1); @@ -80,9 +80,9 @@ auto call_r_r(const wasm::Func* func, const wasm::Ref* ref) -> wasm::own::make( - wasm::Val::i32(i), wasm::Val::ref(ref ? ref->copy() : wasm::own())); - auto results = wasm::vec::make(); + auto args = wasm::vec::make( + wasm::Value::i32(i), wasm::Value::ref(ref ? ref->copy() : wasm::own())); + auto results = wasm::vec::make(); if (func->call(args, results)) { std::cout << "> Error calling function!" << std::endl; exit(1); @@ -92,8 +92,8 @@ void call_ir_v(const wasm::Func* func, int32_t i, const wasm::Ref* ref) { auto call_i_r(const wasm::Func* func, int32_t i) -> wasm::own { std::cout << "call_i_r... " << std::flush; - auto args = wasm::vec::make(wasm::Val::i32(i)); - auto results = wasm::vec::make_uninitialized(1); + auto args = wasm::vec::make(wasm::Value::i32(i)); + auto results = wasm::vec::make_uninitialized(1); if (func->call(args, results)) { std::cout << "> Error calling function!" << std::endl; exit(1); @@ -144,8 +144,8 @@ void run() { // Create external callback function. std::cout << "Creating callback..." << std::endl; auto callback_type = wasm::FuncType::make( - wasm::ownvec::make(wasm::ValType::make(wasm::ValKind::ANYREF)), - wasm::ownvec::make(wasm::ValType::make(wasm::ValKind::ANYREF)) + wasm::ownvec::make(wasm::ValueType::make(wasm::ValueKind::ANYREF)), + wasm::ownvec::make(wasm::ValueType::make(wasm::ValueKind::ANYREF)) ); auto callback_func = wasm::Func::make(store, callback_type.get(), callback); @@ -182,7 +182,7 @@ void run() { check(host1->copy(), host1.get()); check(host2->copy(), host2.get()); - wasm::Val val = wasm::Val::ref(host1->copy()); + wasm::Value val = wasm::Value::ref(host1->copy()); check(val.ref()->copy(), host1.get()); auto ref = val.release_ref(); assert(val.ref() == nullptr); @@ -199,7 +199,7 @@ void run() { check(call_v_r(global_get), nullptr); check(global->get().release_ref(), nullptr); - global->set(wasm::Val(host2->copy())); + global->set(wasm::Value(host2->copy())); check(call_v_r(global_get), host2.get()); check(global->get().release_ref(), host2.get()); diff --git a/lib/c-api/tests/wasm-c-api/example/memory.cc b/lib/c-api/tests/wasm-c-api/example/memory.cc index 6cc36192a85..4f0bf20f3e7 100644 --- a/lib/c-api/tests/wasm-c-api/example/memory.cc +++ b/lib/c-api/tests/wasm-c-api/example/memory.cc @@ -33,8 +33,8 @@ void check(T actual, U expected) { template void check_ok(const wasm::Func* func, Args... xs) { - auto args = wasm::vec::make(wasm::Val::i32(xs)...); - auto results = wasm::vec::make(); + auto args = wasm::vec::make(wasm::Value::i32(xs)...); + auto results = wasm::vec::make(); if (func->call(args, results)) { std::cout << "> Error on result, expected return" << std::endl; exit(1); @@ -43,8 +43,8 @@ void check_ok(const wasm::Func* func, Args... xs) { template void check_trap(const wasm::Func* func, Args... xs) { - auto args = wasm::vec::make(wasm::Val::i32(xs)...); - auto results = wasm::vec::make(); + auto args = wasm::vec::make(wasm::Value::i32(xs)...); + auto results = wasm::vec::make(); if (! func->call(args, results)) { std::cout << "> Error on result, expected trap" << std::endl; exit(1); @@ -53,8 +53,8 @@ void check_trap(const wasm::Func* func, Args... xs) { template auto call(const wasm::Func* func, Args... xs) -> int32_t { - auto args = wasm::vec::make(wasm::Val::i32(xs)...); - auto results = wasm::vec::make_uninitialized(1); + auto args = wasm::vec::make(wasm::Value::i32(xs)...); + auto results = wasm::vec::make_uninitialized(1); if (func->call(args, results)) { std::cout << "> Error on result, expected return" << std::endl; exit(1); diff --git a/lib/c-api/tests/wasm-c-api/example/multi.cc b/lib/c-api/tests/wasm-c-api/example/multi.cc index 6d083557114..7c167a727e1 100644 --- a/lib/c-api/tests/wasm-c-api/example/multi.cc +++ b/lib/c-api/tests/wasm-c-api/example/multi.cc @@ -8,7 +8,7 @@ // A function to be called from Wasm code. auto callback( - const wasm::vec& args, wasm::vec& results + const wasm::vec& args, wasm::vec& results ) -> wasm::own { std::cout << "Calling back..." << std::endl; std::cout << "> " << args[0].i32(); @@ -54,11 +54,11 @@ void run() { // Create external print functions. std::cout << "Creating callback..." << std::endl; - auto tuple = wasm::ownvec::make( - wasm::ValType::make(wasm::ValKind::I32), - wasm::ValType::make(wasm::ValKind::I64), - wasm::ValType::make(wasm::ValKind::I64), - wasm::ValType::make(wasm::ValKind::I32) + auto tuple = wasm::ownvec::make( + wasm::ValueType::make(wasm::ValueKind::I32), + wasm::ValueType::make(wasm::ValueKind::I64), + wasm::ValueType::make(wasm::ValueKind::I64), + wasm::ValueType::make(wasm::ValueKind::I32) ); auto callback_type = wasm::FuncType::make(tuple.deep_copy(), tuple.deep_copy()); @@ -84,10 +84,10 @@ void run() { // Call. std::cout << "Calling export..." << std::endl; - auto args = wasm::vec::make( - wasm::Val::i32(1), wasm::Val::i64(2), wasm::Val::i64(3), wasm::Val::i32(4) + auto args = wasm::vec::make( + wasm::Value::i32(1), wasm::Value::i64(2), wasm::Value::i64(3), wasm::Value::i32(4) ); - auto results = wasm::vec::make_uninitialized(4); + auto results = wasm::vec::make_uninitialized(4); if (wasm::own trap = run_func->call(args, results)) { std::cout << "> Error calling function! " << trap->message().get() << std::endl; exit(1); diff --git a/lib/c-api/tests/wasm-c-api/example/table.cc b/lib/c-api/tests/wasm-c-api/example/table.cc index 9ddf1d902bf..d937ec9038a 100644 --- a/lib/c-api/tests/wasm-c-api/example/table.cc +++ b/lib/c-api/tests/wasm-c-api/example/table.cc @@ -9,10 +9,10 @@ // A function to be called from Wasm code. auto neg_callback( - const wasm::vec& args, wasm::vec& results + const wasm::vec& args, wasm::vec& results ) -> wasm::own { std::cout << "Calling back..." << std::endl; - results[0] = wasm::Val(-args[0].i32()); + results[0] = wasm::Value(-args[0].i32()); return nullptr; } @@ -49,10 +49,10 @@ void check(bool success) { } auto call( - const wasm::Func* func, wasm::Val&& arg1, wasm::Val&& arg2 -) -> wasm::Val { - auto args = wasm::vec::make(std::move(arg1), std::move(arg2)); - auto results = wasm::vec::make_uninitialized(1); + const wasm::Func* func, wasm::Value&& arg1, wasm::Value&& arg2 +) -> wasm::Value { + auto args = wasm::vec::make(std::move(arg1), std::move(arg2)); + auto results = wasm::vec::make_uninitialized(1); if (func->call(args, results)) { std::cout << "> Error on result, expected return" << std::endl; exit(1); @@ -60,9 +60,9 @@ auto call( return results[0].copy(); } -void check_trap(const wasm::Func* func, wasm::Val&& arg1, wasm::Val&& arg2) { - auto args = wasm::vec::make(std::move(arg1), std::move(arg2)); - auto results = wasm::vec::make_uninitialized(1); +void check_trap(const wasm::Func* func, wasm::Value&& arg1, wasm::Value&& arg2) { + auto args = wasm::vec::make(std::move(arg1), std::move(arg2)); + auto results = wasm::vec::make_uninitialized(1); if (! func->call(args, results)) { std::cout << "> Error on result, expected trap" << std::endl; exit(1); @@ -119,8 +119,8 @@ void run() { // Create external function. std::cout << "Creating callback..." << std::endl; auto neg_type = wasm::FuncType::make( - wasm::ownvec::make(wasm::ValType::make(wasm::ValKind::I32)), - wasm::ownvec::make(wasm::ValType::make(wasm::ValKind::I32)) + wasm::ownvec::make(wasm::ValueType::make(wasm::ValueKind::I32)), + wasm::ownvec::make(wasm::ValueType::make(wasm::ValueKind::I32)) ); auto h = wasm::Func::make(store, neg_type.get(), neg_callback); @@ -132,9 +132,9 @@ void run() { check(table->size(), 2u); check(table->get(0) == nullptr); check(table->get(1) != nullptr); - check_trap(call_indirect, wasm::Val::i32(0), wasm::Val::i32(0)); - check(call(call_indirect, wasm::Val::i32(7), wasm::Val::i32(1)).i32(), 7); - check_trap(call_indirect, wasm::Val::i32(0), wasm::Val::i32(2)); + check_trap(call_indirect, wasm::Value::i32(0), wasm::Value::i32(0)); + check(call(call_indirect, wasm::Value::i32(7), wasm::Value::i32(1)).i32(), 7); + check_trap(call_indirect, wasm::Value::i32(0), wasm::Value::i32(2)); // Mutate table. std::cout << "Mutating table..." << std::endl; @@ -143,9 +143,9 @@ void run() { check(! table->set(2, f)); check(table->get(0) != nullptr); check(table->get(1) == nullptr); - check(call(call_indirect, wasm::Val::i32(7), wasm::Val::i32(0)).i32(), 666); - check_trap(call_indirect, wasm::Val::i32(0), wasm::Val::i32(1)); - check_trap(call_indirect, wasm::Val::i32(0), wasm::Val::i32(2)); + check(call(call_indirect, wasm::Value::i32(7), wasm::Value::i32(0)).i32(), 666); + check_trap(call_indirect, wasm::Value::i32(0), wasm::Value::i32(1)); + check_trap(call_indirect, wasm::Value::i32(0), wasm::Value::i32(2)); // Grow table. std::cout << "Growing table..." << std::endl; @@ -157,10 +157,10 @@ void run() { check(table->get(2) != nullptr); check(table->get(3) != nullptr); check(table->get(4) == nullptr); - check(call(call_indirect, wasm::Val::i32(5), wasm::Val::i32(2)).i32(), 5); - check(call(call_indirect, wasm::Val::i32(6), wasm::Val::i32(3)).i32(), -6); - check_trap(call_indirect, wasm::Val::i32(0), wasm::Val::i32(4)); - check_trap(call_indirect, wasm::Val::i32(0), wasm::Val::i32(5)); + check(call(call_indirect, wasm::Value::i32(5), wasm::Value::i32(2)).i32(), 5); + check(call(call_indirect, wasm::Value::i32(6), wasm::Value::i32(3)).i32(), -6); + check_trap(call_indirect, wasm::Value::i32(0), wasm::Value::i32(4)); + check_trap(call_indirect, wasm::Value::i32(0), wasm::Value::i32(5)); check(table->grow(2, f)); check(table->size(), 7u); @@ -175,7 +175,7 @@ void run() { // TODO(wasm+): Once Wasm allows multiple tables, turn this into import. std::cout << "Creating stand-alone table..." << std::endl; auto tabletype = wasm::TableType::make( - wasm::ValType::make(wasm::ValKind::FUNCREF), wasm::Limits(5, 5)); + wasm::ValueType::make(wasm::ValueKind::FUNCREF), wasm::Limits(5, 5)); auto table2 = wasm::Table::make(store, tabletype.get()); check(table2->size() == 5); check(! table2->grow(1)); diff --git a/lib/c-api/tests/wasm-c-api/example/threads.cc b/lib/c-api/tests/wasm-c-api/example/threads.cc index e130717a0cf..cde5f3a3676 100644 --- a/lib/c-api/tests/wasm-c-api/example/threads.cc +++ b/lib/c-api/tests/wasm-c-api/example/threads.cc @@ -10,9 +10,9 @@ const int N_REPS = 3; // A function to be called from Wasm code. auto callback( - void* env, const wasm::vec& args, wasm::vec& results + void* env, const wasm::vec& args, wasm::vec& results ) -> wasm::own { - assert(args[0].kind() == wasm::ValKind::I32); + assert(args[0].kind() == wasm::ValueKind::I32); std::lock_guard lock(*reinterpret_cast(env)); std::cout << "Thread " << args[0].i32() << " running..." << std::endl; std::cout.flush(); @@ -42,15 +42,15 @@ void run( // Create imports. auto func_type = wasm::FuncType::make( - wasm::ownvec::make(wasm::ValType::make(wasm::ValKind::I32)), - wasm::ownvec::make() + wasm::ownvec::make(wasm::ValueType::make(wasm::ValueKind::I32)), + wasm::ownvec::make() ); auto func = wasm::Func::make(store, func_type.get(), callback, mutex); auto global_type = wasm::GlobalType::make( - wasm::ValType::make(wasm::ValKind::I32), wasm::Mutability::CONST); + wasm::ValueType::make(wasm::ValueKind::I32), wasm::Mutability::CONST); auto global = wasm::Global::make( - store, global_type.get(), wasm::Val::i32(i)); + store, global_type.get(), wasm::Value::i32(i)); // Instantiate. auto imports = wasm::vec::make(func.get(), global.get()); @@ -71,7 +71,7 @@ void run( auto run_func = exports[0]->func(); // Call. - auto empty = wasm::vec::make(); + auto empty = wasm::vec::make(); run_func->call(empty, empty); } } diff --git a/lib/c-api/tests/wasm-c-api/example/trap.c b/lib/c-api/tests/wasm-c-api/example/trap.c index 1146f69e621..7b13d673539 100644 --- a/lib/c-api/tests/wasm-c-api/example/trap.c +++ b/lib/c-api/tests/wasm-c-api/example/trap.c @@ -7,14 +7,16 @@ #define own +wasm_store_t* store = NULL; + // A function to be called from Wasm code. own wasm_trap_t* fail_callback( - void* env, const wasm_val_vec_t* args, wasm_val_vec_t* results + const wasm_val_vec_t* args, wasm_val_vec_t* results ) { printf("Calling back...\n"); own wasm_name_t message; wasm_name_new_from_string_nt(&message, "callback abort"); - own wasm_trap_t* trap = wasm_trap_new((wasm_store_t*)env, &message); + own wasm_trap_t* trap = wasm_trap_new(store, &message); wasm_name_delete(&message); return trap; } @@ -34,7 +36,7 @@ int main(int argc, const char* argv[]) { // Initialize. printf("Initializing...\n"); wasm_engine_t* engine = wasm_engine_new(); - wasm_store_t* store = wasm_store_new(engine); + store = wasm_store_new(engine); // Load binary. printf("Loading binary...\n"); @@ -69,7 +71,7 @@ int main(int argc, const char* argv[]) { own wasm_functype_t* fail_type = wasm_functype_new_0_1(wasm_valtype_new_i32()); own wasm_func_t* fail_func = - wasm_func_new_with_env(store, fail_type, fail_callback, store, NULL); + wasm_func_new(store, fail_type, fail_callback); wasm_functype_delete(fail_type); diff --git a/lib/c-api/tests/wasm-c-api/include/wasm.h b/lib/c-api/tests/wasm-c-api/include/wasm.h index 25e0453a3ab..6540804cd67 100644 --- a/lib/c-api/tests/wasm-c-api/include/wasm.h +++ b/lib/c-api/tests/wasm-c-api/include/wasm.h @@ -143,6 +143,13 @@ WASM_DECLARE_OWN(store) WASM_API_EXTERN own wasm_store_t* wasm_store_new(wasm_engine_t*); +// Context + +WASM_DECLARE_OWN(context) + +WASM_API_EXTERN own void wasm_store_context_set(own wasm_store_t*, own wasm_context_t*); +WASM_API_EXTERN own void wasm_store_data_set(own wasm_store_t*, own void*); +WASM_API_EXTERN own void* wasm_store_data_get(own wasm_store_t*); /////////////////////////////////////////////////////////////////////////////// // Type Representations @@ -420,9 +427,6 @@ typedef own wasm_trap_t* (*wasm_func_callback_with_env_t)( WASM_API_EXTERN own wasm_func_t* wasm_func_new( wasm_store_t*, const wasm_functype_t*, wasm_func_callback_t); -WASM_API_EXTERN own wasm_func_t* wasm_func_new_with_env( - wasm_store_t*, const wasm_functype_t* type, wasm_func_callback_with_env_t, - void* env, void (*finalizer)(void*)); WASM_API_EXTERN own wasm_functype_t* wasm_func_type(const wasm_func_t*); WASM_API_EXTERN size_t wasm_func_param_arity(const wasm_func_t*); diff --git a/lib/c-api/tests/wasm-c-api/include/wasm.hh b/lib/c-api/tests/wasm-c-api/include/wasm.hh index 597c10f4d8c..f0b3ee21a78 100644 --- a/lib/c-api/tests/wasm-c-api/include/wasm.hh +++ b/lib/c-api/tests/wasm-c-api/include/wasm.hh @@ -128,7 +128,7 @@ public: return v; } - // TODO: This can't be used for e.g. vec + // TODO: This can't be used for e.g. vec auto deep_copy() const -> vec { auto v = vec(size_); if (v) for (size_t i = 0; i < size_; ++i) v.data_[i] = data_[i]->copy(); @@ -246,25 +246,25 @@ struct Limits { // Value Types -enum class ValKind : uint8_t { +enum class ValueKind : uint8_t { I32, I64, F32, F64, ANYREF = 128, FUNCREF, }; -inline bool is_num(ValKind k) { return k < ValKind::ANYREF; } -inline bool is_ref(ValKind k) { return k >= ValKind::ANYREF; } +inline bool is_num(ValueKind k) { return k < ValueKind::ANYREF; } +inline bool is_ref(ValueKind k) { return k >= ValueKind::ANYREF; } -class WASM_API_EXTERN ValType { +class WASM_API_EXTERN ValueType { public: - ValType() = delete; - ~ValType(); + ValueType() = delete; + ~ValueType(); void operator delete(void*); - static auto make(ValKind) -> own; - auto copy() const -> own; + static auto make(ValueKind) -> own; + auto copy() const -> own; - auto kind() const -> ValKind; + auto kind() const -> ValueKind; auto is_num() const -> bool { return wasm::is_num(kind()); } auto is_ref() const -> bool { return wasm::is_ref(kind()); } }; @@ -311,14 +311,14 @@ public: ~FuncType(); static auto make( - ownvec&& params = ownvec::make(), - ownvec&& results = ownvec::make() + ownvec&& params = ownvec::make(), + ownvec&& results = ownvec::make() ) -> own; auto copy() const -> own; - auto params() const -> const ownvec&; - auto results() const -> const ownvec&; + auto params() const -> const ownvec&; + auto results() const -> const ownvec&; }; @@ -329,10 +329,10 @@ public: GlobalType() = delete; ~GlobalType(); - static auto make(own&&, Mutability) -> own; + static auto make(own&&, Mutability) -> own; auto copy() const -> own; - auto content() const -> const ValType*; + auto content() const -> const ValueType*; auto mutability() const -> Mutability; }; @@ -344,10 +344,10 @@ public: TableType() = delete; ~TableType(); - static auto make(own&&, Limits) -> own; + static auto make(own&&, Limits) -> own; auto copy() const -> own; - auto element() const -> const ValType*; + auto element() const -> const ValueType*; auto limits() const -> const Limits&; }; @@ -423,8 +423,8 @@ public: // Values -class Val { - ValKind kind_; +class Value { + ValueKind kind_; union impl { int32_t i32; int64_t i64; @@ -433,34 +433,34 @@ class Val { Ref* ref; } impl_; - Val(ValKind kind, impl impl) : kind_(kind), impl_(impl) {} + Value(ValueKind kind, impl impl) : kind_(kind), impl_(impl) {} public: - Val() : kind_(ValKind::ANYREF) { impl_.ref = nullptr; } - explicit Val(int32_t i) : kind_(ValKind::I32) { impl_.i32 = i; } - explicit Val(int64_t i) : kind_(ValKind::I64) { impl_.i64 = i; } - explicit Val(float32_t z) : kind_(ValKind::F32) { impl_.f32 = z; } - explicit Val(float64_t z) : kind_(ValKind::F64) { impl_.f64 = z; } - explicit Val(own&& r) : kind_(ValKind::ANYREF) { impl_.ref = r.release(); } - - Val(Val&& that) : kind_(that.kind_), impl_(that.impl_) { + Value() : kind_(ValueKind::ANYREF) { impl_.ref = nullptr; } + explicit Value(int32_t i) : kind_(ValueKind::I32) { impl_.i32 = i; } + explicit Value(int64_t i) : kind_(ValueKind::I64) { impl_.i64 = i; } + explicit Value(float32_t z) : kind_(ValueKind::F32) { impl_.f32 = z; } + explicit Value(float64_t z) : kind_(ValueKind::F64) { impl_.f64 = z; } + explicit Value(own&& r) : kind_(ValueKind::ANYREF) { impl_.ref = r.release(); } + + Value(Value&& that) : kind_(that.kind_), impl_(that.impl_) { if (is_ref()) that.impl_.ref = nullptr; } - ~Val() { + ~Value() { reset(); } auto is_num() const -> bool { return wasm::is_num(kind_); } auto is_ref() const -> bool { return wasm::is_ref(kind_); } - static auto i32(int32_t x) -> Val { return Val(x); } - static auto i64(int64_t x) -> Val { return Val(x); } - static auto f32(float32_t x) -> Val { return Val(x); } - static auto f64(float64_t x) -> Val { return Val(x); } - static auto ref(own&& x) -> Val { return Val(std::move(x)); } - template inline static auto make(T x) -> Val; - template inline static auto make(own&& x) -> Val; + static auto i32(int32_t x) -> Value { return Value(x); } + static auto i64(int64_t x) -> Value { return Value(x); } + static auto f32(float32_t x) -> Value { return Value(x); } + static auto f64(float64_t x) -> Value { return Value(x); } + static auto ref(own&& x) -> Value { return Value(std::move(x)); } + template inline static auto make(T x) -> Value; + template inline static auto make(own&& x) -> Value; void reset() { if (is_ref() && impl_.ref) { @@ -469,23 +469,23 @@ public: } } - void reset(Val& that) { + void reset(Value& that) { reset(); kind_ = that.kind_; impl_ = that.impl_; if (is_ref()) that.impl_.ref = nullptr; } - auto operator=(Val&& that) -> Val& { + auto operator=(Value&& that) -> Value& { reset(that); return *this; } - auto kind() const -> ValKind { return kind_; } - auto i32() const -> int32_t { assert(kind_ == ValKind::I32); return impl_.i32; } - auto i64() const -> int64_t { assert(kind_ == ValKind::I64); return impl_.i64; } - auto f32() const -> float32_t { assert(kind_ == ValKind::F32); return impl_.f32; } - auto f64() const -> float64_t { assert(kind_ == ValKind::F64); return impl_.f64; } + auto kind() const -> ValueKind { return kind_; } + auto i32() const -> int32_t { assert(kind_ == ValueKind::I32); return impl_.i32; } + auto i64() const -> int64_t { assert(kind_ == ValueKind::I64); return impl_.i64; } + auto f32() const -> float32_t { assert(kind_ == ValueKind::F32); return impl_.f32; } + auto f64() const -> float64_t { assert(kind_ == ValueKind::F64); return impl_.f64; } auto ref() const -> Ref* { assert(is_ref()); return impl_.ref; } template inline auto get() const -> T; @@ -496,45 +496,45 @@ public: return own(ref); } - auto copy() const -> Val { + auto copy() const -> Value { if (is_ref() && impl_.ref != nullptr) { // TODO(mvsc): MVSC cannot handle this: // impl impl = {.ref = impl_.ref->copy().release()}; impl impl; impl.ref = impl_.ref->copy().release(); - return Val(kind_, impl); + return Value(kind_, impl); } else { - return Val(kind_, impl_); + return Value(kind_, impl_); } } }; -template<> inline auto Val::make(int32_t x) -> Val { return Val(x); } -template<> inline auto Val::make(int64_t x) -> Val { return Val(x); } -template<> inline auto Val::make(float32_t x) -> Val { return Val(x); } -template<> inline auto Val::make(float64_t x) -> Val { return Val(x); } -template<> inline auto Val::make(own&& x) -> Val { - return Val(std::move(x)); +template<> inline auto Value::make(int32_t x) -> Value { return Value(x); } +template<> inline auto Value::make(int64_t x) -> Value { return Value(x); } +template<> inline auto Value::make(float32_t x) -> Value { return Value(x); } +template<> inline auto Value::make(float64_t x) -> Value { return Value(x); } +template<> inline auto Value::make(own&& x) -> Value { + return Value(std::move(x)); } -template<> inline auto Val::make(uint32_t x) -> Val { - return Val(static_cast(x)); +template<> inline auto Value::make(uint32_t x) -> Value { + return Value(static_cast(x)); } -template<> inline auto Val::make(uint64_t x) -> Val { - return Val(static_cast(x)); +template<> inline auto Value::make(uint64_t x) -> Value { + return Value(static_cast(x)); } -template<> inline auto Val::get() const -> int32_t { return i32(); } -template<> inline auto Val::get() const -> int64_t { return i64(); } -template<> inline auto Val::get() const -> float32_t { return f32(); } -template<> inline auto Val::get() const -> float64_t { return f64(); } -template<> inline auto Val::get() const -> Ref* { return ref(); } +template<> inline auto Value::get() const -> int32_t { return i32(); } +template<> inline auto Value::get() const -> int64_t { return i64(); } +template<> inline auto Value::get() const -> float32_t { return f32(); } +template<> inline auto Value::get() const -> float64_t { return f64(); } +template<> inline auto Value::get() const -> Ref* { return ref(); } -template<> inline auto Val::get() const -> uint32_t { +template<> inline auto Value::get() const -> uint32_t { return static_cast(i32()); } -template<> inline auto Val::get() const -> uint64_t { +template<> inline auto Value::get() const -> uint64_t { return static_cast(i64()); } @@ -654,8 +654,8 @@ public: Func() = delete; ~Func(); - using callback = auto (*)(const vec&, vec&) -> own; - using callback_with_env = auto (*)(void*, const vec&, vec&) -> own; + using callback = auto (*)(const vec&, vec&) -> own; + using callback_with_env = auto (*)(void*, const vec&, vec&) -> own; static auto make(Store*, const FuncType*, callback) -> own; static auto make(Store*, const FuncType*, callback_with_env, @@ -666,7 +666,7 @@ public: auto param_arity() const -> size_t; auto result_arity() const -> size_t; - auto call(const vec&, vec&) const -> own; + auto call(const vec&, vec&) const -> own; }; @@ -677,12 +677,12 @@ public: Global() = delete; ~Global(); - static auto make(Store*, const GlobalType*, const Val&) -> own; + static auto make(Store*, const GlobalType*, const Value&) -> own; auto copy() const -> own; auto type() const -> own; - auto get() const -> Val; - void set(const Val&); + auto get() const -> Value; + void set(const Value&); }; diff --git a/lib/c-api/tests/wasm-c-api/src/wasm-c.cc b/lib/c-api/tests/wasm-c-api/src/wasm-c.cc index b4316116148..23f8151c77b 100644 --- a/lib/c-api/tests/wasm-c-api/src/wasm-c.cc +++ b/lib/c-api/tests/wasm-c-api/src/wasm-c.cc @@ -815,14 +815,6 @@ wasm_func_t* wasm_func_new( store, type, wasm_callback, reinterpret_cast(callback))); } -wasm_func_t *wasm_func_new_with_env( - wasm_store_t* store, const wasm_functype_t* type, - wasm_func_callback_with_env_t callback, void *env, void (*finalizer)(void*) -) { - auto env2 = new wasm_callback_env_t{callback, env, finalizer}; - return release_func(Func::make(store, type, wasm_callback_with_env, env2, wasm_callback_env_finalizer)); -} - wasm_functype_t* wasm_func_type(const wasm_func_t* func) { return release_functype(func->type()); } diff --git a/lib/cli/src/commands/run.rs b/lib/cli/src/commands/run.rs index 0e9c5adb1c3..fc9a29fb374 100644 --- a/lib/cli/src/commands/run.rs +++ b/lib/cli/src/commands/run.rs @@ -111,7 +111,7 @@ impl Run { let imports = imports! {}; let instance = Instance::new(&mut ctx, &module, &imports)?; let result = - self.invoke_function(&mut ctx.as_context_mut(), &instance, &invoke, &self.args)?; + self.invoke_function(&mut ctx.as_context_mut(), &instance, invoke, &self.args)?; println!( "{}", result @@ -383,7 +383,7 @@ impl Run { invoke: &str, args: &[String], ) -> Result> { - let func: Function = self.try_find_function(&instance, invoke, args)?; + let func: Function = self.try_find_function(instance, invoke, args)?; let func_ty = func.ty(ctx); let required_arguments = func_ty.params().len(); let provided_arguments = args.len(); diff --git a/lib/cli/src/commands/run/wasi.rs b/lib/cli/src/commands/run/wasi.rs index 60be4660e33..5cf8287edde 100644 --- a/lib/cli/src/commands/run/wasi.rs +++ b/lib/cli/src/commands/run/wasi.rs @@ -104,9 +104,9 @@ impl Wasi { is_wasix_module(module), std::sync::atomic::Ordering::Release, ); - let mut ctx = Context::new(module.store(), wasi_env.clone()); + let mut ctx = Context::new(module.store(), wasi_env); let import_object = import_object_for_all_wasi_versions(&mut ctx.as_context_mut()); - let instance = Instance::new(&mut ctx, &module, &import_object)?; + let instance = Instance::new(&mut ctx, module, &import_object)?; let memory = instance.exports.get_memory("memory")?; ctx.data_mut().set_memory(memory.clone()); Ok((ctx, instance)) From 53d721928db085d7762d3f4e29cd4f436d98a272 Mon Sep 17 00:00:00 2001 From: Manos Pitsidianakis Date: Tue, 28 Jun 2022 15:12:03 +0300 Subject: [PATCH 3/3] lib/compiler: delete left-over file --- lib/compiler/src/engine/export.rs | 166 ------------------------------ 1 file changed, 166 deletions(-) delete mode 100644 lib/compiler/src/engine/export.rs diff --git a/lib/compiler/src/engine/export.rs b/lib/compiler/src/engine/export.rs deleted file mode 100644 index 2fc80458c20..00000000000 --- a/lib/compiler/src/engine/export.rs +++ /dev/null @@ -1,166 +0,0 @@ -use std::sync::Arc; -use wasmer_vm::{ImportInitializerFuncPtr, VMExtern, VMFunction, VMGlobal, VMMemory, VMTable}; - -/// The value of an export passed from one instance to another. -#[derive(Debug, Clone)] -pub enum Export { - /// A function export value. - Function(ExportFunction), - - /// A table export value. - Table(VMTable), - - /// A memory export value. - Memory(VMMemory), - - /// A global export value. - Global(VMGlobal), -} - -impl From for VMExtern { - fn from(other: Export) -> Self { - match other { - Export::Function(ExportFunction { vm_function, .. }) => Self::Function(vm_function), - Export::Memory(vm_memory) => Self::Memory(vm_memory), - Export::Table(vm_table) => Self::Table(vm_table), - Export::Global(vm_global) => Self::Global(vm_global), - } - } -} - -impl From for Export { - fn from(other: VMExtern) -> Self { - match other { - VMExtern::Function(vm_function) => Self::Function(ExportFunction { - vm_function, - metadata: None, - }), - VMExtern::Memory(vm_memory) => Self::Memory(vm_memory), - VMExtern::Table(vm_table) => Self::Table(vm_table), - VMExtern::Global(vm_global) => Self::Global(vm_global), - } - } -} - -/// Extra metadata about `ExportFunction`s. -/// -/// The metadata acts as a kind of manual virtual dispatch. We store the -/// user-supplied `WasmerEnv` as a void pointer and have methods on it -/// that have been adapted to accept a void pointer. -/// -/// This struct owns the original `host_env`, thus when it gets dropped -/// it calls the `drop` function on it. -#[derive(Debug, PartialEq)] -pub struct ExportFunctionMetadata { - /// This field is stored here to be accessible by `Drop`. - /// - /// At the time it was added, it's not accessed anywhere outside of - /// the `Drop` implementation. This field is the "master copy" of the env, - /// that is, the original env passed in by the user. Every time we create - /// an `Instance` we clone this with the `host_env_clone_fn` field. - /// - /// Thus, we only bother to store the master copy at all here so that - /// we can free it. - /// - /// See `wasmer_vm::export::VMFunction::vmctx` for the version of - /// this pointer that is used by the VM when creating an `Instance`. - pub(crate) host_env: *mut std::ffi::c_void, - - /// Function pointer to `WasmerEnv::init_with_instance(&mut self, instance: &Instance)`. - /// - /// This function is called to finish setting up the environment after - /// we create the `api::Instance`. - // This one is optional for now because dynamic host envs need the rest - // of this without the init fn - pub(crate) import_init_function_ptr: Option, - - /// A function analogous to `Clone::clone` that returns a leaked `Box`. - pub(crate) host_env_clone_fn: fn(*mut std::ffi::c_void) -> *mut std::ffi::c_void, - - /// The destructor to free the host environment. - /// - /// # Safety - /// - This function should only be called in when properly synchronized. - /// For example, in the `Drop` implementation of this type. - pub(crate) host_env_drop_fn: unsafe fn(*mut std::ffi::c_void), -} - -/// This can be `Send` because `host_env` comes from `WasmerEnv` which is -/// `Send`. Therefore all operations should work on any thread. -unsafe impl Send for ExportFunctionMetadata {} -/// This data may be shared across threads, `drop` is an unsafe function -/// pointer, so care must be taken when calling it. -unsafe impl Sync for ExportFunctionMetadata {} - -impl ExportFunctionMetadata { - /// Create an `ExportFunctionMetadata` type with information about - /// the exported function. - /// - /// # Safety - /// - the `host_env` must be `Send`. - /// - all function pointers must work on any thread. - pub unsafe fn new( - host_env: *mut std::ffi::c_void, - import_init_function_ptr: Option, - host_env_clone_fn: fn(*mut std::ffi::c_void) -> *mut std::ffi::c_void, - host_env_drop_fn: fn(*mut std::ffi::c_void), - ) -> Self { - Self { - host_env, - import_init_function_ptr, - host_env_clone_fn, - host_env_drop_fn, - } - } -} - -// We have to free `host_env` here because we always clone it before using it -// so all the `host_env`s freed at the `Instance` level won't touch the original. -impl Drop for ExportFunctionMetadata { - fn drop(&mut self) { - if !self.host_env.is_null() { - // # Safety - // - This is correct because we know no other references - // to this data can exist if we're dropping it. - unsafe { - (self.host_env_drop_fn)(self.host_env); - } - } - } -} - -/// A function export value with an extra function pointer to initialize -/// host environments. -#[derive(Debug, Clone, PartialEq)] -pub struct ExportFunction { - /// The VM function, containing most of the data. - pub vm_function: VMFunction, - /// Contains functions necessary to create and initialize host envs - /// with each `Instance` as well as being responsible for the - /// underlying memory of the host env. - pub metadata: Option>, -} - -impl From for Export { - fn from(func: ExportFunction) -> Self { - Self::Function(func) - } -} - -impl From for Export { - fn from(table: VMTable) -> Self { - Self::Table(table) - } -} - -impl From for Export { - fn from(memory: VMMemory) -> Self { - Self::Memory(memory) - } -} - -impl From for Export { - fn from(global: VMGlobal) -> Self { - Self::Global(global) - } -}