cardinal_wasm_plugins/
instance.rs

1use crate::host::make_imports;
2use crate::plugin::WasmPlugin;
3use crate::runner::HostFunctionMap;
4use crate::ExecutionContext;
5use cardinal_errors::internal::CardinalInternalError;
6use cardinal_errors::CardinalError;
7use wasmer::{FunctionEnv, Instance, Memory, Store};
8
9pub struct WasmInstance {
10    pub store: Store,
11    pub instance: Instance,
12    pub memory: Memory,
13    pub env: FunctionEnv<ExecutionContext>, // <— store the env here
14}
15
16impl WasmInstance {
17    pub fn from_plugin(
18        plugin: &WasmPlugin,
19        host_imports: Option<&HostFunctionMap>,
20    ) -> Result<Self, CardinalError> {
21        let mut store = Store::new(plugin.engine.clone());
22
23        let ctx = ExecutionContext::default();
24
25        let env = FunctionEnv::new(&mut store, ctx);
26
27        let imports = make_imports(&mut store, &env, host_imports);
28
29        // Create the instance.
30        let instance = Instance::new(&mut store, &plugin.module, &imports).map_err(|e| {
31            CardinalError::InternalError(CardinalInternalError::InvalidWasmModule(format!(
32                "Error creating WASM Instance {e}"
33            )))
34        })?;
35
36        // Stash it in the env so host imports can access it.
37        // Get the guest linear memory (usually named "memory")
38        let memory_name = plugin.memory_name.as_str(); // or default to "memory"
39        let memory = instance
40            .exports
41            .get_memory(memory_name)
42            .map_err(|e| {
43                CardinalError::InternalError(CardinalInternalError::InvalidWasmModule(format!(
44                    "missing memory export `{memory_name}`: {e}"
45                )))
46            })?
47            .clone();
48
49        env.as_mut(&mut store).replace_memory(memory.clone());
50
51        Ok(WasmInstance {
52            store,
53            instance,
54            memory,
55            env,
56        })
57    }
58}