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::entity::PrimaryMap;
11use wasmer_types::FunctionType;
12use wasmer_types::WasmResult;
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};
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<ModuleEnvironment<'data>> {
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_table_import(
156 &mut self,
157 table: TableType,
158 module: &str,
159 field: &str,
160 ) -> WasmResult<()> {
161 debug_assert_eq!(
162 self.module.tables.len(),
163 self.module.num_imported_tables,
164 "Imported tables must be declared first"
165 );
166 self.declare_import(
167 ImportIndex::Table(TableIndex::from_u32(self.module.num_imported_tables as _)),
168 module,
169 field,
170 )?;
171 self.module.tables.push(table);
172 self.module.num_imported_tables += 1;
173 Ok(())
174 }
175
176 pub(crate) fn declare_memory_import(
177 &mut self,
178 memory: MemoryType,
179 module: &str,
180 field: &str,
181 ) -> WasmResult<()> {
182 debug_assert_eq!(
183 self.module.memories.len(),
184 self.module.num_imported_memories,
185 "Imported memories must be declared first"
186 );
187 self.declare_import(
188 ImportIndex::Memory(MemoryIndex::from_u32(
189 self.module.num_imported_memories as _,
190 )),
191 module,
192 field,
193 )?;
194 self.module.memories.push(memory);
195 self.module.num_imported_memories += 1;
196 Ok(())
197 }
198
199 pub(crate) fn declare_global_import(
200 &mut self,
201 global: GlobalType,
202 module: &str,
203 field: &str,
204 ) -> WasmResult<()> {
205 debug_assert_eq!(
206 self.module.globals.len(),
207 self.module.num_imported_globals,
208 "Imported globals must be declared first"
209 );
210 self.declare_import(
211 ImportIndex::Global(GlobalIndex::from_u32(self.module.num_imported_globals as _)),
212 module,
213 field,
214 )?;
215 self.module.globals.push(global);
216 self.module.num_imported_globals += 1;
217 Ok(())
218 }
219
220 pub(crate) fn finish_imports(&mut self) -> WasmResult<()> {
221 Ok(())
222 }
223
224 pub(crate) fn reserve_func_types(&mut self, num: u32) -> WasmResult<()> {
225 self.module
226 .functions
227 .reserve_exact(usize::try_from(num).unwrap());
228 self.function_body_inputs
229 .reserve_exact(usize::try_from(num).unwrap());
230 Ok(())
231 }
232
233 pub(crate) fn declare_func_type(&mut self, sig_index: SignatureIndex) -> WasmResult<()> {
234 self.module.functions.push(sig_index);
235 Ok(())
236 }
237
238 pub(crate) fn reserve_tables(&mut self, num: u32) -> WasmResult<()> {
239 self.module
240 .tables
241 .reserve_exact(usize::try_from(num).unwrap());
242 Ok(())
243 }
244
245 pub(crate) fn declare_table(&mut self, table: TableType) -> WasmResult<()> {
246 self.module.tables.push(table);
247 Ok(())
248 }
249
250 pub(crate) fn reserve_memories(&mut self, num: u32) -> WasmResult<()> {
251 self.module
252 .memories
253 .reserve_exact(usize::try_from(num).unwrap());
254 Ok(())
255 }
256
257 pub(crate) fn declare_memory(&mut self, memory: MemoryType) -> WasmResult<()> {
258 self.module.memories.push(memory);
259 Ok(())
260 }
261
262 pub(crate) fn reserve_globals(&mut self, num: u32) -> WasmResult<()> {
263 self.module
264 .globals
265 .reserve_exact(usize::try_from(num).unwrap());
266 Ok(())
267 }
268
269 pub(crate) fn declare_global(
270 &mut self,
271 global: GlobalType,
272 initializer: GlobalInit,
273 ) -> WasmResult<()> {
274 self.module.globals.push(global);
275 self.module.global_initializers.push(initializer);
276 Ok(())
277 }
278
279 pub(crate) fn reserve_exports(&mut self, num: u32) -> WasmResult<()> {
280 self.module.exports.reserve(usize::try_from(num).unwrap());
281 Ok(())
282 }
283
284 pub(crate) fn declare_func_export(
285 &mut self,
286 func_index: FunctionIndex,
287 name: &str,
288 ) -> WasmResult<()> {
289 self.declare_export(ExportIndex::Function(func_index), name)
290 }
291
292 pub(crate) fn declare_table_export(
293 &mut self,
294 table_index: TableIndex,
295 name: &str,
296 ) -> WasmResult<()> {
297 self.declare_export(ExportIndex::Table(table_index), name)
298 }
299
300 pub(crate) fn declare_memory_export(
301 &mut self,
302 memory_index: MemoryIndex,
303 name: &str,
304 ) -> WasmResult<()> {
305 self.declare_export(ExportIndex::Memory(memory_index), name)
306 }
307
308 pub(crate) fn declare_global_export(
309 &mut self,
310 global_index: GlobalIndex,
311 name: &str,
312 ) -> WasmResult<()> {
313 self.declare_export(ExportIndex::Global(global_index), name)
314 }
315
316 pub(crate) fn declare_start_function(&mut self, func_index: FunctionIndex) -> WasmResult<()> {
317 debug_assert!(self.module.start_function.is_none());
318 self.module.start_function = Some(func_index);
319 Ok(())
320 }
321
322 pub(crate) fn reserve_table_initializers(&mut self, num: u32) -> WasmResult<()> {
323 self.module
324 .table_initializers
325 .reserve_exact(usize::try_from(num).unwrap());
326 Ok(())
327 }
328
329 pub(crate) fn declare_table_initializers(
330 &mut self,
331 table_index: TableIndex,
332 base: Option<GlobalIndex>,
333 offset: usize,
334 elements: Box<[FunctionIndex]>,
335 ) -> WasmResult<()> {
336 self.module.table_initializers.push(TableInitializer {
337 table_index,
338 base,
339 offset,
340 elements,
341 });
342 Ok(())
343 }
344
345 pub(crate) fn declare_passive_element(
346 &mut self,
347 elem_index: ElemIndex,
348 segments: Box<[FunctionIndex]>,
349 ) -> WasmResult<()> {
350 let old = self.module.passive_elements.insert(elem_index, segments);
351 debug_assert!(
352 old.is_none(),
353 "should never get duplicate element indices, that would be a bug in `wasmer_compiler`'s \
354 translation"
355 );
356 Ok(())
357 }
358
359 pub(crate) fn define_function_body(
360 &mut self,
361 _module_translation_state: &ModuleTranslationState,
362 body_bytes: &'data [u8],
363 body_offset: usize,
364 ) -> WasmResult<()> {
365 self.function_body_inputs.push(FunctionBodyData {
366 data: body_bytes,
367 module_offset: body_offset,
368 });
369 Ok(())
370 }
371
372 pub(crate) fn reserve_data_initializers(&mut self, num: u32) -> WasmResult<()> {
373 self.data_initializers
374 .reserve_exact(usize::try_from(num).unwrap());
375 Ok(())
376 }
377
378 pub(crate) fn declare_data_initialization(
379 &mut self,
380 memory_index: MemoryIndex,
381 base: Option<GlobalIndex>,
382 offset: usize,
383 data: &'data [u8],
384 ) -> WasmResult<()> {
385 self.data_initializers.push(DataInitializer {
386 location: DataInitializerLocation {
387 memory_index,
388 base,
389 offset,
390 },
391 data,
392 });
393 Ok(())
394 }
395
396 pub(crate) fn reserve_passive_data(&mut self, count: u32) -> WasmResult<()> {
397 let count = usize::try_from(count).unwrap();
398 self.module.passive_data.reserve(count);
399 Ok(())
400 }
401
402 pub(crate) fn declare_passive_data(
403 &mut self,
404 data_index: DataIndex,
405 data: &'data [u8],
406 ) -> WasmResult<()> {
407 let old = self.module.passive_data.insert(data_index, Box::from(data));
408 debug_assert!(
409 old.is_none(),
410 "a module can't have duplicate indices, this would be a wasmer-compiler bug"
411 );
412 Ok(())
413 }
414
415 pub(crate) fn declare_module_name(&mut self, name: &'data str) -> WasmResult<()> {
416 self.module.name = Some(name.to_string());
417 Ok(())
418 }
419
420 pub(crate) fn declare_function_name(
421 &mut self,
422 func_index: FunctionIndex,
423 name: &'data str,
424 ) -> WasmResult<()> {
425 self.module
426 .function_names
427 .insert(func_index, name.to_string());
428 Ok(())
429 }
430
431 pub(crate) fn reserve_imports(&mut self, _num: u32) -> WasmResult<()> {
434 Ok(())
435 }
436
437 pub(crate) fn finish_exports(&mut self) -> WasmResult<()> {
439 Ok(())
440 }
441
442 pub(crate) fn custom_section(&mut self, name: &'data str, data: &'data [u8]) -> WasmResult<()> {
444 let custom_section = CustomSectionIndex::from_u32(
445 self.module.custom_sections_data.len().try_into().unwrap(),
446 );
447 self.module
448 .custom_sections
449 .insert(String::from(name), custom_section);
450 self.module.custom_sections_data.push(Box::from(data));
451 Ok(())
452 }
453}