diff --git a/crates/api/src/externals.rs b/crates/api/src/externals.rs
index fda3d1b635..70d796e047 100644
--- a/crates/api/src/externals.rs
+++ b/crates/api/src/externals.rs
@@ -181,7 +181,7 @@ impl Global {
if val.ty() != *ty.content() {
bail!("value provided does not match the type of this global");
}
- let (wasmtime_export, wasmtime_state) = generate_global_export(&ty, val)?;
+ let (wasmtime_export, wasmtime_state) = generate_global_export(store, &ty, val)?;
Ok(Global {
inner: Rc::new(GlobalInner {
_store: store.clone(),
@@ -321,7 +321,7 @@ impl Table {
/// Returns an error if `init` does not match the element type of the table.
pub fn new(store: &Store, ty: TableType, init: Val) -> Result
{
let item = into_checked_anyfunc(init, store)?;
- let (mut wasmtime_handle, wasmtime_export) = generate_table_export(&ty)?;
+ let (mut wasmtime_handle, wasmtime_export) = generate_table_export(store, &ty)?;
// Initialize entries with the init value.
match wasmtime_export {
@@ -473,7 +473,7 @@ impl Memory {
/// type's configuration. All WebAssembly memory is initialized to zero.
pub fn new(store: &Store, ty: MemoryType) -> Memory {
let (wasmtime_handle, wasmtime_export) =
- generate_memory_export(&ty).expect("generated memory");
+ generate_memory_export(store, &ty).expect("generated memory");
Memory {
_store: store.clone(),
ty,
diff --git a/crates/api/src/trampoline/create_handle.rs b/crates/api/src/trampoline/create_handle.rs
index 860dbbe4da..679f9ef45c 100644
--- a/crates/api/src/trampoline/create_handle.rs
+++ b/crates/api/src/trampoline/create_handle.rs
@@ -12,7 +12,7 @@ use wasmtime_runtime::{Imports, InstanceHandle, VMFunctionBody};
pub(crate) fn create_handle(
module: Module,
- store: Option<&Store>,
+ store: &Store,
finished_functions: PrimaryMap,
state: Box,
) -> Result {
@@ -26,19 +26,16 @@ pub(crate) fn create_handle(
let data_initializers = Vec::new();
// Compute indices into the shared signature table.
- let signatures = store
- .map(|store| {
- module
- .signatures
- .values()
- .map(|sig| store.compiler().signatures().register(sig))
- .collect::>()
- })
- .unwrap_or_else(PrimaryMap::new);
+ let signatures = module
+ .signatures
+ .values()
+ .map(|sig| store.compiler().signatures().register(sig))
+ .collect::>();
unsafe {
Ok(InstanceHandle::new(
Arc::new(module),
+ store.compiler().trap_registry().register_traps(Vec::new()),
finished_functions.into_boxed_slice(),
imports,
&data_initializers,
diff --git a/crates/api/src/trampoline/func.rs b/crates/api/src/trampoline/func.rs
index 4a522b9dfd..bced16addb 100644
--- a/crates/api/src/trampoline/func.rs
+++ b/crates/api/src/trampoline/func.rs
@@ -287,7 +287,7 @@ pub fn create_handle_with_function(
create_handle(
module,
- Some(store),
+ store,
finished_functions,
Box::new(trampoline_state),
)
@@ -322,5 +322,5 @@ pub unsafe fn create_handle_with_raw_function(
.insert("trampoline".to_string(), Export::Function(func_id));
finished_functions.push(func);
- create_handle(module, Some(store), finished_functions, state)
+ create_handle(module, store, finished_functions, state)
}
diff --git a/crates/api/src/trampoline/global.rs b/crates/api/src/trampoline/global.rs
index 58b702d339..c36226f923 100644
--- a/crates/api/src/trampoline/global.rs
+++ b/crates/api/src/trampoline/global.rs
@@ -1,4 +1,5 @@
use super::create_handle::create_handle;
+use crate::Store;
use crate::{GlobalType, Mutability, Val};
use anyhow::{bail, Result};
use wasmtime_environ::entity::PrimaryMap;
@@ -11,7 +12,11 @@ pub struct GlobalState {
handle: InstanceHandle,
}
-pub fn create_global(gt: &GlobalType, val: Val) -> Result<(wasmtime_runtime::Export, GlobalState)> {
+pub fn create_global(
+ store: &Store,
+ gt: &GlobalType,
+ val: Val,
+) -> Result<(wasmtime_runtime::Export, GlobalState)> {
let mut definition = Box::new(VMGlobalDefinition::new());
unsafe {
match val {
@@ -35,7 +40,7 @@ pub fn create_global(gt: &GlobalType, val: Val) -> Result<(wasmtime_runtime::Exp
initializer: wasm::GlobalInit::Import, // TODO is it right?
};
let handle =
- create_handle(Module::new(), None, PrimaryMap::new(), Box::new(())).expect("handle");
+ create_handle(Module::new(), store, PrimaryMap::new(), Box::new(())).expect("handle");
Ok((
wasmtime_runtime::Export::Global {
definition: definition.as_mut(),
diff --git a/crates/api/src/trampoline/memory.rs b/crates/api/src/trampoline/memory.rs
index 9437876219..6a4bb8c42d 100644
--- a/crates/api/src/trampoline/memory.rs
+++ b/crates/api/src/trampoline/memory.rs
@@ -1,13 +1,12 @@
use super::create_handle::create_handle;
use crate::MemoryType;
+use crate::Store;
use anyhow::Result;
use wasmtime_environ::entity::PrimaryMap;
use wasmtime_environ::{wasm, Module};
use wasmtime_runtime::InstanceHandle;
-#[allow(dead_code)]
-
-pub fn create_handle_with_memory(memory: &MemoryType) -> Result {
+pub fn create_handle_with_memory(store: &Store, memory: &MemoryType) -> Result {
let mut module = Module::new();
let memory = wasm::Memory {
@@ -24,5 +23,5 @@ pub fn create_handle_with_memory(memory: &MemoryType) -> Result
wasmtime_environ::Export::Memory(memory_id),
);
- create_handle(module, None, PrimaryMap::new(), Box::new(()))
+ create_handle(module, store, PrimaryMap::new(), Box::new(()))
}
diff --git a/crates/api/src/trampoline/mod.rs b/crates/api/src/trampoline/mod.rs
index 7047f0be49..9e7754a95c 100644
--- a/crates/api/src/trampoline/mod.rs
+++ b/crates/api/src/trampoline/mod.rs
@@ -43,24 +43,27 @@ pub unsafe fn generate_raw_func_export(
}
pub fn generate_global_export(
+ store: &Store,
gt: &GlobalType,
val: Val,
) -> Result<(wasmtime_runtime::Export, GlobalState)> {
- create_global(gt, val)
+ create_global(store, gt, val)
}
pub fn generate_memory_export(
+ store: &Store,
m: &MemoryType,
) -> Result<(wasmtime_runtime::InstanceHandle, wasmtime_runtime::Export)> {
- let instance = create_handle_with_memory(m)?;
+ let instance = create_handle_with_memory(store, m)?;
let export = instance.lookup("memory").expect("memory export");
Ok((instance, export))
}
pub fn generate_table_export(
+ store: &Store,
t: &TableType,
) -> Result<(wasmtime_runtime::InstanceHandle, wasmtime_runtime::Export)> {
- let instance = create_handle_with_table(t)?;
+ let instance = create_handle_with_table(store, t)?;
let export = instance.lookup("table").expect("table export");
Ok((instance, export))
}
diff --git a/crates/api/src/trampoline/table.rs b/crates/api/src/trampoline/table.rs
index 920012dc66..9506e99596 100644
--- a/crates/api/src/trampoline/table.rs
+++ b/crates/api/src/trampoline/table.rs
@@ -1,11 +1,12 @@
use super::create_handle::create_handle;
+use crate::Store;
use crate::{TableType, ValType};
use anyhow::{bail, Result};
use wasmtime_environ::entity::PrimaryMap;
use wasmtime_environ::{wasm, Module};
use wasmtime_runtime::InstanceHandle;
-pub fn create_handle_with_table(table: &TableType) -> Result {
+pub fn create_handle_with_table(store: &Store, table: &TableType) -> Result {
let mut module = Module::new();
let table = wasm::Table {
@@ -25,5 +26,5 @@ pub fn create_handle_with_table(table: &TableType) -> Result {
wasmtime_environ::Export::Table(table_id),
);
- create_handle(module, None, PrimaryMap::new(), Box::new(()))
+ create_handle(module, store, PrimaryMap::new(), Box::new(()))
}
diff --git a/crates/api/tests/traps.rs b/crates/api/tests/traps.rs
index 255071b89b..5ef3bf2644 100644
--- a/crates/api/tests/traps.rs
+++ b/crates/api/tests/traps.rs
@@ -63,7 +63,11 @@ fn test_trap_trace() -> Result<()> {
assert_eq!(trace[1].module_name().unwrap(), "hello_mod");
assert_eq!(trace[1].func_index(), 0);
assert_eq!(trace[1].func_name(), None);
- assert!(e.message().contains("unreachable"));
+ assert!(
+ e.message().contains("unreachable"),
+ "wrong message: {}",
+ e.message()
+ );
Ok(())
}
diff --git a/crates/jit/src/compiler.rs b/crates/jit/src/compiler.rs
index ca4d8012d8..7eb7cc4a40 100644
--- a/crates/jit/src/compiler.rs
+++ b/crates/jit/src/compiler.rs
@@ -21,8 +21,8 @@ use wasmtime_environ::{
VMOffsets,
};
use wasmtime_runtime::{
- get_mut_trap_registry, jit_function_registry, InstantiationError, SignatureRegistry,
- TrapRegistrationGuard, VMFunctionBody,
+ jit_function_registry, InstantiationError, SignatureRegistry, TrapRegistration, TrapRegistry,
+ VMFunctionBody,
};
/// Select which kind of compilation to use.
@@ -51,8 +51,8 @@ pub struct Compiler {
isa: Box,
code_memory: CodeMemory,
- trap_registration_guards: Vec,
jit_function_ranges: Vec<(usize, usize)>,
+ trap_registry: TrapRegistry,
trampoline_park: HashMap<*const VMFunctionBody, *const VMFunctionBody>,
signatures: SignatureRegistry,
strategy: CompilationStrategy,
@@ -67,28 +67,18 @@ impl Compiler {
Self {
isa,
code_memory: CodeMemory::new(),
- trap_registration_guards: Vec::new(),
jit_function_ranges: Vec::new(),
trampoline_park: HashMap::new(),
signatures: SignatureRegistry::new(),
fn_builder_ctx: FunctionBuilderContext::new(),
strategy,
+ trap_registry: TrapRegistry::default(),
}
}
}
impl Drop for Compiler {
fn drop(&mut self) {
- // We must deregister traps before freeing the code memory.
- // Otherwise, we have a race:
- // - Compiler #1 dropped code memory, but hasn't deregistered the trap yet
- // - Compiler #2 allocated code memory and tries to register a trap,
- // but the trap at certain address happens to be already registered,
- // since Compiler #1 hasn't deregistered it yet => assertion in trap registry fails.
- // Having a custom drop implementation we are independent from the field order
- // in the struct what reduces potential human error.
- self.trap_registration_guards.clear();
-
for (start, end) in self.jit_function_ranges.iter() {
jit_function_registry::unregister(*start, *end);
}
@@ -119,6 +109,7 @@ impl Compiler {
PrimaryMap,
Relocations,
Option>,
+ TrapRegistration,
),
SetupError,
> {
@@ -156,11 +147,7 @@ impl Compiler {
)))
})?;
- register_traps(
- &allocated_functions,
- &traps,
- &mut self.trap_registration_guards,
- );
+ let trap_registration = register_traps(&allocated_functions, &traps, &self.trap_registry);
for (i, allocated) in allocated_functions.iter() {
let ptr = (*allocated) as *const VMFunctionBody;
@@ -217,7 +204,13 @@ impl Compiler {
let jt_offsets = compilation.get_jt_offsets();
- Ok((allocated_functions, jt_offsets, relocations, dbg))
+ Ok((
+ allocated_functions,
+ jt_offsets,
+ relocations,
+ dbg,
+ trap_registration,
+ ))
}
/// Create a trampoline for invoking a function.
@@ -267,6 +260,11 @@ impl Compiler {
pub fn signatures(&self) -> &SignatureRegistry {
&self.signatures
}
+
+ /// Shared registration of trap information
+ pub fn trap_registry(&self) -> &TrapRegistry {
+ &self.trap_registry
+ }
}
/// Create a trampoline for invoking a function.
@@ -408,19 +406,21 @@ fn allocate_functions(
fn register_traps(
allocated_functions: &PrimaryMap,
traps: &Traps,
- trap_registration_guards: &mut Vec,
-) {
- let mut trap_registry = get_mut_trap_registry();
- for (func_addr, func_traps) in allocated_functions.values().zip(traps.values()) {
- for trap_desc in func_traps.iter() {
- let func_addr = *func_addr as *const u8 as usize;
- let offset = usize::try_from(trap_desc.code_offset).unwrap();
- let trap_addr = func_addr + offset;
- let guard =
- trap_registry.register_trap(trap_addr, trap_desc.source_loc, trap_desc.trap_code);
- trap_registration_guards.push(guard);
- }
- }
+ registry: &TrapRegistry,
+) -> TrapRegistration {
+ let traps =
+ allocated_functions
+ .values()
+ .zip(traps.values())
+ .flat_map(|(func_addr, func_traps)| {
+ func_traps.iter().map(move |trap_desc| {
+ let func_addr = *func_addr as *const u8 as usize;
+ let offset = usize::try_from(trap_desc.code_offset).unwrap();
+ let trap_addr = func_addr + offset;
+ (trap_addr, trap_desc.source_loc, trap_desc.trap_code)
+ })
+ });
+ registry.register_traps(traps)
}
/// We don't expect trampoline compilation to produce any relocations, so
diff --git a/crates/jit/src/instantiate.rs b/crates/jit/src/instantiate.rs
index c86b664fc8..790e10276f 100644
--- a/crates/jit/src/instantiate.rs
+++ b/crates/jit/src/instantiate.rs
@@ -18,7 +18,7 @@ use wasmtime_environ::{
CompileError, DataInitializer, DataInitializerLocation, Module, ModuleEnvironment,
};
use wasmtime_runtime::{
- GdbJitImageRegistration, InstanceHandle, InstantiationError, VMFunctionBody,
+ GdbJitImageRegistration, InstanceHandle, InstantiationError, TrapRegistration, VMFunctionBody,
VMSharedSignatureIndex,
};
@@ -52,6 +52,7 @@ struct RawCompiledModule<'data> {
data_initializers: Box<[DataInitializer<'data>]>,
signatures: BoxedSlice,
dbg_jit_registration: Option,
+ trap_registration: TrapRegistration,
}
impl<'data> RawCompiledModule<'data> {
@@ -73,12 +74,13 @@ impl<'data> RawCompiledModule<'data> {
None
};
- let (allocated_functions, jt_offsets, relocations, dbg_image) = compiler.compile(
- &translation.module,
- translation.module_translation.as_ref().unwrap(),
- translation.function_body_inputs,
- debug_data,
- )?;
+ let (allocated_functions, jt_offsets, relocations, dbg_image, trap_registration) = compiler
+ .compile(
+ &translation.module,
+ translation.module_translation.as_ref().unwrap(),
+ translation.function_body_inputs,
+ debug_data,
+ )?;
link_module(
&translation.module,
@@ -127,6 +129,7 @@ impl<'data> RawCompiledModule<'data> {
data_initializers: translation.data_initializers.into_boxed_slice(),
signatures: signatures.into_boxed_slice(),
dbg_jit_registration,
+ trap_registration,
})
}
}
@@ -138,6 +141,7 @@ pub struct CompiledModule {
data_initializers: Box<[OwnedDataInitializer]>,
signatures: BoxedSlice,
dbg_jit_registration: Option>,
+ trap_registration: TrapRegistration,
}
impl CompiledModule {
@@ -159,6 +163,7 @@ impl CompiledModule {
.into_boxed_slice(),
raw.signatures.clone(),
raw.dbg_jit_registration,
+ raw.trap_registration,
))
}
@@ -169,6 +174,7 @@ impl CompiledModule {
data_initializers: Box<[OwnedDataInitializer]>,
signatures: BoxedSlice,
dbg_jit_registration: Option,
+ trap_registration: TrapRegistration,
) -> Self {
Self {
module: Arc::new(module),
@@ -176,6 +182,7 @@ impl CompiledModule {
data_initializers,
signatures,
dbg_jit_registration: dbg_jit_registration.map(Rc::new),
+ trap_registration,
}
}
@@ -203,6 +210,7 @@ impl CompiledModule {
let imports = resolve_imports(&self.module, resolver)?;
InstanceHandle::new(
Arc::clone(&self.module),
+ self.trap_registration.clone(),
self.finished_functions.clone(),
imports,
&data_initializers,
diff --git a/crates/runtime/src/instance.rs b/crates/runtime/src/instance.rs
index 794f20a432..be3cc45fb4 100644
--- a/crates/runtime/src/instance.rs
+++ b/crates/runtime/src/instance.rs
@@ -15,6 +15,7 @@ use crate::vmcontext::{
VMGlobalDefinition, VMGlobalImport, VMMemoryDefinition, VMMemoryImport, VMSharedSignatureIndex,
VMTableDefinition, VMTableImport,
};
+use crate::TrapRegistration;
use memoffset::offset_of;
use more_asserts::assert_lt;
use std::any::Any;
@@ -100,6 +101,10 @@ pub(crate) struct Instance {
/// Handler run when `SIGBUS`, `SIGFPE`, `SIGILL`, or `SIGSEGV` are caught by the instance thread.
pub(crate) signal_handler: Cell