wasmtime/
trampoline.rs

1//! Utility module to create trampolines in/out WebAssembly module.
2
3mod func;
4mod global;
5mod memory;
6mod table;
7
8pub(crate) use memory::MemoryCreatorProxy;
9
10pub use self::func::*;
11use self::global::create_global;
12use self::memory::create_memory;
13use self::table::create_table;
14use crate::module::BareModuleInfo;
15use crate::store::{InstanceId, StoreOpaque};
16use crate::{GlobalType, MemoryType, TableType, Val};
17use anyhow::Result;
18use std::any::Any;
19use std::sync::Arc;
20use wasmtime_environ::{GlobalIndex, MemoryIndex, Module, TableIndex};
21use wasmtime_runtime::{
22    Imports, InstanceAllocationRequest, InstanceAllocator, OnDemandInstanceAllocator, SharedMemory,
23    StorePtr, VMFunctionImport, VMSharedSignatureIndex,
24};
25
26fn create_handle(
27    module: Module,
28    store: &mut StoreOpaque,
29    host_state: Box<dyn Any + Send + Sync>,
30    func_imports: &[VMFunctionImport],
31    one_signature: Option<VMSharedSignatureIndex>,
32) -> Result<InstanceId> {
33    let mut imports = Imports::default();
34    imports.functions = func_imports;
35
36    unsafe {
37        let config = store.engine().config();
38        // Use the on-demand allocator when creating handles associated with host objects
39        // The configured instance allocator should only be used when creating module instances
40        // as we don't want host objects to count towards instance limits.
41        let module = Arc::new(module);
42        let runtime_info =
43            &BareModuleInfo::maybe_imported_func(module, one_signature).into_traitobj();
44        let handle = OnDemandInstanceAllocator::new(config.mem_creator.clone(), 0).allocate(
45            InstanceAllocationRequest {
46                imports,
47                host_state,
48                store: StorePtr::new(store.traitobj()),
49                runtime_info,
50            },
51        )?;
52
53        Ok(store.add_instance(handle, true))
54    }
55}
56
57pub fn generate_global_export(
58    store: &mut StoreOpaque,
59    gt: &GlobalType,
60    val: Val,
61) -> Result<wasmtime_runtime::ExportGlobal> {
62    let instance = create_global(store, gt, val)?;
63    Ok(store
64        .instance_mut(instance)
65        .get_exported_global(GlobalIndex::from_u32(0)))
66}
67
68pub fn generate_memory_export(
69    store: &mut StoreOpaque,
70    m: &MemoryType,
71    preallocation: Option<&SharedMemory>,
72) -> Result<wasmtime_runtime::ExportMemory> {
73    let instance = create_memory(store, m, preallocation)?;
74    Ok(store
75        .instance_mut(instance)
76        .get_exported_memory(MemoryIndex::from_u32(0)))
77}
78
79pub fn generate_table_export(
80    store: &mut StoreOpaque,
81    t: &TableType,
82) -> Result<wasmtime_runtime::ExportTable> {
83    let instance = create_table(store, t)?;
84    Ok(store
85        .instance_mut(instance)
86        .get_exported_table(TableIndex::from_u32(0)))
87}