wasmer_vm/
imports.rs

1// This file contains code from external sources.
2// Attributions: https://github.com/wasmerio/wasmer/blob/master/ATTRIBUTIONS.md
3
4use crate::instance::ImportFunctionEnv;
5use crate::vmcontext::{VMFunctionImport, VMGlobalImport, VMMemoryImport, VMTableImport};
6use crate::{VMSharedSignatureIndex, VMTrampoline};
7use wasmer_types::entity::{BoxedSlice, PrimaryMap};
8use wasmer_types::{FunctionIndex, GlobalIndex, MemoryIndex, TableIndex};
9
10/// Type of the import.
11pub enum VMImportType {
12    /// A function import.
13    Function {
14        /// Signature for the function import.
15        sig: VMSharedSignatureIndex,
16        /// Trampoline to use for functions that use [`VMFunctionKind::Static`].
17        static_trampoline: VMTrampoline,
18    },
19    /// A global.
20    Global(wasmer_types::GlobalType),
21    /// A table.
22    Table(wasmer_types::TableType),
23    /// Some memory.
24    Memory(wasmer_types::MemoryType, crate::MemoryStyle),
25}
26
27/// A module import.
28pub struct VMImport {
29    /// This is passed to the `resolve` method.
30    ///
31    /// This index is shared between different import types.
32    pub import_no: u32,
33    /// The module name.
34    pub module: String,
35    /// The field name.
36    pub field: String,
37    /// Type of the import.
38    pub ty: VMImportType,
39}
40
41/// Resolved import pointers.
42#[derive(Clone)]
43pub struct Imports {
44    /// Resolved addresses for imported functions.
45    pub functions: BoxedSlice<FunctionIndex, VMFunctionImport>,
46
47    /// Initializers for host function environments. This is split out from `functions`
48    /// because the generated code never needs to touch this and the extra wasted
49    /// space may affect Wasm runtime performance due to increased cache pressure.
50    ///
51    /// We make it optional so that we can free the data after use.
52    ///
53    /// We move this data in `get_imported_function_envs` because there's
54    /// no value to keeping it around; host functions must be initialized
55    /// exactly once so we save some memory and improve correctness by
56    /// moving this data.
57    pub host_function_env_initializers: Option<BoxedSlice<FunctionIndex, ImportFunctionEnv>>,
58
59    /// Resolved addresses for imported tables.
60    pub tables: BoxedSlice<TableIndex, VMTableImport>,
61
62    /// Resolved addresses for imported memories.
63    pub memories: BoxedSlice<MemoryIndex, VMMemoryImport>,
64
65    /// Resolved addresses for imported globals.
66    pub globals: BoxedSlice<GlobalIndex, VMGlobalImport>,
67}
68
69impl Imports {
70    /// Construct a new `Imports` instance.
71    pub fn new(
72        function_imports: PrimaryMap<FunctionIndex, VMFunctionImport>,
73        host_function_env_initializers: PrimaryMap<FunctionIndex, ImportFunctionEnv>,
74        table_imports: PrimaryMap<TableIndex, VMTableImport>,
75        memory_imports: PrimaryMap<MemoryIndex, VMMemoryImport>,
76        global_imports: PrimaryMap<GlobalIndex, VMGlobalImport>,
77    ) -> Self {
78        Self {
79            functions: function_imports.into_boxed_slice(),
80            host_function_env_initializers: Some(host_function_env_initializers.into_boxed_slice()),
81            tables: table_imports.into_boxed_slice(),
82            memories: memory_imports.into_boxed_slice(),
83            globals: global_imports.into_boxed_slice(),
84        }
85    }
86
87    /// Construct a new `Imports` instance with no imports.
88    pub fn none() -> Self {
89        Self {
90            functions: PrimaryMap::new().into_boxed_slice(),
91            host_function_env_initializers: None,
92            tables: PrimaryMap::new().into_boxed_slice(),
93            memories: PrimaryMap::new().into_boxed_slice(),
94            globals: PrimaryMap::new().into_boxed_slice(),
95        }
96    }
97
98    /// Get the `WasmerEnv::init_with_instance` function pointers and the pointers
99    /// to the envs to call it on.
100    ///
101    /// This function can only be called once, it deletes the data it returns after
102    /// returning it to ensure that it's not called more than once.
103    pub fn get_imported_function_envs(&mut self) -> BoxedSlice<FunctionIndex, ImportFunctionEnv> {
104        self.host_function_env_initializers
105            .take()
106            .unwrap_or_else(|| PrimaryMap::new().into_boxed_slice())
107    }
108}