cardinal_wasm_plugins/
instance.rs

1use crate::host::make_imports;
2use crate::plugin::WasmPlugin;
3use crate::runner::ExecutionType;
4use crate::{ExecutionContext, ExecutionRequest, ExecutionResponse};
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        exec_type: ExecutionType,
20    ) -> Result<Self, CardinalError> {
21        let mut store = Store::new(plugin.engine.clone());
22
23        let ctx = match exec_type {
24            ExecutionType::Inbound => ExecutionContext::Inbound(ExecutionRequest {
25                memory: None,
26                req_headers: Default::default(),
27                query: Default::default(),
28                body: None,
29            }),
30            ExecutionType::Outbound => ExecutionContext::Outbound(ExecutionResponse {
31                memory: None,
32                req_headers: Default::default(),
33                query: Default::default(),
34                resp_headers: Default::default(),
35                status: 200,
36                body: None,
37            }),
38        };
39
40        let env = FunctionEnv::new(&mut store, ctx);
41
42        let imports = make_imports(&mut store, &env, exec_type);
43
44        // Create the instance.
45        let instance = Instance::new(&mut store, &plugin.module, &imports).map_err(|e| {
46            CardinalError::InternalError(CardinalInternalError::InvalidWasmModule(format!(
47                "Error creating WASM Instance {}",
48                e
49            )))
50        })?;
51
52        // Stash it in the env so host imports can access it.
53        // Get the guest linear memory (usually named "memory")
54        let memory_name = plugin.memory_name.as_str(); // or default to "memory"
55        let memory = instance
56            .exports
57            .get_memory(memory_name)
58            .map_err(|e| {
59                CardinalError::InternalError(CardinalInternalError::InvalidWasmModule(format!(
60                    "missing memory export `{}`: {}",
61                    memory_name, e
62                )))
63            })?
64            .clone();
65
66        env.as_mut(&mut store).replace_memory(memory.clone());
67
68        Ok(WasmInstance {
69            store,
70            instance,
71            memory,
72            env,
73        })
74    }
75}