1use crate::engine::error::LinkError;
2use std::ptr::NonNull;
3use wasmer_types::{
4 FunctionType, GlobalType, LocalGlobalIndex, LocalMemoryIndex, LocalTableIndex, MemoryIndex,
5 MemoryType, ModuleInfo, TableIndex, TableType, TagKind, entity::PrimaryMap,
6};
7use wasmer_vm::{InternalStoreHandle, MemoryError, StoreObjects, VMTag};
8use wasmer_vm::{MemoryStyle, TableStyle};
9use wasmer_vm::{VMConfig, VMGlobal, VMGlobalDefinition, VMMemory, VMTable};
10use wasmer_vm::{VMMemoryDefinition, VMTableDefinition};
11
12pub trait Tunables {
15 fn memory_style(&self, memory: &MemoryType) -> MemoryStyle;
17
18 fn table_style(&self, table: &TableType) -> TableStyle;
20
21 fn create_host_memory(
23 &self,
24 ty: &MemoryType,
25 style: &MemoryStyle,
26 ) -> Result<VMMemory, MemoryError>;
27
28 unsafe fn create_vm_memory(
33 &self,
34 ty: &MemoryType,
35 style: &MemoryStyle,
36 vm_definition_location: NonNull<VMMemoryDefinition>,
37 ) -> Result<VMMemory, MemoryError>;
38
39 fn create_host_table(&self, ty: &TableType, style: &TableStyle) -> Result<VMTable, String>;
41
42 unsafe fn create_vm_table(
47 &self,
48 ty: &TableType,
49 style: &TableStyle,
50 vm_definition_location: NonNull<VMTableDefinition>,
51 ) -> Result<VMTable, String>;
52
53 fn create_global(&self, ty: GlobalType) -> Result<VMGlobal, String> {
55 Ok(VMGlobal::new(ty))
56 }
57
58 unsafe fn create_vm_global(
63 &self,
64 ty: GlobalType,
65 vm_definition_location: NonNull<VMGlobalDefinition>,
66 ) -> Result<VMGlobal, String> {
67 unsafe { Ok(VMGlobal::new_instance(ty, vm_definition_location)) }
68 }
69
70 fn create_tag(&self, kind: TagKind, ty: FunctionType) -> Result<VMTag, String> {
72 Ok(VMTag::new(kind, ty))
73 }
74
75 #[allow(clippy::result_large_err)]
80 unsafe fn create_memories(
81 &self,
82 context: &mut StoreObjects,
83 module: &ModuleInfo,
84 memory_styles: &PrimaryMap<MemoryIndex, MemoryStyle>,
85 memory_definition_locations: &[NonNull<VMMemoryDefinition>],
86 ) -> Result<PrimaryMap<LocalMemoryIndex, InternalStoreHandle<VMMemory>>, LinkError> {
87 unsafe {
88 let num_imports = module.num_imported_memories;
89 let mut memories: PrimaryMap<LocalMemoryIndex, _> =
90 PrimaryMap::with_capacity(module.memories.len() - num_imports);
91 for ((mi, ty), mdl) in module
92 .memories
93 .iter()
94 .skip(num_imports)
95 .zip(memory_definition_locations)
96 {
97 let style = &memory_styles[mi];
98 memories.push(InternalStoreHandle::new(
99 context,
100 self.create_vm_memory(ty, style, *mdl).map_err(|e| {
101 LinkError::Resource(format!("Failed to create memory: {e}"))
102 })?,
103 ));
104 }
105 Ok(memories)
106 }
107 }
108
109 #[allow(clippy::result_large_err)]
115 unsafe fn create_tables(
116 &self,
117 context: &mut StoreObjects,
118 module: &ModuleInfo,
119 table_styles: &PrimaryMap<TableIndex, TableStyle>,
120 table_definition_locations: &[NonNull<VMTableDefinition>],
121 ) -> Result<PrimaryMap<LocalTableIndex, InternalStoreHandle<VMTable>>, LinkError> {
122 unsafe {
123 let num_imports = module.num_imported_tables;
124 let mut tables: PrimaryMap<LocalTableIndex, _> =
125 PrimaryMap::with_capacity(module.tables.len() - num_imports);
126 for ((ti, ty), tdl) in module
127 .tables
128 .iter()
129 .skip(num_imports)
130 .zip(table_definition_locations)
131 {
132 let style = &table_styles[ti];
133 tables.push(InternalStoreHandle::new(
134 context,
135 self.create_vm_table(ty, style, *tdl)
136 .map_err(LinkError::Resource)?,
137 ));
138 }
139 Ok(tables)
140 }
141 }
142
143 #[allow(clippy::result_large_err)]
146 fn create_globals(
147 &self,
148 context: &mut StoreObjects,
149 module: &ModuleInfo,
150 vm_definition_locations: &[NonNull<VMGlobalDefinition>],
151 ) -> Result<PrimaryMap<LocalGlobalIndex, InternalStoreHandle<VMGlobal>>, LinkError> {
152 let num_imports = module.num_imported_globals;
153 let mut vmctx_globals = PrimaryMap::with_capacity(module.globals.len() - num_imports);
154
155 for (i, &global_type) in module.globals.values().skip(num_imports).enumerate() {
156 let location = vm_definition_locations
157 .get(i)
158 .ok_or_else(|| LinkError::Resource("global definition location missing".into()))?;
159 vmctx_globals.push(InternalStoreHandle::new(context, unsafe {
160 self.create_vm_global(global_type, *location)
161 .map_err(LinkError::Resource)?
162 }));
163 }
164
165 Ok(vmctx_globals)
166 }
167
168 fn vmconfig(&self) -> &VMConfig {
175 &VMConfig {
176 wasm_stack_size: None,
177 }
178 }
179}
180
181#[derive(Clone, Default)]
190pub struct BaseTunables {}
191
192impl BaseTunables {
193 pub fn new() -> Self {
195 Self {}
196 }
197}
198
199impl Tunables for BaseTunables {
200 fn memory_style(&self, _memory: &MemoryType) -> MemoryStyle {
202 MemoryStyle::Static
203 }
204
205 fn table_style(&self, _table: &TableType) -> TableStyle {
207 TableStyle::CallerChecksSignature
208 }
209
210 fn create_host_memory(
212 &self,
213 ty: &MemoryType,
214 style: &MemoryStyle,
215 ) -> Result<VMMemory, MemoryError> {
216 VMMemory::new(ty, style)
217 }
218
219 unsafe fn create_vm_memory(
225 &self,
226 ty: &MemoryType,
227 style: &MemoryStyle,
228 vm_definition_location: NonNull<VMMemoryDefinition>,
229 ) -> Result<VMMemory, MemoryError> {
230 unsafe { VMMemory::from_definition(ty, style, vm_definition_location) }
231 }
232
233 fn create_host_table(&self, ty: &TableType, style: &TableStyle) -> Result<VMTable, String> {
235 VMTable::new(ty, style)
236 }
237
238 unsafe fn create_vm_table(
244 &self,
245 ty: &TableType,
246 style: &TableStyle,
247 vm_definition_location: NonNull<VMTableDefinition>,
248 ) -> Result<VMTable, String> {
249 unsafe { VMTable::from_definition(ty, style, vm_definition_location) }
250 }
251}
252
253impl Tunables for Box<dyn Tunables + Send + Sync> {
254 fn memory_style(&self, memory: &MemoryType) -> MemoryStyle {
255 self.as_ref().memory_style(memory)
256 }
257
258 fn table_style(&self, table: &TableType) -> TableStyle {
259 self.as_ref().table_style(table)
260 }
261
262 fn create_host_memory(
263 &self,
264 ty: &MemoryType,
265 style: &MemoryStyle,
266 ) -> Result<VMMemory, MemoryError> {
267 self.as_ref().create_host_memory(ty, style)
268 }
269
270 unsafe fn create_vm_memory(
271 &self,
272 ty: &MemoryType,
273 style: &MemoryStyle,
274 vm_definition_location: NonNull<VMMemoryDefinition>,
275 ) -> Result<VMMemory, MemoryError> {
276 unsafe {
277 self.as_ref()
278 .create_vm_memory(ty, style, vm_definition_location)
279 }
280 }
281
282 fn create_host_table(&self, ty: &TableType, style: &TableStyle) -> Result<VMTable, String> {
283 self.as_ref().create_host_table(ty, style)
284 }
285
286 unsafe fn create_vm_table(
287 &self,
288 ty: &TableType,
289 style: &TableStyle,
290 vm_definition_location: NonNull<VMTableDefinition>,
291 ) -> Result<VMTable, String> {
292 unsafe {
293 self.as_ref()
294 .create_vm_table(ty, style, vm_definition_location)
295 }
296 }
297}
298
299impl Tunables for std::sync::Arc<dyn Tunables + Send + Sync> {
300 fn memory_style(&self, memory: &MemoryType) -> MemoryStyle {
301 self.as_ref().memory_style(memory)
302 }
303
304 fn table_style(&self, table: &TableType) -> TableStyle {
305 self.as_ref().table_style(table)
306 }
307
308 fn create_host_memory(
309 &self,
310 ty: &MemoryType,
311 style: &MemoryStyle,
312 ) -> Result<VMMemory, MemoryError> {
313 self.as_ref().create_host_memory(ty, style)
314 }
315
316 unsafe fn create_vm_memory(
317 &self,
318 ty: &MemoryType,
319 style: &MemoryStyle,
320 vm_definition_location: NonNull<VMMemoryDefinition>,
321 ) -> Result<VMMemory, MemoryError> {
322 unsafe {
323 self.as_ref()
324 .create_vm_memory(ty, style, vm_definition_location)
325 }
326 }
327
328 fn create_host_table(&self, ty: &TableType, style: &TableStyle) -> Result<VMTable, String> {
329 self.as_ref().create_host_table(ty, style)
330 }
331
332 unsafe fn create_vm_table(
333 &self,
334 ty: &TableType,
335 style: &TableStyle,
336 vm_definition_location: NonNull<VMTableDefinition>,
337 ) -> Result<VMTable, String> {
338 unsafe {
339 self.as_ref()
340 .create_vm_table(ty, style, vm_definition_location)
341 }
342 }
343}