wasmer/backend/sys/entities/
instance.rs1use crate::{
4 Extern, error::InstantiationError, exports::Exports, imports::Imports, module::Module,
5 store::AsStoreMut,
6};
7use wasmer_vm::{StoreHandle, VMInstance};
8
9use super::store::Store;
10
11#[derive(Clone, PartialEq, Eq)]
12pub struct Instance {
14 _handle: StoreHandle<VMInstance>,
15}
16
17impl From<wasmer_compiler::InstantiationError> for InstantiationError {
18 fn from(other: wasmer_compiler::InstantiationError) -> Self {
19 match other {
20 wasmer_compiler::InstantiationError::Link(e) => Self::Link(e.into()),
21 wasmer_compiler::InstantiationError::Start(e) => Self::Start(e.into()),
22 wasmer_compiler::InstantiationError::CpuFeature(e) => Self::CpuFeature(e),
23 }
24 }
25}
26
27impl Instance {
28 #[allow(clippy::result_large_err)]
29 pub(crate) fn new(
30 store: &mut impl AsStoreMut,
31 module: &Module,
32 imports: &Imports,
33 ) -> Result<(Self, Exports), InstantiationError> {
34 let externs = imports
35 .imports_for_module(module)
36 .map_err(InstantiationError::Link)?;
37 let mut handle = module.as_sys().instantiate(store, &externs)?;
38 let exports = Self::get_exports(store, module, handle.as_sys_mut());
39
40 let instance = Self {
41 _handle: StoreHandle::new(store.objects_mut().as_sys_mut(), handle.into_sys()),
42 };
43
44 Ok((instance, exports))
45 }
46
47 #[allow(clippy::result_large_err)]
48 pub(crate) fn new_by_index(
49 store: &mut impl AsStoreMut,
50 module: &Module,
51 externs: &[Extern],
52 ) -> Result<(Self, Exports), InstantiationError> {
53 let externs = externs.to_vec();
54 let mut handle = module.as_sys().instantiate(store, &externs)?;
55 let exports = Self::get_exports(store, module, handle.as_sys_mut());
56 let instance = Self {
57 _handle: StoreHandle::new(
58 store.as_store_mut().objects_mut().as_sys_mut(),
59 handle.into_sys(),
60 ),
61 };
62
63 Ok((instance, exports))
64 }
65
66 fn get_exports(
67 store: &mut impl AsStoreMut,
68 module: &Module,
69 handle: &mut VMInstance,
70 ) -> Exports {
71 module
72 .exports()
73 .map(|export| {
74 let name = export.name().to_string();
75 let export = handle.lookup(&name).expect("export");
76 let extern_ = Extern::from_vm_extern(store, crate::vm::VMExtern::Sys(export));
77 (name, extern_)
78 })
79 .collect::<Exports>()
80 }
81}
82
83impl crate::BackendInstance {
84 pub(crate) fn into_sys(self) -> crate::backend::sys::instance::Instance {
86 match self {
87 Self::Sys(s) => s,
88 _ => panic!("Not a `sys` instance"),
89 }
90 }
91}
92
93#[cfg(test)]
94mod send_test {
95 use super::*;
96
97 #[allow(dead_code)]
100 fn instance_is_send(inst: Instance) {
101 fn is_send(t: impl Send) {
102 let _ = t;
103 }
104
105 is_send(inst);
106 }
107}