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