wasmer_engine/
artifact.rs1use crate::{resolve_imports, InstantiationError, Resolver, RuntimeError, Tunables};
2use loupe::MemoryUsage;
3use std::any::Any;
4pub use wasmer_artifact::MetadataHeader;
5use wasmer_artifact::{ArtifactCreate, Upcastable};
6use wasmer_compiler::CpuFeature;
7use wasmer_types::entity::BoxedSlice;
8use wasmer_types::{DataInitializer, FunctionIndex, LocalFunctionIndex, SignatureIndex};
9use wasmer_vm::{
10 FuncDataRegistry, FunctionBodyPtr, InstanceAllocator, InstanceHandle, TrapHandler,
11 VMSharedSignatureIndex, VMTrampoline,
12};
13
14pub trait Artifact: Send + Sync + Upcastable + MemoryUsage + ArtifactCreate {
24 fn register_frame_info(&self);
28
29 fn finished_functions(&self) -> &BoxedSlice<LocalFunctionIndex, FunctionBodyPtr>;
32
33 fn finished_function_call_trampolines(&self) -> &BoxedSlice<SignatureIndex, VMTrampoline>;
36
37 fn finished_dynamic_function_trampolines(&self) -> &BoxedSlice<FunctionIndex, FunctionBodyPtr>;
40
41 fn signatures(&self) -> &BoxedSlice<SignatureIndex, VMSharedSignatureIndex>;
43
44 fn func_data_registry(&self) -> &FuncDataRegistry;
46
47 fn preinstantiate(&self) -> Result<(), InstantiationError> {
49 Ok(())
50 }
51 unsafe fn instantiate(
57 &self,
58 tunables: &dyn Tunables,
59 resolver: &dyn Resolver,
60 host_state: Box<dyn Any>,
61 ) -> Result<InstanceHandle, InstantiationError> {
62 let host_cpu_features = CpuFeature::for_host();
65 if !host_cpu_features.is_superset(self.cpu_features()) {
66 Err(InstantiationError::CpuFeature(format!(
67 "{:?}",
68 self.cpu_features().difference(host_cpu_features)
69 )))?;
70 }
71
72 self.preinstantiate()?;
73
74 let module = self.module();
75 let (imports, import_function_envs) = {
76 let mut imports = resolve_imports(
77 &module,
78 resolver,
79 &self.finished_dynamic_function_trampolines(),
80 self.memory_styles(),
81 self.table_styles(),
82 )
83 .map_err(InstantiationError::Link)?;
84
85 let import_function_envs = imports.get_imported_function_envs();
88
89 (imports, import_function_envs)
90 };
91
92 let (allocator, memory_definition_locations, table_definition_locations) =
96 InstanceAllocator::new(&*module);
97 let finished_memories = tunables
98 .create_memories(&module, self.memory_styles(), &memory_definition_locations)
99 .map_err(InstantiationError::Link)?
100 .into_boxed_slice();
101 let finished_tables = tunables
102 .create_tables(&module, self.table_styles(), &table_definition_locations)
103 .map_err(InstantiationError::Link)?
104 .into_boxed_slice();
105 let finished_globals = tunables
106 .create_globals(&module)
107 .map_err(InstantiationError::Link)?
108 .into_boxed_slice();
109
110 self.register_frame_info();
111
112 let handle = InstanceHandle::new(
113 allocator,
114 module,
115 self.finished_functions().clone(),
116 self.finished_function_call_trampolines().clone(),
117 finished_memories,
118 finished_tables,
119 finished_globals,
120 imports,
121 self.signatures().clone(),
122 host_state,
123 import_function_envs,
124 )
125 .map_err(|trap| InstantiationError::Start(RuntimeError::from_trap(trap)))?;
126 Ok(handle)
127 }
128 unsafe fn finish_instantiation(
134 &self,
135 trap_handler: &(dyn TrapHandler + 'static),
136 handle: &InstanceHandle,
137 ) -> Result<(), InstantiationError> {
138 let data_initializers = self
139 .data_initializers()
140 .iter()
141 .map(|init| DataInitializer {
142 location: init.location.clone(),
143 data: &*init.data,
144 })
145 .collect::<Vec<_>>();
146 handle
147 .finish_instantiation(trap_handler, &data_initializers)
148 .map_err(|trap| InstantiationError::Start(RuntimeError::from_trap(trap)))
149 }
150}
151
152impl dyn Artifact + 'static {
153 #[inline]
155 pub fn downcast_ref<T: 'static>(&'_ self) -> Option<&'_ T> {
156 self.upcast_any_ref().downcast_ref::<T>()
157 }
158
159 #[inline]
161 pub fn downcast_mut<T: 'static>(&'_ mut self) -> Option<&'_ mut T> {
162 self.upcast_any_mut().downcast_mut::<T>()
163 }
164}