Refactor how signatures/trampolines are stored in Store

This commit refactors where trampolines and signature information is
stored within a `Store`, namely moving them from
`wasmtime_runtime::Instance` instead to `Store` itself. The goal here is
to remove an allocation inside of an `Instance` and make them a bit
cheaper to create. Additionally this should open up future possibilities
like not creating duplicate trampolines for signatures already in the
`Store` when using `Func::new`.
This commit is contained in:
Alex Crichton
2020-10-25 15:54:21 -07:00
parent de4af90af6
commit 3887881800
14 changed files with 159 additions and 181 deletions

View File

@@ -10,7 +10,6 @@ use crate::object::ObjectUnwindInfo;
use object::File as ObjectFile;
use serde::{Deserialize, Serialize};
use std::any::Any;
use std::collections::HashMap;
use std::sync::Arc;
use thiserror::Error;
use wasmtime_debug::create_gdbjit_image;
@@ -24,8 +23,8 @@ use wasmtime_environ::{
use wasmtime_profiling::ProfilingAgent;
use wasmtime_runtime::{
GdbJitImageRegistration, Imports, InstanceHandle, InstantiationError, RuntimeMemoryCreator,
SignatureRegistry, StackMapRegistry, VMExternRefActivationsTable, VMFunctionBody, VMInterrupts,
VMTrampoline,
StackMapRegistry, VMExternRefActivationsTable, VMFunctionBody, VMInterrupts,
VMSharedSignatureIndex, VMTrampoline,
};
/// An error condition while setting up a wasm instance, be it validation,
@@ -248,37 +247,20 @@ impl CompiledModule {
pub unsafe fn instantiate(
&self,
imports: Imports<'_>,
signature_registry: &mut SignatureRegistry,
lookup_shared_signature: &dyn Fn(SignatureIndex) -> VMSharedSignatureIndex,
mem_creator: Option<&dyn RuntimeMemoryCreator>,
interrupts: *const VMInterrupts,
host_state: Box<dyn Any>,
externref_activations_table: *mut VMExternRefActivationsTable,
stack_map_registry: *mut StackMapRegistry,
) -> Result<InstanceHandle, InstantiationError> {
// Compute indices into the shared signature table.
let signatures = {
self.module
.signatures
.values()
.map(|(wasm_sig, native)| {
signature_registry.register(wasm_sig.clone(), native.clone())
})
.collect::<PrimaryMap<_, _>>()
};
let mut trampolines = HashMap::new();
for (i, trampoline) in self.trampolines.iter() {
trampolines.insert(signatures[i], trampoline.clone());
}
InstanceHandle::new(
self.module.clone(),
self.code.clone(),
&self.finished_functions.0,
trampolines,
imports,
mem_creator,
signatures.into_boxed_slice(),
lookup_shared_signature,
host_state,
interrupts,
externref_activations_table,
@@ -312,6 +294,11 @@ impl CompiledModule {
&self.finished_functions.0
}
/// Returns the per-signature trampolines for this module.
pub fn trampolines(&self) -> &PrimaryMap<SignatureIndex, VMTrampoline> {
&self.trampolines
}
/// Returns the stack map information for all functions defined in this
/// module.
///

View File

@@ -11,7 +11,7 @@ use crate::traphandlers::Trap;
use crate::vmcontext::{
VMBuiltinFunctionsArray, VMCallerCheckedAnyfunc, VMContext, VMFunctionBody, VMFunctionImport,
VMGlobalDefinition, VMGlobalImport, VMInterrupts, VMMemoryDefinition, VMMemoryImport,
VMSharedSignatureIndex, VMTableDefinition, VMTableImport, VMTrampoline,
VMSharedSignatureIndex, VMTableDefinition, VMTableImport,
};
use crate::{ExportFunction, ExportGlobal, ExportMemory, ExportTable};
use memoffset::offset_of;
@@ -62,9 +62,6 @@ pub(crate) struct Instance {
/// get removed. A missing entry is considered equivalent to an empty slice.
passive_data: RefCell<HashMap<DataIndex, Arc<[u8]>>>,
/// Pointers to trampoline functions used to enter particular signatures
trampolines: HashMap<VMSharedSignatureIndex, VMTrampoline>,
/// Hosts can store arbitrary per-instance information here.
host_state: Box<dyn Any>,
@@ -815,10 +812,9 @@ impl InstanceHandle {
module: Arc<Module>,
code: Arc<dyn Any>,
finished_functions: &PrimaryMap<DefinedFuncIndex, *mut [VMFunctionBody]>,
trampolines: HashMap<VMSharedSignatureIndex, VMTrampoline>,
imports: Imports,
mem_creator: Option<&dyn RuntimeMemoryCreator>,
vmshared_signatures: BoxedSlice<SignatureIndex, VMSharedSignatureIndex>,
lookup_shared_signature: &dyn Fn(SignatureIndex) -> VMSharedSignatureIndex,
host_state: Box<dyn Any>,
interrupts: *const VMInterrupts,
externref_activations_table: *mut VMExternRefActivationsTable,
@@ -857,7 +853,6 @@ impl InstanceHandle {
tables,
passive_elements: Default::default(),
passive_data,
trampolines,
host_state,
vmctx: VMContext {},
};
@@ -873,12 +868,12 @@ impl InstanceHandle {
};
let instance = handle.instance();
debug_assert_eq!(vmshared_signatures.len(), handle.module().signatures.len());
ptr::copy(
vmshared_signatures.values().as_slice().as_ptr(),
instance.signature_ids_ptr() as *mut VMSharedSignatureIndex,
vmshared_signatures.len(),
);
let mut ptr = instance.signature_ids_ptr();
for (signature, _) in handle.module().signatures.iter() {
*ptr = lookup_shared_signature(signature);
ptr = ptr.add(1);
}
debug_assert_eq!(imports.functions.len(), handle.module().num_imported_funcs);
ptr::copy(
imports.functions.as_ptr(),
@@ -1128,11 +1123,6 @@ impl InstanceHandle {
self.instance().get_defined_table(index)
}
/// Gets the trampoline pre-registered for a particular signature
pub fn trampoline(&self, sig: VMSharedSignatureIndex) -> Option<VMTrampoline> {
self.instance().trampolines.get(&sig).cloned()
}
/// Return a reference to the contained `Instance`.
pub(crate) fn instance(&self) -> &Instance {
unsafe { &*(self.instance as *const Instance) }

View File

@@ -28,7 +28,6 @@ mod instance;
mod jit_int;
mod memory;
mod mmap;
mod sig_registry;
mod table;
mod traphandlers;
mod vmcontext;
@@ -43,7 +42,6 @@ pub use crate::instance::{InstanceHandle, InstantiationError, LinkError};
pub use crate::jit_int::GdbJitImageRegistration;
pub use crate::memory::{RuntimeLinearMemory, RuntimeMemoryCreator};
pub use crate::mmap::Mmap;
pub use crate::sig_registry::SignatureRegistry;
pub use crate::table::{Table, TableElement};
pub use crate::traphandlers::{
catch_traps, init_traps, raise_lib_trap, raise_user_trap, resume_panic, SignalHandler, Trap,

View File

@@ -492,6 +492,11 @@ impl VMSharedSignatureIndex {
pub fn new(value: u32) -> Self {
Self(value)
}
/// Returns the underlying bits of the index.
pub fn bits(&self) -> u32 {
self.0
}
}
impl Default for VMSharedSignatureIndex {

View File

@@ -540,7 +540,10 @@ impl Func {
pub fn ty(&self) -> FuncType {
// Signatures should always be registered in the store's registry of
// shared signatures, so we should be able to unwrap safely here.
let wft = self.instance.store.lookup_signature(self.sig_index());
let signatures = self.instance.store.signatures().borrow();
let (wft, _, _) = signatures
.lookup_shared(self.sig_index())
.expect("signature should be registered");
// This is only called with `Export::Function`, and since it's coming
// from wasmtime_runtime itself we should support all the types coming
@@ -550,19 +553,19 @@ impl Func {
/// Returns the number of parameters that this function takes.
pub fn param_arity(&self) -> usize {
let sig = self
.instance
.store
.lookup_signature(unsafe { self.export.anyfunc.as_ref().type_index });
let signatures = self.instance.store.signatures().borrow();
let (sig, _, _) = signatures
.lookup_shared(self.sig_index())
.expect("signature should be registered");
sig.params.len()
}
/// Returns the number of results this function produces.
pub fn result_arity(&self) -> usize {
let sig = self
.instance
.store
.lookup_signature(unsafe { self.export.anyfunc.as_ref().type_index });
let signatures = self.instance.store.signatures().borrow();
let (sig, _, _) = signatures
.lookup_shared(self.sig_index())
.expect("signature should be registered");
sig.returns.len()
}
@@ -649,8 +652,12 @@ impl Func {
// on that module as well, so unwrap the result here since otherwise
// it's a bug in wasmtime.
let trampoline = instance
.trampoline(unsafe { export.anyfunc.as_ref().type_index })
.expect("failed to retrieve trampoline from module");
.store
.signatures()
.borrow()
.lookup_shared(unsafe { export.anyfunc.as_ref().type_index })
.expect("failed to retrieve trampoline from module")
.2;
Func {
instance,

View File

@@ -20,7 +20,7 @@ fn instantiate(
let instance = unsafe {
let instance = compiled_module.instantiate(
imports,
&mut store.signatures_mut(),
&store.lookup_shared_signature(compiled_module.module()),
config.memory_creator.as_ref().map(|a| a as _),
store.interrupts(),
host,
@@ -161,12 +161,8 @@ impl Instance {
bail!("cross-`Engine` instantiation is not currently supported");
}
let host_info = Box::new({
let frame_info_registration = module.register_frame_info();
store.register_jit_code(&module);
store.register_stack_maps(&module);
frame_info_registration
});
store.register_module(&module);
let host_info = Box::new(module.register_frame_info());
let handle = with_imports(store, module.compiled_module(), imports, |imports| {
instantiate(store, module.compiled_module(), imports, host_info)
@@ -295,7 +291,8 @@ fn with_imports<R>(
// functions registered with that type, so `func` is guaranteed
// to not match.
let ty = store
.signatures_mut()
.signatures()
.borrow()
.lookup(&m.signatures[m.functions[i]].0)
.ok_or_else(|| anyhow!("function types incompatible"))?;
if !func.matches_expected(ty) {

View File

@@ -242,6 +242,7 @@ mod linker;
mod module;
mod r#ref;
mod runtime;
mod sig_registry;
mod trampoline;
mod trap;
mod types;

View File

@@ -1,4 +1,5 @@
use crate::externals::MemoryCreator;
use crate::sig_registry::SignatureRegistry;
use crate::trampoline::{MemoryCreatorProxy, StoreInstanceHandle};
use crate::Module;
use anyhow::{bail, Result};
@@ -16,13 +17,12 @@ use wasmparser::WasmFeatures;
#[cfg(feature = "cache")]
use wasmtime_cache::CacheConfig;
use wasmtime_environ::settings::{self, Configurable, SetError};
use wasmtime_environ::{ir, isa, isa::TargetIsa, wasm, Tunables};
use wasmtime_environ::{isa, isa::TargetIsa, wasm, Tunables};
use wasmtime_jit::{native, CompilationStrategy, Compiler};
use wasmtime_profiling::{JitDumpAgent, NullProfilerAgent, ProfilingAgent, VTuneAgent};
use wasmtime_runtime::{
debug_builtins, InstanceHandle, RuntimeMemoryCreator, SignalHandler, SignatureRegistry,
StackMapRegistry, VMExternRef, VMExternRefActivationsTable, VMInterrupts,
VMSharedSignatureIndex,
debug_builtins, InstanceHandle, RuntimeMemoryCreator, SignalHandler, StackMapRegistry,
VMExternRef, VMExternRefActivationsTable, VMInterrupts, VMSharedSignatureIndex,
};
// Runtime Environment
@@ -915,38 +915,21 @@ impl Store {
.map(|x| x as _)
}
pub(crate) fn lookup_signature(&self, sig_index: VMSharedSignatureIndex) -> wasm::WasmFuncType {
self.inner
.signatures
pub(crate) fn signatures(&self) -> &RefCell<SignatureRegistry> {
&self.inner.signatures
}
pub(crate) fn lookup_shared_signature<'a>(
&'a self,
module: &'a wasmtime_environ::Module,
) -> impl Fn(wasm::SignatureIndex) -> VMSharedSignatureIndex + 'a {
move |index| {
let (wasm, _native) = &module.signatures[index];
self.signatures()
.borrow()
.lookup_wasm(sig_index)
.expect("failed to lookup signature")
.lookup(wasm)
.expect("signature not previously registered")
}
pub(crate) fn lookup_wasm_and_native_signatures(
&self,
sig_index: VMSharedSignatureIndex,
) -> (wasm::WasmFuncType, ir::Signature) {
self.inner
.signatures
.borrow()
.lookup_wasm_and_native_signatures(sig_index)
.expect("failed to lookup signature")
}
pub(crate) fn register_signature(
&self,
wasm_sig: wasm::WasmFuncType,
native: ir::Signature,
) -> VMSharedSignatureIndex {
self.inner
.signatures
.borrow_mut()
.register(wasm_sig, native)
}
pub(crate) fn signatures_mut(&self) -> std::cell::RefMut<'_, SignatureRegistry> {
self.inner.signatures.borrow_mut()
}
/// Returns whether or not the given address falls within the JIT code
@@ -959,7 +942,32 @@ impl Store {
.any(|(start, end)| *start <= addr && addr < *end)
}
pub(crate) fn register_jit_code(&self, module: &Module) {
pub(crate) fn register_module(&self, module: &Module) {
// All modules register their JIT code in a store for two reasons
// currently:
//
// * First we only catch signals/traps if the program counter falls
// within the jit code of an instantiated wasm module. This ensures
// we don't catch accidental Rust/host segfaults.
//
// * Second when generating a backtrace we'll use this mapping to
// only generate wasm frames for instruction pointers that fall
// within jit code.
self.register_jit_code(module);
// We need to know about all the stack maps of all instantiated modules
// so when performing a GC we know about all wasm frames that we find
// on the stack.
self.register_stack_maps(module);
// Signatures are loaded into our `SignatureRegistry` here
// once-per-module (and once-per-signature). This allows us to create
// a `Func` wrapper for any function in the module, which requires that
// we know about the signature and trampoline for all instances.
self.register_signatures(module);
}
fn register_jit_code(&self, module: &Module) {
let mut ranges = module.compiled_module().jit_code_ranges();
// Checking of we already registered JIT code ranges by searching
// first range start.
@@ -977,7 +985,7 @@ impl Store {
}
}
pub(crate) fn register_stack_maps(&self, module: &Module) {
fn register_stack_maps(&self, module: &Module) {
let module = &module.compiled_module();
self.stack_map_registry()
.register_stack_maps(module.stack_maps().map(|(func, stack_maps)| unsafe {
@@ -990,6 +998,15 @@ impl Store {
}));
}
fn register_signatures(&self, module: &Module) {
let trampolines = module.compiled_module().trampolines();
let module = module.compiled_module().module();
let mut signatures = self.signatures().borrow_mut();
for (index, (wasm, native)) in module.signatures.iter() {
signatures.register(wasm, native, trampolines[index]);
}
}
pub(crate) unsafe fn add_instance(&self, handle: InstanceHandle) -> StoreInstanceHandle {
self.inner.instances.borrow_mut().push(handle.clone());
StoreInstanceHandle {

View File

@@ -1,11 +1,10 @@
//! Implement a registry of function signatures, for fast indirect call
//! signature checking.
use crate::vmcontext::VMSharedSignatureIndex;
use more_asserts::assert_lt;
use std::collections::{hash_map, HashMap};
use std::convert::TryFrom;
use wasmtime_environ::{ir, wasm::WasmFuncType};
use wasmtime_runtime::{VMSharedSignatureIndex, VMTrampoline};
/// WebAssembly requires that the caller and callee signatures in an indirect
/// call must match. To implement this efficiently, keep a registry of all
@@ -13,21 +12,35 @@ use wasmtime_environ::{ir, wasm::WasmFuncType};
/// index comparison.
#[derive(Debug, Default)]
pub struct SignatureRegistry {
// Map from a wasm actual function type to the index that it is assigned,
// shared amongst all wasm modules.
wasm2index: HashMap<WasmFuncType, VMSharedSignatureIndex>,
// Maps the index to the original Wasm signature.
index2wasm: HashMap<VMSharedSignatureIndex, WasmFuncType>,
// Map of all known wasm function signatures in this registry. This is
// keyed by `VMSharedSignatureIndex` above.
index_map: Vec<Entry>,
}
// Maps the index to the native signature.
index2native: HashMap<VMSharedSignatureIndex, ir::Signature>,
#[derive(Debug)]
struct Entry {
// The WebAssembly type signature, using wasm types.
wasm: WasmFuncType,
// The native signature we're using for this wasm type signature.
native: ir::Signature,
// The native trampoline used to invoke this type signature from `Func`.
// Note that the code memory for this trampoline is not owned by this
// type, but instead it's expected to be owned by the store that this
// registry lives within.
trampoline: VMTrampoline,
}
impl SignatureRegistry {
/// Register a signature and return its unique index.
pub fn register(
&mut self,
wasm: WasmFuncType,
native: ir::Signature,
wasm: &WasmFuncType,
native: &ir::Signature,
trampoline: VMTrampoline,
) -> VMSharedSignatureIndex {
let len = self.wasm2index.len();
@@ -36,15 +49,18 @@ impl SignatureRegistry {
hash_map::Entry::Vacant(entry) => {
// Keep `signature_hash` len under 2**32 -- VMSharedSignatureIndex::new(std::u32::MAX)
// is reserved for VMSharedSignatureIndex::default().
assert_lt!(
len,
std::u32::MAX as usize,
assert!(
len < std::u32::MAX as usize,
"Invariant check: signature_hash.len() < std::u32::MAX"
);
debug_assert_eq!(len, self.index_map.len());
let index = VMSharedSignatureIndex::new(u32::try_from(len).unwrap());
self.index_map.push(Entry {
wasm: wasm.clone(),
native: native.clone(),
trampoline,
});
entry.insert(index);
self.index2wasm.insert(index, wasm);
self.index2native.insert(index, native);
index
}
}
@@ -55,33 +71,16 @@ impl SignatureRegistry {
self.wasm2index.get(wasm).cloned()
}
/// Looks up a shared native signature within this registry.
/// Looks up information known about a shared signature index.
///
/// Note that for this operation to be semantically correct the `idx` must
/// have previously come from a call to `register` of this same object.
pub fn lookup_native(&self, idx: VMSharedSignatureIndex) -> Option<ir::Signature> {
self.index2native.get(&idx).cloned()
}
/// Looks up a shared Wasm signature within this registry.
///
/// Note that for this operation to be semantically correct the `idx` must
/// have previously come from a call to `register` of this same object.
pub fn lookup_wasm(&self, idx: VMSharedSignatureIndex) -> Option<WasmFuncType> {
self.index2wasm.get(&idx).cloned()
}
/// Looks up both a shared Wasm function signature and its associated native
/// `ir::Signature` within this registry.
///
/// Note that for this operation to be semantically correct the `idx` must
/// have previously come from a call to `register` of this same object.
pub fn lookup_wasm_and_native_signatures(
pub fn lookup_shared(
&self,
idx: VMSharedSignatureIndex,
) -> Option<(WasmFuncType, ir::Signature)> {
let wasm = self.lookup_wasm(idx)?;
let native = self.lookup_native(idx)?;
Some((wasm, native))
) -> Option<(&WasmFuncType, &ir::Signature, VMTrampoline)> {
self.index_map
.get(idx.bits() as usize)
.map(|e| (&e.wasm, &e.native, e.trampoline))
}
}

View File

@@ -4,43 +4,35 @@ use crate::trampoline::StoreInstanceHandle;
use crate::Store;
use anyhow::Result;
use std::any::Any;
use std::collections::HashMap;
use std::sync::Arc;
use wasmtime_environ::entity::PrimaryMap;
use wasmtime_environ::wasm::DefinedFuncIndex;
use wasmtime_environ::Module;
use wasmtime_runtime::{
Imports, InstanceHandle, StackMapRegistry, VMExternRefActivationsTable, VMFunctionBody,
VMFunctionImport, VMSharedSignatureIndex, VMTrampoline,
VMFunctionImport,
};
pub(crate) fn create_handle(
module: Module,
store: &Store,
finished_functions: PrimaryMap<DefinedFuncIndex, *mut [VMFunctionBody]>,
trampolines: HashMap<VMSharedSignatureIndex, VMTrampoline>,
state: Box<dyn Any>,
func_imports: &[VMFunctionImport],
) -> Result<StoreInstanceHandle> {
let mut imports = Imports::default();
imports.functions = func_imports;
// Compute indices into the shared signature table.
let signatures = module
.signatures
.values()
.map(|(wasm, native)| store.register_signature(wasm.clone(), native.clone()))
.collect::<PrimaryMap<_, _>>();
let module = Arc::new(module);
let module2 = module.clone();
unsafe {
let handle = InstanceHandle::new(
Arc::new(module),
module,
Arc::new(()),
&finished_functions,
trampolines,
imports,
store.memory_creator(),
signatures.into_boxed_slice(),
&store.lookup_shared_signature(&module2),
state,
store.interrupts(),
store.externref_activations_table() as *const VMExternRefActivationsTable as *mut _,

View File

@@ -6,7 +6,6 @@ use crate::{FuncType, Store, Trap};
use anyhow::Result;
use std::any::Any;
use std::cmp;
use std::collections::HashMap;
use std::mem;
use std::panic::{self, AssertUnwindSafe};
use wasmtime_environ::entity::PrimaryMap;
@@ -215,18 +214,16 @@ pub fn create_handle_with_function(
let pointer_type = isa.pointer_type();
let sig = ft.get_wasmtime_signature(pointer_type);
let wft = ft.to_wasm_func_type();
let mut fn_builder_ctx = FunctionBuilderContext::new();
let mut module = Module::new();
let mut finished_functions = PrimaryMap::new();
let mut trampolines = HashMap::new();
let mut code_memory = CodeMemory::new();
// First up we manufacture a trampoline which has the ABI specified by `ft`
// and calls into `stub_fn`...
let sig_id = module
.signatures
.push((ft.to_wasm_func_type(), sig.clone()));
let sig_id = module.signatures.push((wft.clone(), sig.clone()));
let func_id = module.functions.push(sig_id);
module
.exports
@@ -244,8 +241,10 @@ pub fn create_handle_with_function(
&sig,
mem::size_of::<u128>(),
)?;
let sig_id = store.register_signature(ft.to_wasm_func_type(), sig);
trampolines.insert(sig_id, trampoline);
store
.signatures()
.borrow_mut()
.register(&wft, &sig, trampoline);
// Next up we wrap everything up into an `InstanceHandle` by publishing our
// code memory (makes it executable) and ensuring all our various bits of
@@ -256,7 +255,6 @@ pub fn create_handle_with_function(
module,
store,
finished_functions,
trampolines,
Box::new(trampoline_state),
&[],
)
@@ -272,21 +270,21 @@ pub unsafe fn create_handle_with_raw_function(
) -> Result<StoreInstanceHandle> {
let pointer_type = store.engine().compiler().isa().pointer_type();
let sig = ft.get_wasmtime_signature(pointer_type);
let wft = ft.to_wasm_func_type();
let mut module = Module::new();
let mut finished_functions = PrimaryMap::new();
let mut trampolines = HashMap::new();
let sig_id = module
.signatures
.push((ft.to_wasm_func_type(), sig.clone()));
let sig_id = module.signatures.push((wft.clone(), sig.clone()));
let func_id = module.functions.push(sig_id);
module
.exports
.insert(String::new(), EntityIndex::Function(func_id));
finished_functions.push(func);
let sig_id = store.register_signature(ft.to_wasm_func_type(), sig);
trampolines.insert(sig_id, trampoline);
store
.signatures()
.borrow_mut()
.register(&wft, &sig, trampoline);
create_handle(module, store, finished_functions, trampolines, state, &[])
create_handle(module, store, finished_functions, state, &[])
}

View File

@@ -35,10 +35,12 @@ pub fn create_global(store: &Store, gt: &GlobalType, val: Val) -> Result<StoreIn
Val::FuncRef(Some(f)) => {
// Add a function import to the stub module, and then initialize
// our global with a `ref.func` to grab that imported function.
let signatures = store.signatures().borrow();
let shared_sig_index = f.sig_index();
let local_sig_index = module
.signatures
.push(store.lookup_wasm_and_native_signatures(shared_sig_index));
let (wasm, native, _) = signatures
.lookup_shared(shared_sig_index)
.expect("signature not registered");
let local_sig_index = module.signatures.push((wasm.clone(), native.clone()));
let func_index = module.functions.push(local_sig_index);
module.num_imported_funcs = 1;
module
@@ -66,7 +68,6 @@ pub fn create_global(store: &Store, gt: &GlobalType, val: Val) -> Result<StoreIn
module,
store,
PrimaryMap::new(),
Default::default(),
Box::new(()),
&func_imports,
)?;

View File

@@ -29,14 +29,7 @@ pub fn create_handle_with_memory(
.exports
.insert(String::new(), EntityIndex::Memory(memory_id));
create_handle(
module,
store,
PrimaryMap::new(),
Default::default(),
Box::new(()),
&[],
)
create_handle(module, store, PrimaryMap::new(), Box::new(()), &[])
}
struct LinearMemoryProxy {

View File

@@ -27,12 +27,5 @@ pub fn create_handle_with_table(store: &Store, table: &TableType) -> Result<Stor
.exports
.insert(String::new(), EntityIndex::Table(table_id));
create_handle(
module,
store,
PrimaryMap::new(),
Default::default(),
Box::new(()),
&[],
)
create_handle(module, store, PrimaryMap::new(), Box::new(()), &[])
}