diff --git a/crates/api/src/instance.rs b/crates/api/src/instance.rs index d60c3d17f9..fd576d987f 100644 --- a/crates/api/src/instance.rs +++ b/crates/api/src/instance.rs @@ -3,6 +3,7 @@ use crate::module::Module; use crate::runtime::{Config, Store}; use crate::trap::Trap; use anyhow::{bail, Error, Result}; +use std::any::Any; use wasmtime_jit::{CompiledModule, Resolver}; use wasmtime_runtime::{Export, InstanceHandle, InstantiationError, SignatureRegistry}; @@ -23,6 +24,7 @@ fn instantiate( compiled_module: &CompiledModule, imports: &[Extern], sig_registry: &SignatureRegistry, + host: Box, ) -> Result { let mut resolver = SimpleResolver { imports }; unsafe { @@ -32,6 +34,7 @@ fn instantiate( &mut resolver, sig_registry, config.memory_creator.as_ref().map(|a| a as _), + host, ) .map_err(|e| -> Error { match e { @@ -132,13 +135,14 @@ impl Instance { ); } - module.register_frame_info(); + let info = module.register_frame_info(); let config = store.engine().config(); let instance_handle = instantiate( config, module.compiled_module(), imports, store.compiler().signatures(), + Box::new(info), )?; let mut exports = Vec::with_capacity(module.exports().len()); diff --git a/crates/api/src/module.rs b/crates/api/src/module.rs index a92d469ce9..1060167a9d 100644 --- a/crates/api/src/module.rs +++ b/crates/api/src/module.rs @@ -137,7 +137,7 @@ struct ModuleInner { imports: Box<[ImportType]>, exports: Box<[ExportType]>, compiled: CompiledModule, - frame_info_registration: Mutex>>, + frame_info_registration: Mutex>>>, } impl Module { @@ -665,11 +665,13 @@ and for re-adding support for interface types you can see this issue: /// Register this module's stack frame information into the global scope. /// /// This is required to ensure that any traps can be properly symbolicated. - pub(crate) fn register_frame_info(&self) { + pub(crate) fn register_frame_info(&self) -> Option> { let mut info = self.inner.frame_info_registration.lock().unwrap(); - if info.is_some() { - return; + if let Some(info) = &*info { + return info.clone(); } - *info = Some(super::frame_info::register(&self.inner.compiled)); + let ret = super::frame_info::register(&self.inner.compiled).map(Arc::new); + *info = Some(ret.clone()); + return ret; } } diff --git a/crates/api/tests/traps.rs b/crates/api/tests/traps.rs index f1f836bc14..755fa81203 100644 --- a/crates/api/tests/traps.rs +++ b/crates/api/tests/traps.rs @@ -411,3 +411,25 @@ wasm backtrace: ); Ok(()) } + +#[test] +fn present_after_module_drop() -> Result<()> { + let store = Store::default(); + let module = Module::new(&store, r#"(func (export "foo") unreachable)"#)?; + let instance = Instance::new(&module, &[])?; + let func = instance.exports()[0].func().unwrap().clone(); + + println!("asserting before we drop modules"); + assert_trap(func.call(&[]).unwrap_err().downcast()?); + drop((instance, module)); + + println!("asserting after drop"); + assert_trap(func.call(&[]).unwrap_err().downcast()?); + return Ok(()); + + fn assert_trap(t: Trap) { + println!("{}", t); + assert_eq!(t.trace().len(), 1); + assert_eq!(t.trace()[0].func_index(), 0); + } +} diff --git a/crates/jit/src/instantiate.rs b/crates/jit/src/instantiate.rs index 8aa6487160..d8d92089db 100644 --- a/crates/jit/src/instantiate.rs +++ b/crates/jit/src/instantiate.rs @@ -7,6 +7,7 @@ use crate::compiler::Compiler; use crate::imports::resolve_imports; use crate::link::link_module; use crate::resolver::Resolver; +use std::any::Any; use std::collections::HashMap; use std::io::Write; use std::rc::Rc; @@ -202,6 +203,7 @@ impl CompiledModule { resolver: &mut dyn Resolver, sig_registry: &SignatureRegistry, mem_creator: Option<&dyn RuntimeMemoryCreator>, + host_state: Box, ) -> Result { let data_initializers = self .data_initializers @@ -222,7 +224,7 @@ impl CompiledModule { self.signatures.clone(), self.dbg_jit_registration.as_ref().map(|r| Rc::clone(&r)), is_bulk_memory, - Box::new(()), + host_state, ) } @@ -275,29 +277,3 @@ impl OwnedDataInitializer { } } } - -/// Create a new wasm instance by compiling the wasm module in `data` and instatiating it. -/// -/// This is equivalent to creating a `CompiledModule` and calling `instantiate()` on it, -/// but avoids creating an intermediate copy of the data initializers. -/// -/// # Unsafety -/// -/// See `InstanceHandle::new` -#[allow(clippy::implicit_hasher)] -pub unsafe fn instantiate( - compiler: &mut Compiler, - data: &[u8], - resolver: &mut dyn Resolver, - is_bulk_memory: bool, - profiler: &dyn ProfilingAgent, - mem_creator: Option<&dyn RuntimeMemoryCreator>, -) -> Result { - let instance = CompiledModule::new(compiler, data, profiler)?.instantiate( - is_bulk_memory, - resolver, - compiler.signatures(), - mem_creator, - )?; - Ok(instance) -} diff --git a/crates/jit/src/lib.rs b/crates/jit/src/lib.rs index 057e76c125..f6148e21cb 100644 --- a/crates/jit/src/lib.rs +++ b/crates/jit/src/lib.rs @@ -34,7 +34,7 @@ pub mod trampoline; pub use crate::code_memory::CodeMemory; pub use crate::compiler::{make_trampoline, Compilation, CompilationStrategy, Compiler}; -pub use crate::instantiate::{instantiate, CompiledModule, SetupError}; +pub use crate::instantiate::{CompiledModule, SetupError}; pub use crate::link::link_module; pub use crate::resolver::{NullResolver, Resolver};