diff --git a/crates/api/src/instance.rs b/crates/api/src/instance.rs index e28d6e8b28..b5d433fe2d 100644 --- a/crates/api/src/instance.rs +++ b/crates/api/src/instance.rs @@ -121,10 +121,7 @@ impl Instance { Some(&self.exports()[i]) } - pub fn from_handle( - store: &HostRef, - instance_handle: InstanceHandle, - ) -> Result { + pub fn from_handle(store: &HostRef, instance_handle: InstanceHandle) -> Instance { let contexts = HashSet::new(); let mut exports = Vec::new(); @@ -152,12 +149,12 @@ impl Instance { exports_types.into_boxed_slice(), )); - Ok(Instance { + Instance { instance_handle, module, contexts, exports: exports.into_boxed_slice(), - }) + } } pub fn handle(&self) -> &InstanceHandle { diff --git a/crates/misc/py/src/lib.rs b/crates/misc/py/src/lib.rs index c250acd37c..6d71a2dfe4 100644 --- a/crates/misc/py/src/lib.rs +++ b/crates/misc/py/src/lib.rs @@ -103,11 +103,8 @@ pub fn instantiate( // If this module expects to be able to use wasi then go ahead and hook // that up into the imported crates. let wasi = if let Some(module_name) = data.find_wasi_module_name() { - let global_exports = store.borrow().global_exports().clone(); - let wasi_handle = wasmtime_wasi::instantiate_wasi("", global_exports, &[], &[], &[]) + let instance = wasmtime_wasi::create_wasi_instance(&store, &[], &[], &[]) .map_err(|e| err2py(e.into()))?; - let instance = - api::Instance::from_handle(&store, wasi_handle).map_err(|e| err2py(e.into()))?; Some((module_name, instance)) } else { None diff --git a/crates/misc/rust/macro/src/lib.rs b/crates/misc/rust/macro/src/lib.rs index e94deb6b0d..be1c1b4783 100644 --- a/crates/misc/rust/macro/src/lib.rs +++ b/crates/misc/rust/macro/src/lib.rs @@ -66,14 +66,8 @@ fn generate_load(item: &syn::ItemTrait) -> syn::Result { let mut imports: Vec = Vec::new(); if let Some(module_name) = data.find_wasi_module_name() { - let wasi_handle = wasmtime_wasi::instantiate_wasi( - "", - global_exports, - &[], - &[], - &[], - )?; - let wasi_instance = Instance::from_handle(&store, wasi_handle)?; + let wasi_instance = wasmtime_wasi::create_wasi_instance(&store, &[], &[], &[]) + .map_err(|e| format_err!("wasm instantiation error: {:?}", e))?; for i in module.borrow().imports().iter() { if i.module().as_str() != module_name { bail!("unknown import module {}", i.module().as_str()); diff --git a/crates/test-programs/tests/wasm_tests/runtime.rs b/crates/test-programs/tests/wasm_tests/runtime.rs index 3d06b6cfbb..8b27ecd2ae 100644 --- a/crates/test-programs/tests/wasm_tests/runtime.rs +++ b/crates/test-programs/tests/wasm_tests/runtime.rs @@ -58,8 +58,7 @@ pub fn instantiate(data: &[u8], bin_name: &str, workspace: Option<&Path>) -> any builder.build().context("failed to build wasi context")?, ) .context("failed to instantiate wasi")?, - ) - .context("failed to create instance from handle")?, + ), ); let module = HostRef::new(Module::new(&store, &data).context("failed to create wasm module")?); diff --git a/crates/wasi/Cargo.toml b/crates/wasi/Cargo.toml index 7592a6b351..d35b6994ac 100644 --- a/crates/wasi/Cargo.toml +++ b/crates/wasi/Cargo.toml @@ -11,6 +11,7 @@ readme = "README.md" edition = "2018" [dependencies] +wasmtime = { path = "../api" } wasmtime-runtime = { path = "../runtime" } wasmtime-environ = { path = "../environ" } wasmtime-jit = { path = "../jit" } diff --git a/crates/wasi/src/instantiate.rs b/crates/wasi/src/instantiate.rs index 003f2f0cdc..e66ce88c52 100644 --- a/crates/wasi/src/instantiate.rs +++ b/crates/wasi/src/instantiate.rs @@ -9,9 +9,23 @@ use std::collections::HashMap; use std::fs::File; use target_lexicon::HOST; use wasi_common::{WasiCtx, WasiCtxBuilder}; +use wasmtime_api as api; use wasmtime_environ::{translate_signature, Export, Module}; use wasmtime_runtime::{Imports, InstanceHandle, InstantiationError, VMFunctionBody}; +/// Creates `api::Instance` object implementing the "wasi" interface. +pub fn create_wasi_instance( + store: &api::HostRef, + preopened_dirs: &[(String, File)], + argv: &[String], + environ: &[(String, String)], +) -> Result { + let global_exports = store.borrow().global_exports().clone(); + let wasi = instantiate_wasi("", global_exports, preopened_dirs, argv, environ)?; + let instance = api::Instance::from_handle(&store, wasi); + Ok(instance) +} + /// Return an instance implementing the "wasi" interface. pub fn instantiate_wasi( prefix: &str, diff --git a/crates/wasi/src/lib.rs b/crates/wasi/src/lib.rs index 7ef37df6b7..ef699ce0b6 100644 --- a/crates/wasi/src/lib.rs +++ b/crates/wasi/src/lib.rs @@ -5,7 +5,7 @@ extern crate alloc; mod instantiate; mod syscalls; -pub use instantiate::{instantiate_wasi, instantiate_wasi_with_context}; +pub use instantiate::{create_wasi_instance, instantiate_wasi, instantiate_wasi_with_context}; pub fn is_wasi_module(name: &str) -> bool { // FIXME: this should be more conservative, but while WASI is in flux and diff --git a/src/bin/wasmtime.rs b/src/bin/wasmtime.rs index 0539f3c322..e19dbd67f3 100644 --- a/src/bin/wasmtime.rs +++ b/src/bin/wasmtime.rs @@ -46,7 +46,7 @@ use wasmtime_cli::pick_compilation_strategy; use wasmtime_environ::{cache_create_new_config, cache_init}; use wasmtime_interface_types::ModuleData; use wasmtime_jit::Features; -use wasmtime_wasi::instantiate_wasi; +use wasmtime_wasi::create_wasi_instance; #[cfg(feature = "wasi-c")] use wasmtime_wasi_c::instantiate_wasi_c; use wasmtime_wast::instantiate_spectest; @@ -281,36 +281,31 @@ fn main() -> Result<()> { // Make spectest available by default. module_registry.insert( "spectest".to_owned(), - Instance::from_handle(&store, instantiate_spectest()?)?, + HostRef::new(Instance::from_handle(&store, instantiate_spectest()?)), ); // Make wasi available by default. - let global_exports = store.borrow().global_exports().clone(); let preopen_dirs = compute_preopen_dirs(&args.flag_dir, &args.flag_mapdir); let argv = compute_argv(&args.arg_file, &args.arg_arg); let environ = compute_environ(&args.flag_env); - let wasi = if args.flag_wasi_c { + let wasi = HostRef::new(if args.flag_wasi_c { #[cfg(feature = "wasi-c")] { - instantiate_wasi_c("", global_exports.clone(), &preopen_dirs, &argv, &environ)? + let global_exports = store.borrow().global_exports().clone(); + let handle = instantiate_wasi_c("", global_exports, &preopen_dirs, &argv, &environ)?; + Instance::from_handle(&store, handle) } #[cfg(not(feature = "wasi-c"))] { bail!("wasi-c feature not enabled at build time") } } else { - instantiate_wasi("", global_exports.clone(), &preopen_dirs, &argv, &environ)? - }; + create_wasi_instance(&store, &preopen_dirs, &argv, &environ)? + }); - module_registry.insert( - "wasi_unstable".to_owned(), - Instance::from_handle(&store, wasi.clone())?, - ); - module_registry.insert( - "wasi_unstable_preview0".to_owned(), - Instance::from_handle(&store, wasi)?, - ); + module_registry.insert("wasi_unstable".to_owned(), wasi.clone()); + module_registry.insert("wasi_unstable_preview0".to_owned(), wasi); // Load the preload wasm modules. for filename in &args.flag_preload { @@ -328,7 +323,7 @@ fn main() -> Result<()> { fn instantiate_module( store: &HostRef, - module_registry: &HashMap, + module_registry: &HashMap>, path: &Path, ) -> Result<(HostRef, HostRef, Vec)> { // Read the wasm module binary either as `*.wat` or a raw binary @@ -345,7 +340,7 @@ fn instantiate_module( let module_name = i.module().as_str(); if let Some(instance) = module_registry.get(module_name) { let field_name = i.name().as_str(); - if let Some(export) = instance.find_export_by_name(field_name) { + if let Some(export) = instance.borrow().find_export_by_name(field_name) { Ok(export.clone()) } else { bail!( @@ -367,7 +362,7 @@ fn instantiate_module( fn handle_module( store: &HostRef, - module_registry: &HashMap, + module_registry: &HashMap>, args: &Args, path: &Path, ) -> Result<()> {