linera_wasmer/sys/
instance.rs

1use crate::errors::InstantiationError;
2use crate::exports::Exports;
3use crate::module::Module;
4use wasmer_vm::{StoreHandle, VMInstance};
5
6use crate::imports::Imports;
7use crate::store::AsStoreMut;
8use crate::Extern;
9
10#[derive(Clone, PartialEq, Eq)]
11pub struct Instance {
12    _handle: StoreHandle<VMInstance>,
13}
14
15#[cfg(test)]
16mod send_test {
17    use super::*;
18
19    // Only here to statically ensure that `Instance` is `Send`.
20    // Will fail to compile otherwise.
21    #[allow(dead_code)]
22    fn instance_is_send(inst: Instance) {
23        fn is_send(t: impl Send) {
24            let _ = t;
25        }
26
27        is_send(inst);
28    }
29}
30
31impl From<wasmer_compiler::InstantiationError> for InstantiationError {
32    fn from(other: wasmer_compiler::InstantiationError) -> Self {
33        match other {
34            wasmer_compiler::InstantiationError::Link(e) => Self::Link(e.into()),
35            wasmer_compiler::InstantiationError::Start(e) => Self::Start(e.into()),
36            wasmer_compiler::InstantiationError::CpuFeature(e) => Self::CpuFeature(e),
37        }
38    }
39}
40
41impl Instance {
42    #[allow(clippy::result_large_err)]
43    pub(crate) fn new(
44        store: &mut impl AsStoreMut,
45        module: &Module,
46        imports: &Imports,
47    ) -> Result<(Self, Exports), InstantiationError> {
48        let externs = imports
49            .imports_for_module(module)
50            .map_err(InstantiationError::Link)?;
51        let mut handle = module.0.instantiate(store, &externs)?;
52        let exports = Self::get_exports(store, module, &mut handle);
53
54        let instance = Self {
55            _handle: StoreHandle::new(store.objects_mut(), handle),
56        };
57
58        Ok((instance, exports))
59    }
60
61    #[allow(clippy::result_large_err)]
62    pub(crate) fn new_by_index(
63        store: &mut impl AsStoreMut,
64        module: &Module,
65        externs: &[Extern],
66    ) -> Result<(Self, Exports), InstantiationError> {
67        let externs = externs.to_vec();
68        let mut handle = module.0.instantiate(store, &externs)?;
69        let exports = Self::get_exports(store, module, &mut handle);
70        let instance = Self {
71            _handle: StoreHandle::new(store.objects_mut(), handle),
72        };
73
74        Ok((instance, exports))
75    }
76
77    fn get_exports(
78        store: &mut impl AsStoreMut,
79        module: &Module,
80        handle: &mut VMInstance,
81    ) -> Exports {
82        module
83            .exports()
84            .map(|export| {
85                let name = export.name().to_string();
86                let export = handle.lookup(&name).expect("export");
87                let extern_ = Extern::from_vm_extern(store, export);
88                (name, extern_)
89            })
90            .collect::<Exports>()
91    }
92}