1use super::state::ModuleTranslationState;
4use crate::lib::std::string::ToString;
5use crate::lib::std::{boxed::Box, string::String, vec::Vec};
6use crate::translate_module;
7use crate::wasmparser::{Operator, ValType};
8use std::collections::HashMap;
9use std::convert::{TryFrom, TryInto};
10use std::ops::Range;
11use wasmer_types::FunctionType;
12use wasmer_types::entity::PrimaryMap;
13use wasmer_types::{
14 CustomSectionIndex, DataIndex, DataInitializer, DataInitializerLocation, ElemIndex,
15 ExportIndex, FunctionIndex, GlobalIndex, GlobalInit, GlobalType, ImportIndex, InitExpr,
16 LocalFunctionIndex, MemoryIndex, MemoryType, ModuleInfo, SignatureHash, SignatureIndex,
17 TableIndex, TableInitializer, TableType,
18};
19use wasmer_types::{TagIndex, WasmResult};
20
21#[derive(Hash)]
23pub struct FunctionBodyData<'a> {
24 pub data: &'a [u8],
26
27 pub module_offset: usize,
29}
30
31pub trait FunctionBinaryReader<'a> {
33 fn read_local_count(&mut self) -> WasmResult<u32>;
35
36 fn read_local_decl(&mut self) -> WasmResult<(u32, ValType)>;
38
39 fn read_operator(&mut self) -> WasmResult<Operator<'a>>;
41
42 fn current_position(&self) -> usize;
44
45 fn original_position(&self) -> usize;
47
48 fn bytes_remaining(&self) -> usize;
50
51 fn eof(&self) -> bool;
53
54 fn range(&self) -> Range<usize>;
56}
57
58pub struct ModuleEnvironment<'data> {
63 pub module: ModuleInfo,
65
66 pub function_body_inputs: PrimaryMap<LocalFunctionIndex, FunctionBodyData<'data>>,
68
69 pub data_initializers: Vec<DataInitializer<'data>>,
71
72 pub module_translation_state: Option<ModuleTranslationState>,
74}
75
76impl<'data> ModuleEnvironment<'data> {
77 pub fn new() -> Self {
79 Self {
80 module: ModuleInfo::new(),
81 function_body_inputs: PrimaryMap::new(),
82 data_initializers: Vec::new(),
83 module_translation_state: None,
84 }
85 }
86
87 pub fn translate(mut self, data: &'data [u8]) -> WasmResult<Self> {
90 assert!(self.module_translation_state.is_none());
91 let module_translation_state = translate_module(data, &mut self)?;
92 self.module.validate_signature_hashes()?;
93 self.module_translation_state = Some(module_translation_state);
94
95 Ok(self)
96 }
97
98 pub(crate) fn declare_export(&mut self, export: ExportIndex, name: &str) -> WasmResult<()> {
99 self.module.exports.insert(String::from(name), export);
100 Ok(())
101 }
102
103 pub(crate) fn declare_import(
104 &mut self,
105 import: ImportIndex,
106 module: &str,
107 field: &str,
108 ) -> WasmResult<()> {
109 self.module.imports.insert(
110 (
111 String::from(module),
112 String::from(field),
113 self.module.imports.len().try_into().unwrap(),
114 )
115 .into(),
116 import,
117 );
118 Ok(())
119 }
120
121 pub(crate) fn reserve_signatures(&mut self, num: u32) -> WasmResult<()> {
122 self.module
123 .signatures
124 .reserve_exact(usize::try_from(num).unwrap());
125 Ok(())
126 }
127
128 pub(crate) fn declare_signature(&mut self, sig: FunctionType) -> WasmResult<()> {
129 let signature_hash = SignatureHash::new(sig.signature_hash());
131 self.module.signatures.push(sig);
132 self.module.signature_hashes.push(signature_hash);
133 Ok(())
134 }
135
136 pub(crate) fn declare_func_import(
137 &mut self,
138 sig_index: SignatureIndex,
139 module: &str,
140 field: &str,
141 ) -> WasmResult<()> {
142 debug_assert_eq!(
143 self.module.functions.len(),
144 self.module.num_imported_functions,
145 "Imported functions must be declared first"
146 );
147 self.declare_import(
148 ImportIndex::Function(FunctionIndex::from_u32(
149 self.module.num_imported_functions as _,
150 )),
151 module,
152 field,
153 )?;
154 self.module.functions.push(sig_index);
155 self.module.num_imported_functions += 1;
156 Ok(())
157 }
158
159 pub(crate) fn declare_tag_import(
160 &mut self,
161 t: wasmparser::TagType,
162 module_name: &str,
163 field_name: &str,
164 ) -> WasmResult<()> {
165 debug_assert_eq!(
166 self.module.tags.len(),
167 self.module.num_imported_tags,
168 "Imported tags must be declared first"
169 );
170
171 let tag = SignatureIndex::from_u32(t.func_type_idx);
172 debug_assert!(
173 self.module
174 .signatures
175 .get(SignatureIndex::from_u32(t.func_type_idx))
176 .is_some(),
177 "Imported tags must mach a declared signature!"
178 );
179
180 self.declare_import(
181 ImportIndex::Tag(TagIndex::from_u32(self.module.num_imported_tags as _)),
182 module_name,
183 field_name,
184 )?;
185
186 self.module.num_imported_tags += 1;
187 self.module.tags.push(tag);
188
189 Ok(())
190 }
191
192 pub(crate) fn declare_table_import(
193 &mut self,
194 table: TableType,
195 module: &str,
196 field: &str,
197 ) -> WasmResult<()> {
198 debug_assert_eq!(
199 self.module.tables.len(),
200 self.module.num_imported_tables,
201 "Imported tables must be declared first"
202 );
203 self.declare_import(
204 ImportIndex::Table(TableIndex::from_u32(self.module.num_imported_tables as _)),
205 module,
206 field,
207 )?;
208 self.module.tables.push(table);
209 self.module.num_imported_tables += 1;
210 Ok(())
211 }
212
213 pub(crate) fn declare_memory_import(
214 &mut self,
215 memory: MemoryType,
216 module: &str,
217 field: &str,
218 ) -> WasmResult<()> {
219 debug_assert_eq!(
220 self.module.memories.len(),
221 self.module.num_imported_memories,
222 "Imported memories must be declared first"
223 );
224 self.declare_import(
225 ImportIndex::Memory(MemoryIndex::from_u32(
226 self.module.num_imported_memories as _,
227 )),
228 module,
229 field,
230 )?;
231 self.module.memories.push(memory);
232 self.module.num_imported_memories += 1;
233 Ok(())
234 }
235
236 pub(crate) fn declare_global_import(
237 &mut self,
238 global: GlobalType,
239 module: &str,
240 field: &str,
241 ) -> WasmResult<()> {
242 debug_assert_eq!(
243 self.module.globals.len(),
244 self.module.num_imported_globals,
245 "Imported globals must be declared first"
246 );
247 self.declare_import(
248 ImportIndex::Global(GlobalIndex::from_u32(self.module.num_imported_globals as _)),
249 module,
250 field,
251 )?;
252 self.module.globals.push(global);
253 self.module.num_imported_globals += 1;
254 Ok(())
255 }
256
257 pub(crate) fn finish_imports(&mut self) -> WasmResult<()> {
258 Ok(())
259 }
260
261 pub(crate) fn reserve_func_types(&mut self, num: u32) -> WasmResult<()> {
262 self.module
263 .functions
264 .reserve_exact(usize::try_from(num).unwrap());
265 self.function_body_inputs
266 .reserve_exact(usize::try_from(num).unwrap());
267 Ok(())
268 }
269
270 pub(crate) fn declare_func_type(&mut self, sig_index: SignatureIndex) -> WasmResult<()> {
271 self.module.functions.push(sig_index);
272 Ok(())
273 }
274
275 pub(crate) fn reserve_tables(&mut self, num: u32) -> WasmResult<()> {
276 self.module
277 .tables
278 .reserve_exact(usize::try_from(num).unwrap());
279 Ok(())
280 }
281
282 pub(crate) fn declare_table(&mut self, table: TableType) -> WasmResult<()> {
283 self.module.tables.push(table);
284 Ok(())
285 }
286
287 pub(crate) fn reserve_memories(&mut self, num: u32) -> WasmResult<()> {
288 self.module
289 .memories
290 .reserve_exact(usize::try_from(num).unwrap());
291 Ok(())
292 }
293
294 pub(crate) fn declare_memory(&mut self, memory: MemoryType) -> WasmResult<()> {
295 self.module.memories.push(memory);
296 Ok(())
297 }
298
299 pub(crate) fn reserve_tags(&mut self, num: u32) -> WasmResult<()> {
300 self.module
301 .tags
302 .reserve_exact(usize::try_from(num).unwrap());
303 Ok(())
304 }
305
306 pub(crate) fn declare_tag(&mut self, tag: SignatureIndex) -> WasmResult<()> {
307 self.module.tags.push(tag);
308 Ok(())
309 }
310
311 pub(crate) fn reserve_globals(&mut self, num: u32) -> WasmResult<()> {
312 self.module
313 .globals
314 .reserve_exact(usize::try_from(num).unwrap());
315 Ok(())
316 }
317
318 pub(crate) fn declare_global(
319 &mut self,
320 global: GlobalType,
321 initializer: GlobalInit,
322 ) -> WasmResult<()> {
323 self.module.globals.push(global);
324 self.module.global_initializers.push(initializer);
325 Ok(())
326 }
327
328 pub(crate) fn reserve_exports(&mut self, num: u32) -> WasmResult<()> {
329 self.module.exports.reserve(usize::try_from(num).unwrap());
330 Ok(())
331 }
332
333 pub(crate) fn declare_func_export(
334 &mut self,
335 func_index: FunctionIndex,
336 name: &str,
337 ) -> WasmResult<()> {
338 self.declare_export(ExportIndex::Function(func_index), name)
339 }
340
341 pub(crate) fn declare_table_export(
342 &mut self,
343 table_index: TableIndex,
344 name: &str,
345 ) -> WasmResult<()> {
346 self.declare_export(ExportIndex::Table(table_index), name)
347 }
348
349 pub(crate) fn declare_memory_export(
350 &mut self,
351 memory_index: MemoryIndex,
352 name: &str,
353 ) -> WasmResult<()> {
354 self.declare_export(ExportIndex::Memory(memory_index), name)
355 }
356
357 pub(crate) fn declare_tag_export(&mut self, tag_index: TagIndex, name: &str) -> WasmResult<()> {
358 self.declare_export(ExportIndex::Tag(tag_index), name)
359 }
360
361 pub(crate) fn declare_global_export(
362 &mut self,
363 global_index: GlobalIndex,
364 name: &str,
365 ) -> WasmResult<()> {
366 self.declare_export(ExportIndex::Global(global_index), name)
367 }
368
369 pub(crate) fn declare_start_function(&mut self, func_index: FunctionIndex) -> WasmResult<()> {
370 debug_assert!(self.module.start_function.is_none());
371 self.module.start_function = Some(func_index);
372 Ok(())
373 }
374
375 pub(crate) fn reserve_table_initializers(&mut self, num: u32) -> WasmResult<()> {
376 self.module
377 .table_initializers
378 .reserve_exact(usize::try_from(num).unwrap());
379 Ok(())
380 }
381
382 pub(crate) fn declare_table_initializers(
383 &mut self,
384 table_index: TableIndex,
385 offset_expr: InitExpr,
386 elements: Box<[FunctionIndex]>,
387 ) -> WasmResult<()> {
388 self.module.table_initializers.push(TableInitializer {
389 table_index,
390 offset_expr,
391 elements,
392 });
393 Ok(())
394 }
395
396 pub(crate) fn declare_passive_element(
397 &mut self,
398 elem_index: ElemIndex,
399 segments: Box<[FunctionIndex]>,
400 ) -> WasmResult<()> {
401 let old = self.module.passive_elements.insert(elem_index, segments);
402 debug_assert!(
403 old.is_none(),
404 "should never get duplicate element indices, that would be a bug in `wasmer_compiler`'s \
405 translation"
406 );
407 Ok(())
408 }
409
410 pub(crate) fn define_function_body(
411 &mut self,
412 _module_translation_state: &ModuleTranslationState,
413 body_bytes: &'data [u8],
414 body_offset: usize,
415 ) -> WasmResult<()> {
416 self.function_body_inputs.push(FunctionBodyData {
417 data: body_bytes,
418 module_offset: body_offset,
419 });
420 Ok(())
421 }
422
423 pub(crate) fn reserve_data_initializers(&mut self, num: u32) -> WasmResult<()> {
424 self.data_initializers
425 .reserve_exact(usize::try_from(num).unwrap());
426 Ok(())
427 }
428
429 pub(crate) fn declare_data_initialization(
430 &mut self,
431 memory_index: MemoryIndex,
432 offset_expr: InitExpr,
433 data: &'data [u8],
434 ) -> WasmResult<()> {
435 self.data_initializers.push(DataInitializer {
436 location: DataInitializerLocation {
437 memory_index,
438 offset_expr,
439 },
440 data,
441 });
442 Ok(())
443 }
444
445 pub(crate) fn reserve_passive_data(&mut self, count: u32) -> WasmResult<()> {
446 let count = usize::try_from(count).unwrap();
447 self.module.passive_data.reserve(count);
448 Ok(())
449 }
450
451 pub(crate) fn declare_passive_data(
452 &mut self,
453 data_index: DataIndex,
454 data: &'data [u8],
455 ) -> WasmResult<()> {
456 let old = self.module.passive_data.insert(data_index, Box::from(data));
457 debug_assert!(
458 old.is_none(),
459 "a module can't have duplicate indices, this would be a wasmer-compiler bug"
460 );
461 Ok(())
462 }
463
464 pub(crate) fn declare_module_name(&mut self, name: &'data str) -> WasmResult<()> {
465 self.module.name = Some(name.to_string());
466 Ok(())
467 }
468
469 pub(crate) fn declare_function_names(
470 &mut self,
471 functions: HashMap<FunctionIndex, String>,
472 ) -> WasmResult<()> {
473 self.module.function_names = functions;
474 Ok(())
475 }
476
477 pub(crate) fn reserve_imports(&mut self, _num: u32) -> WasmResult<()> {
480 Ok(())
481 }
482
483 pub(crate) fn finish_exports(&mut self) -> WasmResult<()> {
485 Ok(())
486 }
487
488 pub(crate) fn custom_section(&mut self, name: &'data str, data: &'data [u8]) -> WasmResult<()> {
490 let custom_section = CustomSectionIndex::from_u32(
491 self.module.custom_sections_data.len().try_into().unwrap(),
492 );
493 self.module
494 .custom_sections
495 .insert(String::from(name), custom_section);
496 self.module.custom_sections_data.push(Box::from(data));
497 Ok(())
498 }
499}