diff --git a/crates/api/examples/gcd.rs b/crates/api/examples/gcd.rs index 0fdbf27d2c..405d73e9f1 100644 --- a/crates/api/examples/gcd.rs +++ b/crates/api/examples/gcd.rs @@ -38,7 +38,7 @@ fn main() -> Result<()> { let wasm = wat::parse_str(WAT)?; // Instantiate engine and store. - let engine = HostRef::new(Engine::default()); + let engine = Engine::default(); let store = HostRef::new(Store::new(&engine)); // Load a module. diff --git a/crates/api/examples/hello.rs b/crates/api/examples/hello.rs index 6d00ed15bb..09462cb334 100644 --- a/crates/api/examples/hello.rs +++ b/crates/api/examples/hello.rs @@ -18,7 +18,7 @@ fn main() -> Result<()> { // Configure the initial compilation environment, creating more global // structures such as an `Engine` and a `Store`. println!("Initializing..."); - let engine = HostRef::new(Engine::default()); + let engine = Engine::default(); let store = HostRef::new(Store::new(&engine)); // Next upload the `*.wasm` binary file, which in this case we're going to diff --git a/crates/api/examples/memory.rs b/crates/api/examples/memory.rs index 7214a95e8c..0c11c58a9d 100644 --- a/crates/api/examples/memory.rs +++ b/crates/api/examples/memory.rs @@ -62,7 +62,7 @@ macro_rules! call { fn main() -> Result<(), Error> { // Initialize. println!("Initializing..."); - let engine = HostRef::new(Engine::default()); + let engine = Engine::default(); let store = HostRef::new(Store::new(&engine)); // Load binary. diff --git a/crates/api/examples/multi.rs b/crates/api/examples/multi.rs index a1632a644e..be7826b4e7 100644 --- a/crates/api/examples/multi.rs +++ b/crates/api/examples/multi.rs @@ -50,7 +50,7 @@ fn main() -> Result<()> { multi_value: true, ..Default::default() }); - let engine = HostRef::new(Engine::new(&cfg)); + let engine = Engine::new(&cfg); let store = HostRef::new(Store::new(&engine)); // Load binary. diff --git a/crates/api/src/callable.rs b/crates/api/src/callable.rs index bb203ffd46..5a4e89a08a 100644 --- a/crates/api/src/callable.rs +++ b/crates/api/src/callable.rs @@ -43,7 +43,7 @@ use wasmtime_runtime::Export; /// "#)?; /// /// // Initialise environment and our module. -/// let engine = HostRef::new(wasmtime::Engine::default()); +/// let engine = wasmtime::Engine::default(); /// let store = HostRef::new(wasmtime::Store::new(&engine)); /// let module = HostRef::new(wasmtime::Module::new(&store, &binary)?); /// diff --git a/crates/api/src/module.rs b/crates/api/src/module.rs index 6f40585e18..b2155494d7 100644 --- a/crates/api/src/module.rs +++ b/crates/api/src/module.rs @@ -204,7 +204,7 @@ impl Module { } } pub fn validate(store: &HostRef, binary: &[u8]) -> Result<()> { - let features = store.borrow().engine().borrow().config.features.clone(); + let features = store.borrow().engine().config.features.clone(); let config = ValidatingParserConfig { operator_config: OperatorValidatorConfig { enable_threads: features.threads, diff --git a/crates/api/src/runtime.rs b/crates/api/src/runtime.rs index 3ed7ea6499..02fb1ea9a9 100644 --- a/crates/api/src/runtime.rs +++ b/crates/api/src/runtime.rs @@ -1,8 +1,8 @@ use crate::context::Context; -use crate::r#ref::HostRef; use std::cell::RefCell; use std::collections::HashMap; use std::rc::Rc; +use std::sync::Arc; use wasmtime_environ::{ir, settings}; use wasmtime_jit::{CompilationStrategy, Features}; @@ -92,15 +92,38 @@ impl Default for Config { // Engine -#[derive(Default)] +/// An `Engine` which is a global context for compilation and management of wasm +/// modules. +/// +/// An engine can be safely shared across threads and is a cheap cloneable +/// handle to the actual engine. The engine itself will be deallocate once all +/// references to it have gone away. +/// +/// Engines store global configuration preferences such as compilation settings, +/// enabled features, etc. You'll likely only need at most one of these for a +/// program. +/// +/// ## Engines and `Clone` +/// +/// 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. +/// +/// ## 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. +#[derive(Default, Clone)] pub struct Engine { - pub(crate) config: Config, + pub(crate) config: Arc, } impl Engine { + /// Creates a new [`Engine`] with the specified compilation and + /// configuration settings. pub fn new(config: &Config) -> Engine { Engine { - config: config.clone(), + config: Arc::new(config.clone()), } } } @@ -108,23 +131,23 @@ impl Engine { // Store pub struct Store { - engine: HostRef, + engine: Engine, context: Context, global_exports: Rc>>>, signature_cache: HashMap, } impl Store { - pub fn new(engine: &HostRef) -> Store { + pub fn new(engine: &Engine) -> Store { Store { engine: engine.clone(), - context: Context::new(&engine.borrow().config), + context: Context::new(&engine.config), global_exports: Rc::new(RefCell::new(HashMap::new())), signature_cache: HashMap::new(), } } - pub fn engine(&self) -> &HostRef { + pub fn engine(&self) -> &Engine { &self.engine } @@ -161,3 +184,8 @@ impl Store { self.signature_cache.get(&type_index) } } + +fn _assert_send_sync() { + fn _assert() {} + _assert::(); +} diff --git a/crates/api/src/wasm.rs b/crates/api/src/wasm.rs index 7cd8961ca4..e42784f45d 100644 --- a/crates/api/src/wasm.rs +++ b/crates/api/src/wasm.rs @@ -778,7 +778,7 @@ pub unsafe extern "C" fn wasm_store_delete(store: *mut wasm_store_t) { pub unsafe extern "C" fn wasm_store_new(engine: *mut wasm_engine_t) -> *mut wasm_store_t { let engine = &(*engine).engine; let store = Box::new(wasm_store_t { - store: HostRef::new(Store::new(&engine)), + store: HostRef::new(Store::new(&engine.borrow())), }); Box::into_raw(store) } diff --git a/crates/api/tests/import_calling_export.rs b/crates/api/tests/import_calling_export.rs index 0157d5d315..447d9a2710 100644 --- a/crates/api/tests/import_calling_export.rs +++ b/crates/api/tests/import_calling_export.rs @@ -32,7 +32,7 @@ fn test_import_calling_export() { } } - let engine = HostRef::new(Engine::default()); + let engine = Engine::default(); let store = HostRef::new(Store::new(&engine)); 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 25527fbfcd..ad36574b39 100644 --- a/crates/api/tests/traps.rs +++ b/crates/api/tests/traps.rs @@ -12,7 +12,7 @@ fn test_trap_return() -> Result<(), String> { } } - let engine = HostRef::new(Engine::default()); + let engine = Engine::default(); let store = HostRef::new(Store::new(&engine)); let binary = parse_str( r#" diff --git a/crates/fuzzing/src/oracles.rs b/crates/fuzzing/src/oracles.rs index 1068cb8521..004f1ad906 100644 --- a/crates/fuzzing/src/oracles.rs +++ b/crates/fuzzing/src/oracles.rs @@ -40,7 +40,7 @@ pub fn instantiate(wasm: &[u8], compilation_strategy: CompilationStrategy) { let mut config = Config::new(); config.strategy(compilation_strategy); - let engine = HostRef::new(Engine::new(&config)); + let engine = Engine::new(&config); let store = HostRef::new(Store::new(&engine)); let module = @@ -89,7 +89,7 @@ pub fn make_api_calls(api: crate::generators::api::ApiCalls) { use crate::generators::api::ApiCall; let mut config: Option = None; - let mut engine: Option> = None; + let mut engine: Option = None; let mut store: Option> = None; let mut modules: HashMap> = Default::default(); let mut instances: HashMap> = Default::default(); @@ -107,7 +107,7 @@ pub fn make_api_calls(api: crate::generators::api::ApiCalls) { ApiCall::EngineNew => { assert!(engine.is_none()); - engine = Some(HostRef::new(Engine::new(config.as_ref().unwrap()))); + engine = Some(Engine::new(config.as_ref().unwrap())); } ApiCall::StoreNew => { diff --git a/crates/misc/py/src/lib.rs b/crates/misc/py/src/lib.rs index 7e56b06977..f10016a58e 100644 --- a/crates/misc/py/src/lib.rs +++ b/crates/misc/py/src/lib.rs @@ -92,7 +92,7 @@ pub fn instantiate( ..Default::default() }); - let engine = wasmtime::HostRef::new(wasmtime::Engine::new(&config)); + let engine = wasmtime::Engine::new(&config); let store = wasmtime::HostRef::new(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 03d167eef8..f53095367f 100644 --- a/crates/misc/rust/macro/src/lib.rs +++ b/crates/misc/rust/macro/src/lib.rs @@ -56,7 +56,7 @@ fn generate_load(item: &syn::ItemTrait) -> syn::Result { multi_value: true, ..Default::default() }); - let engine = HostRef::new(Engine::new(&config)); + let engine = Engine::new(&config); let store = HostRef::new(Store::new(&engine)); let global_exports = store.borrow().global_exports().clone(); diff --git a/crates/test-programs/tests/wasm_tests/runtime.rs b/crates/test-programs/tests/wasm_tests/runtime.rs index b8c88308ba..6688b022e6 100644 --- a/crates/test-programs/tests/wasm_tests/runtime.rs +++ b/crates/test-programs/tests/wasm_tests/runtime.rs @@ -15,7 +15,7 @@ pub fn instantiate(data: &[u8], bin_name: &str, workspace: Option<&Path>) -> any let mut config = Config::new(); config.flags(settings::Flags::new(flag_builder)); - let engine = HostRef::new(Engine::new(&config)); + let engine = Engine::new(&config); let store = HostRef::new(Store::new(&engine)); let global_exports = store.borrow().global_exports().clone(); diff --git a/docs/embed-rust.md b/docs/embed-rust.md index a37d767617..f09196c133 100644 --- a/docs/embed-rust.md +++ b/docs/embed-rust.md @@ -38,7 +38,7 @@ It is time to add code to the `src/main.rs`. First, the engine and storage need ```rust use wasmtime::*; -let engine = HostRef::new(Engine::default()); +let engine = Engine::default(); let store = HostRef::new(Store::new(&engine)); ``` @@ -87,7 +87,7 @@ use std::fs::read; use wasmtime::*; fn main() { - let engine = HostRef::new(Engine::default()); + let engine = Engine::default(); let store = HostRef::new(Store::new(&engine)); let wasm = read("hello.wasm").expect("wasm file"); diff --git a/src/bin/wasmtime.rs b/src/bin/wasmtime.rs index 4a8be1441f..b6f325fb44 100644 --- a/src/bin/wasmtime.rs +++ b/src/bin/wasmtime.rs @@ -266,7 +266,7 @@ fn main() -> Result<()> { .flags(settings::Flags::new(flag_builder)) .debug_info(debug_info) .strategy(strategy); - let engine = HostRef::new(Engine::new(&config)); + let engine = Engine::new(&config); let store = HostRef::new(Store::new(&engine)); let mut module_registry = HashMap::new(); diff --git a/src/bin/wast.rs b/src/bin/wast.rs index ba89bfc08b..0973baa5af 100644 --- a/src/bin/wast.rs +++ b/src/bin/wast.rs @@ -154,7 +154,7 @@ fn main() { cfg.strategy(strategy) .flags(settings::Flags::new(flag_builder)) .features(features); - let store = HostRef::new(Store::new(&HostRef::new(Engine::new(&cfg)))); + let store = HostRef::new(Store::new(&Engine::new(&cfg))); let mut wast_context = WastContext::new(store); wast_context diff --git a/tests/wast_testsuites.rs b/tests/wast_testsuites.rs index 1a0c1748c6..544aa3c870 100644 --- a/tests/wast_testsuites.rs +++ b/tests/wast_testsuites.rs @@ -27,7 +27,7 @@ fn run_wast(wast: &str, strategy: CompilationStrategy) -> anyhow::Result<()> { cfg.strategy(strategy) .flags(settings::Flags::new(flag_builder)) .features(features); - let store = HostRef::new(Store::new(&HostRef::new(Engine::new(&cfg)))); + let store = HostRef::new(Store::new(&Engine::new(&cfg))); let mut wast_context = WastContext::new(store); wast_context.register_spectest()?; wast_context.run_file(wast)?;