From 045d6a731019009d56a34ad50a63d6faa2d5aa00 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 7 Jan 2020 16:29:44 -0600 Subject: [PATCH] Remove the need for `HostRef` (#771) * Remove the need for `HostRef` This commit goes through the public API of the `wasmtime` crate and removes the need for `HostRef`, as discussed in #708. This commit is accompanied with a few changes: * The `Store` type now also implements `Default`, creating a new `Engine` with default settings and returning that. * The `Store` type now implements `Clone`, and is documented as being a "cheap clone" aka being reference counted. As before there is no supported way to create a deep clone of a `Store`. * All APIs take/return `&Store` or `Store` instead of `HostRef`, and `HostRef` is left as purely a detail of the C API. * The `global_exports` function is tagged as `#[doc(hidden)]` for now while we await its removal. * The `Store` type is not yet `Send` nor `Sync` due to the usage of `global_exports`, but it is intended to become so eventually. * Touch up comments on some examples * Run rustfmt --- crates/api/examples/gcd.rs | 17 ++--- crates/api/examples/hello.rs | 15 ++-- crates/api/examples/memory.rs | 3 +- crates/api/examples/multi.rs | 2 +- crates/api/src/callable.rs | 14 ++-- crates/api/src/context.rs | 2 +- crates/api/src/externals.rs | 35 +++++----- crates/api/src/instance.rs | 12 ++-- crates/api/src/module.rs | 13 ++-- crates/api/src/runtime.rs | 70 ++++++++++++++----- crates/api/src/trampoline/create_handle.rs | 6 +- crates/api/src/trampoline/func.rs | 5 +- crates/api/src/trampoline/mod.rs | 3 +- crates/api/src/values.rs | 10 ++- crates/api/src/wasm.rs | 23 +++--- crates/api/tests/import_calling_export.rs | 3 +- crates/api/tests/traps.rs | 3 +- crates/fuzzing/src/oracles.rs | 6 +- crates/fuzzing/src/oracles/dummy.rs | 13 ++-- crates/misc/py/src/function.rs | 2 +- crates/misc/py/src/lib.rs | 8 +-- crates/misc/rust/macro/src/lib.rs | 4 +- .../test-programs/tests/wasm_tests/runtime.rs | 7 +- crates/wasi/src/instantiate.rs | 4 +- crates/wasi/src/old/snapshot_0/instantiate.rs | 4 +- crates/wast/src/spectest.rs | 4 +- crates/wast/src/wast.rs | 4 +- docs/embed-rust.md | 8 +-- src/commands/run.rs | 10 +-- src/commands/wast.rs | 4 +- tests/wast_testsuites.rs | 4 +- 31 files changed, 163 insertions(+), 155 deletions(-) diff --git a/crates/api/examples/gcd.rs b/crates/api/examples/gcd.rs index 405d73e9f1..033e90e98c 100644 --- a/crates/api/examples/gcd.rs +++ b/crates/api/examples/gcd.rs @@ -1,7 +1,6 @@ //! Example of instantiating of the WebAssembly module and //! invoking its exported function. -use anyhow::{format_err, Result}; use wasmtime::*; const WAT: &str = r#" @@ -34,14 +33,11 @@ const WAT: &str = r#" ) "#; -fn main() -> Result<()> { +fn main() -> anyhow::Result<()> { + // Load our WebAssembly (parsed WAT in our case), and then load it into a + // `Module` which is attached to a `Store` cache. let wasm = wat::parse_str(WAT)?; - - // Instantiate engine and store. - let engine = Engine::default(); - let store = HostRef::new(Store::new(&engine)); - - // Load a module. + let store = Store::default(); let module = HostRef::new(Module::new(&store, &wasm)?); // Find index of the `gcd` export. @@ -59,10 +55,7 @@ fn main() -> Result<()> { // Invoke `gcd` export let gcd = instance.exports()[gcd_index].func().expect("gcd"); - let result = gcd - .borrow() - .call(&[Val::from(6i32), Val::from(27i32)]) - .map_err(|e| format_err!("call error: {:?}", e))?; + let result = gcd.borrow().call(&[Val::from(6i32), Val::from(27i32)])?; println!("{:?}", result); Ok(()) diff --git a/crates/api/examples/hello.rs b/crates/api/examples/hello.rs index 09462cb334..6d2044e223 100644 --- a/crates/api/examples/hello.rs +++ b/crates/api/examples/hello.rs @@ -1,6 +1,6 @@ //! Translation of hello example -use anyhow::{ensure, format_err, Context as _, Result}; +use anyhow::{ensure, Context as _, Result}; use std::rc::Rc; use wasmtime::*; @@ -15,11 +15,11 @@ impl Callable for HelloCallback { } fn main() -> Result<()> { - // Configure the initial compilation environment, creating more global - // structures such as an `Engine` and a `Store`. + // Configure the initial compilation environment, creating the global + // `Store` structure. Note that you can also tweak configuration settings + // with a `Config` and an `Engine` if desired. println!("Initializing..."); - let engine = Engine::default(); - let store = HostRef::new(Store::new(&engine)); + let store = Store::default(); // Next upload the `*.wasm` binary file, which in this case we're going to // be parsing an inline text format into a binary. @@ -59,10 +59,7 @@ fn main() -> Result<()> { // And last but not least we can call it! println!("Calling export..."); - run_func - .borrow() - .call(&[]) - .map_err(|e| format_err!("> Error calling function: {:?}", e))?; + run_func.borrow().call(&[])?; println!("Done."); Ok(()) diff --git a/crates/api/examples/memory.rs b/crates/api/examples/memory.rs index 0c11c58a9d..05b93711e8 100644 --- a/crates/api/examples/memory.rs +++ b/crates/api/examples/memory.rs @@ -62,8 +62,7 @@ macro_rules! call { fn main() -> Result<(), Error> { // Initialize. println!("Initializing..."); - let engine = Engine::default(); - let store = HostRef::new(Store::new(&engine)); + let store = Store::default(); // Load binary. println!("Loading binary..."); diff --git a/crates/api/examples/multi.rs b/crates/api/examples/multi.rs index 764b777d05..13b06d1bd3 100644 --- a/crates/api/examples/multi.rs +++ b/crates/api/examples/multi.rs @@ -46,7 +46,7 @@ fn main() -> Result<()> { // Initialize. println!("Initializing..."); let engine = Engine::new(Config::new().wasm_multi_value(true)); - let store = HostRef::new(Store::new(&engine)); + let store = Store::new(&engine); // Load binary. println!("Loading binary..."); diff --git a/crates/api/src/callable.rs b/crates/api/src/callable.rs index 5a4e89a08a..d849a38c1c 100644 --- a/crates/api/src/callable.rs +++ b/crates/api/src/callable.rs @@ -43,8 +43,7 @@ use wasmtime_runtime::Export; /// "#)?; /// /// // Initialise environment and our module. -/// let engine = wasmtime::Engine::default(); -/// let store = HostRef::new(wasmtime::Store::new(&engine)); +/// let store = wasmtime::Store::default(); /// let module = HostRef::new(wasmtime::Module::new(&store, &binary)?); /// /// // Define the type of the function we're going to call. @@ -103,13 +102,13 @@ pub(crate) trait WrappedCallable { } pub(crate) struct WasmtimeFn { - store: HostRef, + store: Store, instance: InstanceHandle, export: Export, } impl WasmtimeFn { - pub fn new(store: &HostRef, instance: InstanceHandle, export: Export) -> WasmtimeFn { + pub fn new(store: &Store, instance: InstanceHandle, export: Export) -> WasmtimeFn { WasmtimeFn { store: store.clone(), instance, @@ -146,7 +145,6 @@ impl WrappedCallable for WasmtimeFn { // Get the trampoline to call for this function. let exec_code_buf = self .store - .borrow_mut() .context() .compiler() .get_published_trampoline(body, &signature, value_size) @@ -191,11 +189,7 @@ pub struct NativeCallable { } impl NativeCallable { - pub(crate) fn new( - callable: Rc, - ft: &FuncType, - store: &HostRef, - ) -> Self { + pub(crate) fn new(callable: Rc, ft: &FuncType, store: &Store) -> Self { let (instance, export) = generate_func_export(ft, &callable, store).expect("generated func"); NativeCallable { diff --git a/crates/api/src/context.rs b/crates/api/src/context.rs index b369a43b6b..05f9ecf02f 100644 --- a/crates/api/src/context.rs +++ b/crates/api/src/context.rs @@ -30,7 +30,7 @@ impl Context { self.debug_info } - pub(crate) fn compiler(&mut self) -> RefMut { + pub(crate) fn compiler(&self) -> RefMut { self.compiler.borrow_mut() } } diff --git a/crates/api/src/externals.rs b/crates/api/src/externals.rs index 5a70885a5d..c5be5b27a0 100644 --- a/crates/api/src/externals.rs +++ b/crates/api/src/externals.rs @@ -66,7 +66,7 @@ impl Extern { } pub(crate) fn from_wasmtime_export( - store: &HostRef, + store: &Store, instance_handle: InstanceHandle, export: wasmtime_runtime::Export, ) -> Extern { @@ -112,19 +112,19 @@ impl From> for Extern { } pub struct Func { - _store: HostRef, + _store: Store, callable: Rc, r#type: FuncType, } impl Func { - pub fn new(store: &HostRef, ty: FuncType, callable: Rc) -> Self { + pub fn new(store: &Store, ty: FuncType, callable: Rc) -> Self { let callable = Rc::new(NativeCallable::new(callable, &ty, &store)); Func::from_wrapped(store, ty, callable) } fn from_wrapped( - store: &HostRef, + store: &Store, r#type: FuncType, callable: Rc, ) -> Func { @@ -159,7 +159,7 @@ impl Func { pub(crate) fn from_wasmtime_function( export: wasmtime_runtime::Export, - store: &HostRef, + store: &Store, instance_handle: InstanceHandle, ) -> Self { let ty = if let wasmtime_runtime::Export::Function { signature, .. } = &export { @@ -179,7 +179,7 @@ impl fmt::Debug for Func { } pub struct Global { - _store: HostRef, + _store: Store, r#type: GlobalType, wasmtime_export: wasmtime_runtime::Export, #[allow(dead_code)] @@ -187,7 +187,7 @@ pub struct Global { } impl Global { - pub fn new(store: &HostRef, r#type: GlobalType, val: Val) -> Global { + pub fn new(store: &Store, r#type: GlobalType, val: Val) -> Global { let (wasmtime_export, wasmtime_state) = generate_global_export(&r#type, val).expect("generated global"); Global { @@ -246,10 +246,7 @@ impl Global { &self.wasmtime_export } - pub(crate) fn from_wasmtime_global( - export: wasmtime_runtime::Export, - store: &HostRef, - ) -> Global { + pub(crate) fn from_wasmtime_global(export: wasmtime_runtime::Export, store: &Store) -> Global { let global = if let wasmtime_runtime::Export::Global { ref global, .. } = export { global } else { @@ -266,7 +263,7 @@ impl Global { } pub struct Table { - store: HostRef, + store: Store, r#type: TableType, wasmtime_handle: InstanceHandle, wasmtime_export: wasmtime_runtime::Export, @@ -274,7 +271,7 @@ pub struct Table { fn get_table_item( handle: &InstanceHandle, - store: &HostRef, + store: &Store, table_index: wasm::DefinedTableIndex, item_index: u32, ) -> Val { @@ -287,7 +284,7 @@ fn get_table_item( fn set_table_item( handle: &mut InstanceHandle, - store: &HostRef, + store: &Store, table_index: wasm::DefinedTableIndex, item_index: u32, val: Val, @@ -302,7 +299,7 @@ fn set_table_item( } impl Table { - pub fn new(store: &HostRef, r#type: TableType, init: Val) -> Table { + pub fn new(store: &Store, r#type: TableType, init: Val) -> Table { match r#type.element() { ValType::FuncRef => (), _ => panic!("table is not for funcref"), @@ -387,7 +384,7 @@ impl Table { pub(crate) fn from_wasmtime_table( export: wasmtime_runtime::Export, - store: &HostRef, + store: &Store, instance_handle: wasmtime_runtime::InstanceHandle, ) -> Table { let table = if let wasmtime_runtime::Export::Table { ref table, .. } = export { @@ -406,14 +403,14 @@ impl Table { } pub struct Memory { - _store: HostRef, + _store: Store, r#type: MemoryType, wasmtime_handle: InstanceHandle, wasmtime_export: wasmtime_runtime::Export, } impl Memory { - pub fn new(store: &HostRef, r#type: MemoryType) -> Memory { + pub fn new(store: &Store, r#type: MemoryType) -> Memory { let (wasmtime_handle, wasmtime_export) = generate_memory_export(&r#type).expect("generated memory"); Memory { @@ -473,7 +470,7 @@ impl Memory { pub(crate) fn from_wasmtime_memory( export: wasmtime_runtime::Export, - store: &HostRef, + store: &Store, instance_handle: wasmtime_runtime::InstanceHandle, ) -> Memory { let memory = if let wasmtime_runtime::Export::Memory { ref memory, .. } = export { diff --git a/crates/api/src/instance.rs b/crates/api/src/instance.rs index f85b243447..ea7a7b56db 100644 --- a/crates/api/src/instance.rs +++ b/crates/api/src/instance.rs @@ -30,7 +30,7 @@ impl Resolver for SimpleResolver { pub fn instantiate_in_context( data: &[u8], imports: Vec<(String, String, Extern)>, - mut context: Context, + context: Context, exports: Rc>>>, ) -> Result<(InstanceHandle, HashSet), Error> { let mut contexts = HashSet::new(); @@ -70,12 +70,12 @@ pub struct Instance { impl Instance { pub fn new( - store: &HostRef, + store: &Store, module: &HostRef, externs: &[Extern], ) -> Result { - let context = store.borrow_mut().context().clone(); - let exports = store.borrow_mut().global_exports().clone(); + let context = store.context().clone(); + let exports = store.global_exports().clone(); let imports = module .borrow() .imports() @@ -131,7 +131,7 @@ impl Instance { Some(&self.exports()[i]) } - pub fn from_handle(store: &HostRef, instance_handle: InstanceHandle) -> Instance { + pub fn from_handle(store: &Store, instance_handle: InstanceHandle) -> Instance { let contexts = HashSet::new(); let mut exports = Vec::new(); @@ -143,7 +143,7 @@ impl Instance { // HACK ensure all handles, instantiated outside Store, present in // the store's SignatureRegistry, e.g. WASI instances that are // imported into this store using the from_handle() method. - let _ = store.borrow_mut().register_wasmtime_signature(signature); + let _ = store.register_wasmtime_signature(signature); } let extern_type = ExternType::from_wasmtime_export(&export); exports_types.push(ExportType::new(name, extern_type)); diff --git a/crates/api/src/module.rs b/crates/api/src/module.rs index b2155494d7..52a84a0824 100644 --- a/crates/api/src/module.rs +++ b/crates/api/src/module.rs @@ -1,4 +1,3 @@ -use crate::r#ref::HostRef; use crate::runtime::Store; use crate::types::{ ExportType, ExternType, FuncType, GlobalType, ImportType, Limits, MemoryType, Mutability, @@ -173,7 +172,7 @@ pub(crate) enum ModuleCodeSource { #[derive(Clone)] pub struct Module { - store: HostRef, + store: Store, source: ModuleCodeSource, imports: Box<[ImportType]>, exports: Box<[ExportType]>, @@ -182,13 +181,13 @@ pub struct Module { impl Module { /// Validate and decode the raw wasm data in `binary` and create a new /// `Module` in the given `store`. - pub fn new(store: &HostRef, binary: &[u8]) -> Result { + pub fn new(store: &Store, binary: &[u8]) -> Result { Self::validate(store, binary)?; Self::new_unchecked(store, binary) } /// Similar to `new`, but does not perform any validation. Only use this /// on modules which are known to have been validated already! - pub fn new_unchecked(store: &HostRef, binary: &[u8]) -> Result { + pub fn new_unchecked(store: &Store, binary: &[u8]) -> Result { let (imports, exports) = read_imports_and_exports(binary)?; Ok(Module { store: store.clone(), @@ -203,8 +202,8 @@ impl Module { _ => None, } } - pub fn validate(store: &HostRef, binary: &[u8]) -> Result<()> { - let features = store.borrow().engine().config.features.clone(); + pub fn validate(store: &Store, binary: &[u8]) -> Result<()> { + let features = store.engine().config.features.clone(); let config = ValidatingParserConfig { operator_config: OperatorValidatorConfig { enable_threads: features.threads, @@ -222,7 +221,7 @@ impl Module { pub fn exports(&self) -> &[ExportType] { &self.exports } - pub fn from_exports(store: &HostRef, exports: Box<[ExportType]>) -> Self { + pub fn from_exports(store: &Store, exports: Box<[ExportType]>) -> Self { Module { store: store.clone(), source: ModuleCodeSource::Unknown, diff --git a/crates/api/src/runtime.rs b/crates/api/src/runtime.rs index 500b9afbfa..90cd20ddc2 100644 --- a/crates/api/src/runtime.rs +++ b/crates/api/src/runtime.rs @@ -288,12 +288,13 @@ pub enum OptLevel { /// /// Using `clone` on an `Engine` is a cheap operation. It will not create an /// entirely new engine, but rather just a new reference to the existing engine. +/// In other words it's a shallow copy, not a deep copy. /// /// ## Engines and `Default` /// -/// You can create an engine with default settings using `Engine::default()`. -/// This engine will not have any unstable wasm features enabled and will use -/// the default compilation backend configured at this crate's compile time. +/// You can create an engine with default configuration settings using +/// `Engine::default()`. Be sure to consult the documentation of [`Config`] for +/// default settings. #[derive(Default, Clone)] pub struct Engine { pub(crate) config: Arc, @@ -311,45 +312,72 @@ impl Engine { // Store +/// A `Store` is a shared cache of information between WebAssembly modules. +/// +/// Each `Module` is compiled into a `Store` and a `Store` is associated with an +/// [`Engine`]. You'll use a `Store` to attach to a number of global items in +/// the production of various items for wasm modules. +/// +/// # Stores and `Clone` +/// +/// Using `clone` on a `Store` is a cheap operation. It will not create an +/// entirely new store, but rather just a new reference to the existing object. +/// In other words it's a shallow copy, not a deep copy. +/// +/// ## Stores and `Default` +/// +/// You can create a store with default configuration settings using +/// `Store::default()`. This will create a brand new [`Engine`] with default +/// ocnfiguration (see [`Config`] for more information). +#[derive(Clone)] pub struct Store { + inner: Rc, +} + +struct StoreInner { engine: Engine, context: Context, global_exports: Rc>>>, - signature_cache: HashMap, + signature_cache: RefCell>, } impl Store { + /// Creates a new store to be associated with the given [`Engine`]. pub fn new(engine: &Engine) -> Store { Store { - engine: engine.clone(), - context: Context::new(&engine.config), - global_exports: Rc::new(RefCell::new(HashMap::new())), - signature_cache: HashMap::new(), + inner: Rc::new(StoreInner { + engine: engine.clone(), + context: Context::new(&engine.config), + global_exports: Rc::new(RefCell::new(HashMap::new())), + signature_cache: RefCell::new(HashMap::new()), + }), } } + /// Returns the [`Engine`] that this store is associated with. pub fn engine(&self) -> &Engine { - &self.engine + &self.inner.engine } - pub(crate) fn context(&mut self) -> &mut Context { - &mut self.context + pub(crate) fn context(&self) -> &Context { + &self.inner.context } // Specific to wasmtime: hack to pass memory around to wasi + #[doc(hidden)] pub fn global_exports( &self, ) -> &Rc>>> { - &self.global_exports + &self.inner.global_exports } pub(crate) fn register_wasmtime_signature( - &mut self, + &self, signature: &ir::Signature, ) -> wasmtime_runtime::VMSharedSignatureIndex { use std::collections::hash_map::Entry; let index = self.context().compiler().signatures().register(signature); - match self.signature_cache.entry(index) { + match self.inner.signature_cache.borrow_mut().entry(index) { Entry::Vacant(v) => { v.insert(signature.clone()); } @@ -361,8 +389,18 @@ impl Store { pub(crate) fn lookup_wasmtime_signature( &self, type_index: wasmtime_runtime::VMSharedSignatureIndex, - ) -> Option<&ir::Signature> { - self.signature_cache.get(&type_index) + ) -> Option { + self.inner + .signature_cache + .borrow() + .get(&type_index) + .cloned() + } +} + +impl Default for Store { + fn default() -> Store { + Store::new(&Engine::default()) } } diff --git a/crates/api/src/trampoline/create_handle.rs b/crates/api/src/trampoline/create_handle.rs index 7854b14db5..864ec3a612 100644 --- a/crates/api/src/trampoline/create_handle.rs +++ b/crates/api/src/trampoline/create_handle.rs @@ -3,7 +3,7 @@ use crate::runtime::Store; use anyhow::Result; use std::any::Any; -use std::cell::{RefCell, RefMut}; +use std::cell::RefCell; use std::collections::{HashMap, HashSet}; use std::rc::Rc; use wasmtime_environ::entity::PrimaryMap; @@ -13,7 +13,7 @@ use wasmtime_runtime::{Imports, InstanceHandle, VMFunctionBody}; pub(crate) fn create_handle( module: Module, - signature_registry: Option>, + signature_registry: Option<&Store>, finished_functions: PrimaryMap, state: Box, ) -> Result { @@ -31,7 +31,7 @@ pub(crate) fn create_handle( // Compute indices into the shared signature table. let signatures = signature_registry - .map(|mut signature_registry| { + .map(|signature_registry| { module .signatures .values() diff --git a/crates/api/src/trampoline/func.rs b/crates/api/src/trampoline/func.rs index aa411cbb0d..3d0ae86fe3 100644 --- a/crates/api/src/trampoline/func.rs +++ b/crates/api/src/trampoline/func.rs @@ -2,7 +2,6 @@ use super::create_handle::create_handle; use super::trap::{record_api_trap, TrapSink, API_TRAP_CODE}; -use crate::r#ref::HostRef; use crate::{Callable, FuncType, Store, Val}; use anyhow::Result; use std::cmp; @@ -234,7 +233,7 @@ fn make_trampoline( pub fn create_handle_with_function( ft: &FuncType, func: &Rc, - store: &HostRef, + store: &Store, ) -> Result { let sig = ft.get_wasmtime_signature().clone(); @@ -270,7 +269,7 @@ pub fn create_handle_with_function( create_handle( module, - Some(store.borrow_mut()), + Some(store), finished_functions, Box::new(trampoline_state), ) diff --git a/crates/api/src/trampoline/mod.rs b/crates/api/src/trampoline/mod.rs index 50a76293ca..999785571a 100644 --- a/crates/api/src/trampoline/mod.rs +++ b/crates/api/src/trampoline/mod.rs @@ -12,7 +12,6 @@ use self::global::create_global; use self::memory::create_handle_with_memory; use self::table::create_handle_with_table; use super::{Callable, FuncType, GlobalType, MemoryType, Store, TableType, Val}; -use crate::r#ref::HostRef; use anyhow::Result; use std::rc::Rc; @@ -22,7 +21,7 @@ pub use self::trap::take_api_trap; pub fn generate_func_export( ft: &FuncType, func: &Rc, - store: &HostRef, + store: &Store, ) -> Result<(wasmtime_runtime::InstanceHandle, wasmtime_runtime::Export)> { let mut instance = create_handle_with_function(ft, func, store)?; let export = instance.lookup("trampoline").expect("trampoline export"); diff --git a/crates/api/src/values.rs b/crates/api/src/values.rs index 7f9d367982..419f4534f9 100644 --- a/crates/api/src/values.rs +++ b/crates/api/src/values.rs @@ -197,7 +197,7 @@ impl From for Val { pub(crate) fn into_checked_anyfunc( val: Val, - store: &HostRef, + store: &Store, ) -> wasmtime_runtime::VMCallerCheckedAnyfunc { match val { Val::AnyRef(AnyRef::Null) => wasmtime_runtime::VMCallerCheckedAnyfunc { @@ -215,7 +215,7 @@ pub(crate) fn into_checked_anyfunc( } => (*vmctx, *address, signature), _ => panic!("expected function export"), }; - let type_index = store.borrow_mut().register_wasmtime_signature(signature); + let type_index = store.register_wasmtime_signature(signature); wasmtime_runtime::VMCallerCheckedAnyfunc { func_ptr, type_index, @@ -228,16 +228,14 @@ pub(crate) fn into_checked_anyfunc( pub(crate) fn from_checked_anyfunc( item: &wasmtime_runtime::VMCallerCheckedAnyfunc, - store: &HostRef, + store: &Store, ) -> Val { if item.type_index == wasmtime_runtime::VMSharedSignatureIndex::default() { return Val::AnyRef(AnyRef::Null); } let signature = store - .borrow() .lookup_wasmtime_signature(item.type_index) - .expect("signature") - .clone(); + .expect("signature"); let instance_handle = unsafe { wasmtime_runtime::InstanceHandle::from_vmctx(item.vmctx) }; let export = wasmtime_runtime::Export::Function { address: item.func_ptr, diff --git a/crates/api/src/wasm.rs b/crates/api/src/wasm.rs index e42784f45d..11786f9363 100644 --- a/crates/api/src/wasm.rs +++ b/crates/api/src/wasm.rs @@ -609,7 +609,7 @@ pub unsafe extern "C" fn wasm_func_new( ty: *const wasm_functype_t, callback: wasm_func_callback_t, ) -> *mut wasm_func_t { - let store = &(*store).store; + let store = &(*store).store.borrow(); let ty = (*ty).functype.clone(); let callback = Rc::new(callback); let func = Box::new(wasm_func_t { @@ -663,7 +663,7 @@ pub unsafe extern "C" fn wasm_instance_new( imports: *const *const wasm_extern_t, result: *mut *mut wasm_trap_t, ) -> *mut wasm_instance_t { - let store = &(*store).store; + let store = &(*store).store.borrow(); let mut externs: Vec = Vec::with_capacity((*module).imports.len()); for i in 0..(*module).imports.len() { let import = *imports.add(i); @@ -731,7 +731,7 @@ pub unsafe extern "C" fn wasm_module_new( binary: *const wasm_byte_vec_t, ) -> *mut wasm_module_t { let binary = (*binary).as_slice(); - let store = &(*store).store; + let store = &(*store).store.borrow(); let module = Module::new_unchecked(store, binary).expect("module"); let imports = module .imports() @@ -765,7 +765,7 @@ pub unsafe extern "C" fn wasm_module_validate( binary: *const wasm_byte_vec_t, ) -> bool { let binary = (*binary).as_slice(); - let store = &(*store).store; + let store = &(*store).store.borrow(); Module::validate(store, binary).is_ok() } @@ -814,7 +814,7 @@ pub unsafe extern "C" fn wasm_func_new_with_env( env: *mut std::ffi::c_void, finalizer: std::option::Option, ) -> *mut wasm_func_t { - let store = &(*store).store; + let store = &(*store).store.borrow(); let ty = (*ty).functype.clone(); let callback = Rc::new(CallbackWithEnv { callback, @@ -1337,7 +1337,7 @@ pub unsafe extern "C" fn wasm_global_new( val: *const wasm_val_t, ) -> *mut wasm_global_t { let global = HostRef::new(Global::new( - &(*store).store, + &(*store).store.borrow(), (*gt).globaltype.clone(), (*val).val(), )); @@ -1456,7 +1456,10 @@ pub unsafe extern "C" fn wasm_memory_new( store: *mut wasm_store_t, mt: *const wasm_memorytype_t, ) -> *mut wasm_memory_t { - let memory = HostRef::new(Memory::new(&(*store).store, (*mt).memorytype.clone())); + let memory = HostRef::new(Memory::new( + &(*store).store.borrow(), + (*mt).memorytype.clone(), + )); let m = Box::new(wasm_memory_t { memory, ext: None }); Box::into_raw(m) } @@ -1549,7 +1552,11 @@ pub unsafe extern "C" fn wasm_table_new( Val::AnyRef(AnyRef::Null) }; let t = Box::new(wasm_table_t { - table: HostRef::new(Table::new(&(*store).store, (*tt).tabletype.clone(), init)), + table: HostRef::new(Table::new( + &(*store).store.borrow(), + (*tt).tabletype.clone(), + init, + )), ext: None, }); Box::into_raw(t) diff --git a/crates/api/tests/import_calling_export.rs b/crates/api/tests/import_calling_export.rs index 447d9a2710..5538e19792 100644 --- a/crates/api/tests/import_calling_export.rs +++ b/crates/api/tests/import_calling_export.rs @@ -32,8 +32,7 @@ fn test_import_calling_export() { } } - let engine = Engine::default(); - let store = HostRef::new(Store::new(&engine)); + let store = Store::default(); let wasm = wat::parse_str(WAT).unwrap(); let module = HostRef::new(Module::new(&store, &wasm).expect("failed to create module")); diff --git a/crates/api/tests/traps.rs b/crates/api/tests/traps.rs index ad36574b39..9f32d077de 100644 --- a/crates/api/tests/traps.rs +++ b/crates/api/tests/traps.rs @@ -12,8 +12,7 @@ fn test_trap_return() -> Result<(), String> { } } - let engine = Engine::default(); - let store = HostRef::new(Store::new(&engine)); + let store = Store::default(); let binary = parse_str( r#" (module diff --git a/crates/fuzzing/src/oracles.rs b/crates/fuzzing/src/oracles.rs index 45c6290332..d04ca8cb5c 100644 --- a/crates/fuzzing/src/oracles.rs +++ b/crates/fuzzing/src/oracles.rs @@ -42,7 +42,7 @@ pub fn instantiate(wasm: &[u8], strategy: Strategy) { .strategy(strategy) .expect("failed to enable lightbeam"); let engine = Engine::new(&config); - let store = HostRef::new(Store::new(&engine)); + let store = Store::new(&engine); let module = HostRef::new(Module::new(&store, wasm).expect("Failed to compile a valid Wasm module!")); @@ -91,7 +91,7 @@ pub fn make_api_calls(api: crate::generators::api::ApiCalls) { let mut config: Option = None; let mut engine: Option = None; - let mut store: Option> = None; + let mut store: Option = None; let mut modules: HashMap> = Default::default(); let mut instances: HashMap> = Default::default(); @@ -113,7 +113,7 @@ pub fn make_api_calls(api: crate::generators::api::ApiCalls) { ApiCall::StoreNew => { assert!(store.is_none()); - store = Some(HostRef::new(Store::new(engine.as_ref().unwrap()))); + store = Some(Store::new(engine.as_ref().unwrap())); } ApiCall::ModuleNew { id, wasm } => { diff --git a/crates/fuzzing/src/oracles/dummy.rs b/crates/fuzzing/src/oracles/dummy.rs index 829eb5206c..f72cd4858f 100644 --- a/crates/fuzzing/src/oracles/dummy.rs +++ b/crates/fuzzing/src/oracles/dummy.rs @@ -7,10 +7,7 @@ use wasmtime::{ }; /// Create a set of dummy functions/globals/etc for the given imports. -pub fn dummy_imports( - store: &HostRef, - import_tys: &[ImportType], -) -> Result, Trap> { +pub fn dummy_imports(store: &Store, import_tys: &[ImportType]) -> Result, Trap> { let mut imports = Vec::with_capacity(import_tys.len()); for imp in import_tys { imports.push(match imp.ty() { @@ -38,7 +35,7 @@ pub struct DummyFunc(FuncType); impl DummyFunc { /// Construct a new dummy `Func`. - pub fn new(store: &HostRef, ty: FuncType) -> Func { + pub fn new(store: &Store, ty: FuncType) -> Func { let callable = DummyFunc(ty.clone()); Func::new(store, ty, Rc::new(callable) as _) } @@ -80,18 +77,18 @@ pub fn dummy_value(val_ty: &ValType) -> Result { } /// Construct a dummy global for the given global type. -pub fn dummy_global(store: &HostRef, ty: GlobalType) -> Result { +pub fn dummy_global(store: &Store, ty: GlobalType) -> Result { let val = dummy_value(ty.content())?; Ok(Global::new(store, ty, val)) } /// Construct a dummy table for the given table type. -pub fn dummy_table(store: &HostRef, ty: TableType) -> Result { +pub fn dummy_table(store: &Store, ty: TableType) -> Result { let init_val = dummy_value(&ty.element())?; Ok(Table::new(store, ty, init_val)) } /// Construct a dummy memory for the given memory type. -pub fn dummy_memory(store: &HostRef, ty: MemoryType) -> Memory { +pub fn dummy_memory(store: &Store, ty: MemoryType) -> Memory { Memory::new(store, ty) } diff --git a/crates/misc/py/src/function.rs b/crates/misc/py/src/function.rs index 7093ea4aff..3b88dcccf0 100644 --- a/crates/misc/py/src/function.rs +++ b/crates/misc/py/src/function.rs @@ -126,7 +126,7 @@ impl wasmtime::Callable for WrappedFn { } pub fn wrap_into_pyfunction( - store: &wasmtime::HostRef, + store: &wasmtime::Store, callable: &PyAny, ) -> PyResult> { if !callable.hasattr("__annotations__")? { diff --git a/crates/misc/py/src/lib.rs b/crates/misc/py/src/lib.rs index 0d13b5a92b..20db96ba9d 100644 --- a/crates/misc/py/src/lib.rs +++ b/crates/misc/py/src/lib.rs @@ -44,11 +44,7 @@ impl InstantiateResultObject { } } -fn find_export_in( - obj: &PyAny, - store: &wasmtime::HostRef, - name: &str, -) -> PyResult { +fn find_export_in(obj: &PyAny, store: &wasmtime::Store, name: &str) -> PyResult { let obj = obj.cast_as::()?; Ok(if let Some(item) = obj.get_item(name) { @@ -86,7 +82,7 @@ pub fn instantiate( let wasm_data = buffer_source.as_bytes(); let engine = wasmtime::Engine::new(&wasmtime::Config::new().wasm_multi_value(true)); - let store = wasmtime::HostRef::new(wasmtime::Store::new(&engine)); + let store = wasmtime::Store::new(&engine); let module = wasmtime::HostRef::new(wasmtime::Module::new(&store, wasm_data).map_err(err2py)?); diff --git a/crates/misc/rust/macro/src/lib.rs b/crates/misc/rust/macro/src/lib.rs index 57a40816bf..378897d311 100644 --- a/crates/misc/rust/macro/src/lib.rs +++ b/crates/misc/rust/macro/src/lib.rs @@ -52,8 +52,8 @@ fn generate_load(item: &syn::ItemTrait) -> syn::Result { use #root::anyhow::{bail, format_err}; let engine = Engine::new(Config::new().wasm_multi_value(true)); - let store = HostRef::new(Store::new(&engine)); - let global_exports = store.borrow().global_exports().clone(); + let store = Store::new(&engine); + let global_exports = store.global_exports().clone(); let data = #root::wasmtime_interface_types::ModuleData::new(&bytes)?; diff --git a/crates/test-programs/tests/wasm_tests/runtime.rs b/crates/test-programs/tests/wasm_tests/runtime.rs index a0c7e420d9..5c4d10220b 100644 --- a/crates/test-programs/tests/wasm_tests/runtime.rs +++ b/crates/test-programs/tests/wasm_tests/runtime.rs @@ -1,13 +1,12 @@ use anyhow::{bail, Context}; use std::fs::File; use std::path::Path; -use wasmtime::{Engine, HostRef, Instance, Module, Store}; +use wasmtime::{HostRef, Instance, Module, Store}; pub fn instantiate(data: &[u8], bin_name: &str, workspace: Option<&Path>) -> anyhow::Result<()> { - let engine = Engine::default(); - let store = HostRef::new(Store::new(&engine)); + let store = Store::default(); - let global_exports = store.borrow().global_exports().clone(); + let global_exports = store.global_exports().clone(); let get_preopens = |workspace: Option<&Path>| -> anyhow::Result> { if let Some(workspace) = workspace { let preopen_dir = wasi_common::preopen_dir(workspace) diff --git a/crates/wasi/src/instantiate.rs b/crates/wasi/src/instantiate.rs index 79d103953f..4bbfdbbde8 100644 --- a/crates/wasi/src/instantiate.rs +++ b/crates/wasi/src/instantiate.rs @@ -14,12 +14,12 @@ use wasmtime_runtime::{Imports, InstanceHandle, InstantiationError, VMContext}; /// Creates `wasmtime::Instance` object implementing the "wasi" interface. pub fn create_wasi_instance( - store: &wasmtime::HostRef, + store: &wasmtime::Store, preopened_dirs: &[(String, File)], argv: &[String], environ: &[(String, String)], ) -> Result { - let global_exports = store.borrow().global_exports().clone(); + let global_exports = store.global_exports().clone(); let wasi = instantiate_wasi(global_exports, preopened_dirs, argv, environ)?; let instance = wasmtime::Instance::from_handle(&store, wasi); Ok(instance) diff --git a/crates/wasi/src/old/snapshot_0/instantiate.rs b/crates/wasi/src/old/snapshot_0/instantiate.rs index 7f6765affe..10e42f89c6 100644 --- a/crates/wasi/src/old/snapshot_0/instantiate.rs +++ b/crates/wasi/src/old/snapshot_0/instantiate.rs @@ -14,12 +14,12 @@ use wasmtime_runtime::{Imports, InstanceHandle, InstantiationError, VMFunctionBo /// Creates `wasmtime::Instance` object implementing the "wasi" interface. pub fn create_wasi_instance( - store: &wasmtime::HostRef, + store: &wasmtime::Store, preopened_dirs: &[(String, File)], argv: &[String], environ: &[(String, String)], ) -> Result { - let global_exports = store.borrow().global_exports().clone(); + let global_exports = store.global_exports().clone(); let wasi = instantiate_wasi(global_exports, preopened_dirs, argv, environ)?; let instance = wasmtime::Instance::from_handle(&store, wasi); Ok(instance) diff --git a/crates/wast/src/spectest.rs b/crates/wast/src/spectest.rs index 6dc7d976de..8d906f56c6 100644 --- a/crates/wast/src/spectest.rs +++ b/crates/wast/src/spectest.rs @@ -17,7 +17,7 @@ where } fn wrap( - store: &HostRef, + store: &Store, ty: FuncType, callable: impl Fn(&[Val], &mut [Val]) -> Result<(), Trap> + 'static, ) -> Func { @@ -26,7 +26,7 @@ fn wrap( /// Return an instance implementing the "spectest" interface used in the /// spec testsuite. -pub fn instantiate_spectest(store: &HostRef) -> HashMap<&'static str, Extern> { +pub fn instantiate_spectest(store: &Store) -> HashMap<&'static str, Extern> { let mut ret = HashMap::new(); let ty = FuncType::new(Box::new([]), Box::new([])); diff --git a/crates/wast/src/wast.rs b/crates/wast/src/wast.rs index f392756bd8..73d47c20ea 100644 --- a/crates/wast/src/wast.rs +++ b/crates/wast/src/wast.rs @@ -30,7 +30,7 @@ pub struct WastContext { current: Option>, instances: HashMap>, - store: HostRef, + store: Store, spectest: Option>, } @@ -41,7 +41,7 @@ enum Outcome> { impl WastContext { /// Construct a new instance of `WastContext`. - pub fn new(store: HostRef) -> Self { + pub fn new(store: Store) -> Self { Self { current: None, store, diff --git a/docs/embed-rust.md b/docs/embed-rust.md index f09196c133..3aec04ae09 100644 --- a/docs/embed-rust.md +++ b/docs/embed-rust.md @@ -33,13 +33,12 @@ wasmtime = "" where "" is the current version number of the `wasmtime` crate. -It is time to add code to the `src/main.rs`. First, the engine and storage need to be activated: +It is time to add code to the `src/main.rs`. First, storage needs to be activated: ```rust use wasmtime::*; -let engine = Engine::default(); -let store = HostRef::new(Store::new(&engine)); +let store = Store::default(); ``` The `HostRef` will be used a lot -- it is a "convenience" object to store and refer an object between the host and @@ -87,8 +86,7 @@ use std::fs::read; use wasmtime::*; fn main() { - let engine = Engine::default(); - let store = HostRef::new(Store::new(&engine)); + let store = Store::default(); let wasm = read("hello.wasm").expect("wasm file"); diff --git a/src/commands/run.rs b/src/commands/run.rs index d23594fa9d..cafd7f19f8 100644 --- a/src/commands/run.rs +++ b/src/commands/run.rs @@ -141,7 +141,7 @@ impl RunCommand { } let engine = Engine::new(&config); - let store = HostRef::new(Store::new(&engine)); + let store = Store::new(&engine); let mut module_registry = HashMap::new(); // Make wasi available by default. @@ -151,7 +151,7 @@ impl RunCommand { let wasi_unstable = HostRef::new(if self.enable_wasi_c { #[cfg(feature = "wasi-c")] { - let global_exports = store.borrow().global_exports().clone(); + let global_exports = store.global_exports().clone(); let handle = instantiate_wasi_c(global_exports, &preopen_dirs, &argv, &self.vars)?; Instance::from_handle(&store, handle) } @@ -231,12 +231,12 @@ impl RunCommand { } fn instantiate_module( - store: &HostRef, + store: &Store, module_registry: &HashMap>, path: &Path, ) -> Result<(HostRef, HostRef, Vec)> { // Read the wasm module binary either as `*.wat` or a raw binary - let data = wat::parse_file(path.to_path_buf())?; + let data = wat::parse_file(path)?; let module = HostRef::new(Module::new(store, &data)?); @@ -274,7 +274,7 @@ impl RunCommand { fn handle_module( &self, - store: &HostRef, + store: &Store, module_registry: &HashMap>, ) -> Result<()> { let (instance, module, data) = diff --git a/src/commands/wast.rs b/src/commands/wast.rs index 8377e00848..7610c0425f 100644 --- a/src/commands/wast.rs +++ b/src/commands/wast.rs @@ -4,7 +4,7 @@ use crate::{init_file_per_thread_logger, pick_compilation_strategy, CommonOption use anyhow::{bail, Context as _, Result}; use std::{fmt::Write, path::PathBuf}; use structopt::{clap::AppSettings, StructOpt}; -use wasmtime::{Config, Engine, HostRef, Store}; +use wasmtime::{Config, Engine, Store}; use wasmtime_environ::cache_init; use wasmtime_wast::WastContext; @@ -65,7 +65,7 @@ impl WastCommand { config.cranelift_opt_level(wasmtime::OptLevel::Speed); } - let store = HostRef::new(Store::new(&Engine::new(&config))); + let store = Store::new(&Engine::new(&config)); let mut wast_context = WastContext::new(store); wast_context diff --git a/tests/wast_testsuites.rs b/tests/wast_testsuites.rs index e56310e1b6..877c59ccfc 100644 --- a/tests/wast_testsuites.rs +++ b/tests/wast_testsuites.rs @@ -1,5 +1,5 @@ use std::path::Path; -use wasmtime::{Config, Engine, HostRef, Store, Strategy}; +use wasmtime::{Config, Engine, Store, Strategy}; use wasmtime_wast::WastContext; include!(concat!(env!("OUT_DIR"), "/wast_testsuite_tests.rs")); @@ -15,7 +15,7 @@ fn run_wast(wast: &str, strategy: Strategy) -> anyhow::Result<()> { .wasm_multi_value(wast.iter().any(|s| s == "multi-value")) .strategy(strategy)? .cranelift_debug_verifier(true); - let store = HostRef::new(Store::new(&Engine::new(&cfg))); + let store = Store::new(&Engine::new(&cfg)); let mut wast_context = WastContext::new(store); wast_context.register_spectest()?; wast_context.run_file(wast)?;