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