1 //! "Dummy" implementations of `ModuleEnvironment` and `FuncEnvironment` for testing
2 //! wasm translation. For complete implementations of `ModuleEnvironment` and
3 //! `FuncEnvironment`, see [wasmtime-environ] in [Wasmtime].
4 //!
5 //! [wasmtime-environ]: https://crates.io/crates/wasmtime-environ
6 //! [Wasmtime]: https://github.com/bytecodealliance/wasmtime
7
8 use crate::environ::{
9 FuncEnvironment, GlobalVariable, ModuleEnvironment, ReturnMode, TargetEnvironment, WasmResult,
10 };
11 use crate::func_translator::FuncTranslator;
12 use crate::state::ModuleTranslationState;
13 use crate::translation_utils::{
14 DataIndex, DefinedFuncIndex, ElemIndex, FuncIndex, Global, GlobalIndex, Memory, MemoryIndex,
15 SignatureIndex, Table, TableIndex,
16 };
17 use core::convert::TryFrom;
18 use cranelift_codegen::cursor::FuncCursor;
19 use cranelift_codegen::ir::immediates::{Offset32, Uimm64};
20 use cranelift_codegen::ir::types::*;
21 use cranelift_codegen::ir::{self, InstBuilder};
22 use cranelift_codegen::isa::TargetFrontendConfig;
23 use cranelift_entity::{EntityRef, PrimaryMap, SecondaryMap};
24 use std::boxed::Box;
25 use std::string::String;
26 use std::vec::Vec;
27
28 /// Compute a `ir::ExternalName` for a given wasm function index.
get_func_name(func_index: FuncIndex) -> ir::ExternalName29 fn get_func_name(func_index: FuncIndex) -> ir::ExternalName {
30 ir::ExternalName::user(0, func_index.as_u32())
31 }
32
33 /// A collection of names under which a given entity is exported.
34 pub struct Exportable<T> {
35 /// A wasm entity.
36 pub entity: T,
37
38 /// Names under which the entity is exported.
39 pub export_names: Vec<String>,
40 }
41
42 impl<T> Exportable<T> {
new(entity: T) -> Self43 pub fn new(entity: T) -> Self {
44 Self {
45 entity,
46 export_names: Vec::new(),
47 }
48 }
49 }
50
51 /// The main state belonging to a `DummyEnvironment`. This is split out from
52 /// `DummyEnvironment` to allow it to be borrowed separately from the
53 /// `FuncTranslator` field.
54 pub struct DummyModuleInfo {
55 /// Target description relevant to frontends producing Cranelift IR.
56 config: TargetFrontendConfig,
57
58 /// Signatures as provided by `declare_signature`.
59 pub signatures: PrimaryMap<SignatureIndex, ir::Signature>,
60
61 /// Module and field names of imported functions as provided by `declare_func_import`.
62 pub imported_funcs: Vec<(String, String)>,
63
64 /// Module and field names of imported globals as provided by `declare_global_import`.
65 pub imported_globals: Vec<(String, String)>,
66
67 /// Module and field names of imported tables as provided by `declare_table_import`.
68 pub imported_tables: Vec<(String, String)>,
69
70 /// Module and field names of imported memories as provided by `declare_memory_import`.
71 pub imported_memories: Vec<(String, String)>,
72
73 /// Functions, imported and local.
74 pub functions: PrimaryMap<FuncIndex, Exportable<SignatureIndex>>,
75
76 /// Function bodies.
77 pub function_bodies: PrimaryMap<DefinedFuncIndex, ir::Function>,
78
79 /// Tables as provided by `declare_table`.
80 pub tables: PrimaryMap<TableIndex, Exportable<Table>>,
81
82 /// Memories as provided by `declare_memory`.
83 pub memories: PrimaryMap<MemoryIndex, Exportable<Memory>>,
84
85 /// Globals as provided by `declare_global`.
86 pub globals: PrimaryMap<GlobalIndex, Exportable<Global>>,
87
88 /// The start function.
89 pub start_func: Option<FuncIndex>,
90 }
91
92 impl DummyModuleInfo {
93 /// Creates a new `DummyModuleInfo` instance.
new(config: TargetFrontendConfig) -> Self94 pub fn new(config: TargetFrontendConfig) -> Self {
95 Self {
96 config,
97 signatures: PrimaryMap::new(),
98 imported_funcs: Vec::new(),
99 imported_globals: Vec::new(),
100 imported_tables: Vec::new(),
101 imported_memories: Vec::new(),
102 functions: PrimaryMap::new(),
103 function_bodies: PrimaryMap::new(),
104 tables: PrimaryMap::new(),
105 memories: PrimaryMap::new(),
106 globals: PrimaryMap::new(),
107 start_func: None,
108 }
109 }
110 }
111
112 /// This `ModuleEnvironment` implementation is a "naïve" one, doing essentially nothing and
113 /// emitting placeholders when forced to. Don't try to execute code translated for this
114 /// environment, essentially here for translation debug purposes.
115 pub struct DummyEnvironment {
116 /// Module information.
117 pub info: DummyModuleInfo,
118
119 /// Function translation.
120 trans: FuncTranslator,
121
122 /// Vector of wasm bytecode size for each function.
123 pub func_bytecode_sizes: Vec<usize>,
124
125 /// How to return from functions.
126 return_mode: ReturnMode,
127
128 /// Instructs to collect debug data during translation.
129 debug_info: bool,
130
131 /// Name of the module from the wasm file.
132 pub module_name: Option<String>,
133
134 /// Function names.
135 function_names: SecondaryMap<FuncIndex, String>,
136 }
137
138 impl DummyEnvironment {
139 /// Creates a new `DummyEnvironment` instance.
new(config: TargetFrontendConfig, return_mode: ReturnMode, debug_info: bool) -> Self140 pub fn new(config: TargetFrontendConfig, return_mode: ReturnMode, debug_info: bool) -> Self {
141 Self {
142 info: DummyModuleInfo::new(config),
143 trans: FuncTranslator::new(),
144 func_bytecode_sizes: Vec::new(),
145 return_mode,
146 debug_info,
147 module_name: None,
148 function_names: SecondaryMap::new(),
149 }
150 }
151
152 /// Return a `DummyFuncEnvironment` for translating functions within this
153 /// `DummyEnvironment`.
func_env(&self) -> DummyFuncEnvironment154 pub fn func_env(&self) -> DummyFuncEnvironment {
155 DummyFuncEnvironment::new(&self.info, self.return_mode)
156 }
157
get_func_type(&self, func_index: FuncIndex) -> SignatureIndex158 fn get_func_type(&self, func_index: FuncIndex) -> SignatureIndex {
159 self.info.functions[func_index].entity
160 }
161
162 /// Return the number of imported functions within this `DummyEnvironment`.
get_num_func_imports(&self) -> usize163 pub fn get_num_func_imports(&self) -> usize {
164 self.info.imported_funcs.len()
165 }
166
167 /// Return the name of the function, if a name for the function with
168 /// the corresponding index exists.
get_func_name(&self, func_index: FuncIndex) -> Option<&str>169 pub fn get_func_name(&self, func_index: FuncIndex) -> Option<&str> {
170 self.function_names.get(func_index).map(String::as_ref)
171 }
172 }
173
174 /// The `FuncEnvironment` implementation for use by the `DummyEnvironment`.
175 pub struct DummyFuncEnvironment<'dummy_environment> {
176 pub mod_info: &'dummy_environment DummyModuleInfo,
177
178 return_mode: ReturnMode,
179 }
180
181 impl<'dummy_environment> DummyFuncEnvironment<'dummy_environment> {
new(mod_info: &'dummy_environment DummyModuleInfo, return_mode: ReturnMode) -> Self182 pub fn new(mod_info: &'dummy_environment DummyModuleInfo, return_mode: ReturnMode) -> Self {
183 Self {
184 mod_info,
185 return_mode,
186 }
187 }
188
189 // Create a signature for `sigidx` amended with a `vmctx` argument after the standard wasm
190 // arguments.
vmctx_sig(&self, sigidx: SignatureIndex) -> ir::Signature191 fn vmctx_sig(&self, sigidx: SignatureIndex) -> ir::Signature {
192 let mut sig = self.mod_info.signatures[sigidx].clone();
193 sig.params.push(ir::AbiParam::special(
194 self.pointer_type(),
195 ir::ArgumentPurpose::VMContext,
196 ));
197 sig
198 }
199 }
200
201 impl<'dummy_environment> TargetEnvironment for DummyFuncEnvironment<'dummy_environment> {
target_config(&self) -> TargetFrontendConfig202 fn target_config(&self) -> TargetFrontendConfig {
203 self.mod_info.config
204 }
205 }
206
207 impl<'dummy_environment> FuncEnvironment for DummyFuncEnvironment<'dummy_environment> {
return_mode(&self) -> ReturnMode208 fn return_mode(&self) -> ReturnMode {
209 self.return_mode
210 }
211
make_global( &mut self, func: &mut ir::Function, index: GlobalIndex, ) -> WasmResult<GlobalVariable>212 fn make_global(
213 &mut self,
214 func: &mut ir::Function,
215 index: GlobalIndex,
216 ) -> WasmResult<GlobalVariable> {
217 // Just create a dummy `vmctx` global.
218 let offset = i32::try_from((index.index() * 8) + 8).unwrap().into();
219 let vmctx = func.create_global_value(ir::GlobalValueData::VMContext {});
220 Ok(GlobalVariable::Memory {
221 gv: vmctx,
222 offset,
223 ty: self.mod_info.globals[index].entity.ty,
224 })
225 }
226
make_heap(&mut self, func: &mut ir::Function, _index: MemoryIndex) -> WasmResult<ir::Heap>227 fn make_heap(&mut self, func: &mut ir::Function, _index: MemoryIndex) -> WasmResult<ir::Heap> {
228 // Create a static heap whose base address is stored at `vmctx+0`.
229 let addr = func.create_global_value(ir::GlobalValueData::VMContext);
230 let gv = func.create_global_value(ir::GlobalValueData::Load {
231 base: addr,
232 offset: Offset32::new(0),
233 global_type: self.pointer_type(),
234 readonly: true,
235 });
236
237 Ok(func.create_heap(ir::HeapData {
238 base: gv,
239 min_size: 0.into(),
240 offset_guard_size: 0x8000_0000.into(),
241 style: ir::HeapStyle::Static {
242 bound: 0x1_0000_0000.into(),
243 },
244 index_type: I32,
245 }))
246 }
247
make_table(&mut self, func: &mut ir::Function, _index: TableIndex) -> WasmResult<ir::Table>248 fn make_table(&mut self, func: &mut ir::Function, _index: TableIndex) -> WasmResult<ir::Table> {
249 // Create a table whose base address is stored at `vmctx+0`.
250 let vmctx = func.create_global_value(ir::GlobalValueData::VMContext);
251 let base_gv = func.create_global_value(ir::GlobalValueData::Load {
252 base: vmctx,
253 offset: Offset32::new(0),
254 global_type: self.pointer_type(),
255 readonly: true, // when tables in wasm become "growable", revisit whether this can be readonly or not.
256 });
257 let bound_gv = func.create_global_value(ir::GlobalValueData::Load {
258 base: vmctx,
259 offset: Offset32::new(0),
260 global_type: I32,
261 readonly: true,
262 });
263
264 Ok(func.create_table(ir::TableData {
265 base_gv,
266 min_size: Uimm64::new(0),
267 bound_gv,
268 element_size: Uimm64::from(u64::from(self.pointer_bytes()) * 2),
269 index_type: I32,
270 }))
271 }
272
make_indirect_sig( &mut self, func: &mut ir::Function, index: SignatureIndex, ) -> WasmResult<ir::SigRef>273 fn make_indirect_sig(
274 &mut self,
275 func: &mut ir::Function,
276 index: SignatureIndex,
277 ) -> WasmResult<ir::SigRef> {
278 // A real implementation would probably change the calling convention and add `vmctx` and
279 // signature index arguments.
280 Ok(func.import_signature(self.vmctx_sig(index)))
281 }
282
make_direct_func( &mut self, func: &mut ir::Function, index: FuncIndex, ) -> WasmResult<ir::FuncRef>283 fn make_direct_func(
284 &mut self,
285 func: &mut ir::Function,
286 index: FuncIndex,
287 ) -> WasmResult<ir::FuncRef> {
288 let sigidx = self.mod_info.functions[index].entity;
289 // A real implementation would probably add a `vmctx` argument.
290 // And maybe attempt some signature de-duplication.
291 let signature = func.import_signature(self.vmctx_sig(sigidx));
292 let name = get_func_name(index);
293 Ok(func.import_function(ir::ExtFuncData {
294 name,
295 signature,
296 colocated: false,
297 }))
298 }
299
translate_call_indirect( &mut self, mut pos: FuncCursor, _table_index: TableIndex, _table: ir::Table, _sig_index: SignatureIndex, sig_ref: ir::SigRef, callee: ir::Value, call_args: &[ir::Value], ) -> WasmResult<ir::Inst>300 fn translate_call_indirect(
301 &mut self,
302 mut pos: FuncCursor,
303 _table_index: TableIndex,
304 _table: ir::Table,
305 _sig_index: SignatureIndex,
306 sig_ref: ir::SigRef,
307 callee: ir::Value,
308 call_args: &[ir::Value],
309 ) -> WasmResult<ir::Inst> {
310 // Pass the current function's vmctx parameter on to the callee.
311 let vmctx = pos
312 .func
313 .special_param(ir::ArgumentPurpose::VMContext)
314 .expect("Missing vmctx parameter");
315
316 // The `callee` value is an index into a table of function pointers.
317 // Apparently, that table is stored at absolute address 0 in this dummy environment.
318 // TODO: Generate bounds checking code.
319 let ptr = self.pointer_type();
320 let callee_offset = if ptr == I32 {
321 pos.ins().imul_imm(callee, 4)
322 } else {
323 let ext = pos.ins().uextend(I64, callee);
324 pos.ins().imul_imm(ext, 4)
325 };
326 let mflags = ir::MemFlags::trusted();
327 let func_ptr = pos.ins().load(ptr, mflags, callee_offset, 0);
328
329 // Build a value list for the indirect call instruction containing the callee, call_args,
330 // and the vmctx parameter.
331 let mut args = ir::ValueList::default();
332 args.push(func_ptr, &mut pos.func.dfg.value_lists);
333 args.extend(call_args.iter().cloned(), &mut pos.func.dfg.value_lists);
334 args.push(vmctx, &mut pos.func.dfg.value_lists);
335
336 Ok(pos
337 .ins()
338 .CallIndirect(ir::Opcode::CallIndirect, INVALID, sig_ref, args)
339 .0)
340 }
341
translate_call( &mut self, mut pos: FuncCursor, _callee_index: FuncIndex, callee: ir::FuncRef, call_args: &[ir::Value], ) -> WasmResult<ir::Inst>342 fn translate_call(
343 &mut self,
344 mut pos: FuncCursor,
345 _callee_index: FuncIndex,
346 callee: ir::FuncRef,
347 call_args: &[ir::Value],
348 ) -> WasmResult<ir::Inst> {
349 // Pass the current function's vmctx parameter on to the callee.
350 let vmctx = pos
351 .func
352 .special_param(ir::ArgumentPurpose::VMContext)
353 .expect("Missing vmctx parameter");
354
355 // Build a value list for the call instruction containing the call_args and the vmctx
356 // parameter.
357 let mut args = ir::ValueList::default();
358 args.extend(call_args.iter().cloned(), &mut pos.func.dfg.value_lists);
359 args.push(vmctx, &mut pos.func.dfg.value_lists);
360
361 Ok(pos.ins().Call(ir::Opcode::Call, INVALID, callee, args).0)
362 }
363
translate_memory_grow( &mut self, mut pos: FuncCursor, _index: MemoryIndex, _heap: ir::Heap, _val: ir::Value, ) -> WasmResult<ir::Value>364 fn translate_memory_grow(
365 &mut self,
366 mut pos: FuncCursor,
367 _index: MemoryIndex,
368 _heap: ir::Heap,
369 _val: ir::Value,
370 ) -> WasmResult<ir::Value> {
371 Ok(pos.ins().iconst(I32, -1))
372 }
373
translate_memory_size( &mut self, mut pos: FuncCursor, _index: MemoryIndex, _heap: ir::Heap, ) -> WasmResult<ir::Value>374 fn translate_memory_size(
375 &mut self,
376 mut pos: FuncCursor,
377 _index: MemoryIndex,
378 _heap: ir::Heap,
379 ) -> WasmResult<ir::Value> {
380 Ok(pos.ins().iconst(I32, -1))
381 }
382
translate_memory_copy( &mut self, _pos: FuncCursor, _index: MemoryIndex, _heap: ir::Heap, _dst: ir::Value, _src: ir::Value, _len: ir::Value, ) -> WasmResult<()>383 fn translate_memory_copy(
384 &mut self,
385 _pos: FuncCursor,
386 _index: MemoryIndex,
387 _heap: ir::Heap,
388 _dst: ir::Value,
389 _src: ir::Value,
390 _len: ir::Value,
391 ) -> WasmResult<()> {
392 Ok(())
393 }
394
translate_memory_fill( &mut self, _pos: FuncCursor, _index: MemoryIndex, _heap: ir::Heap, _dst: ir::Value, _val: ir::Value, _len: ir::Value, ) -> WasmResult<()>395 fn translate_memory_fill(
396 &mut self,
397 _pos: FuncCursor,
398 _index: MemoryIndex,
399 _heap: ir::Heap,
400 _dst: ir::Value,
401 _val: ir::Value,
402 _len: ir::Value,
403 ) -> WasmResult<()> {
404 Ok(())
405 }
406
translate_memory_init( &mut self, _pos: FuncCursor, _index: MemoryIndex, _heap: ir::Heap, _seg_index: u32, _dst: ir::Value, _src: ir::Value, _len: ir::Value, ) -> WasmResult<()>407 fn translate_memory_init(
408 &mut self,
409 _pos: FuncCursor,
410 _index: MemoryIndex,
411 _heap: ir::Heap,
412 _seg_index: u32,
413 _dst: ir::Value,
414 _src: ir::Value,
415 _len: ir::Value,
416 ) -> WasmResult<()> {
417 Ok(())
418 }
419
translate_data_drop(&mut self, _pos: FuncCursor, _seg_index: u32) -> WasmResult<()>420 fn translate_data_drop(&mut self, _pos: FuncCursor, _seg_index: u32) -> WasmResult<()> {
421 Ok(())
422 }
423
translate_table_size( &mut self, mut pos: FuncCursor, _index: TableIndex, _table: ir::Table, ) -> WasmResult<ir::Value>424 fn translate_table_size(
425 &mut self,
426 mut pos: FuncCursor,
427 _index: TableIndex,
428 _table: ir::Table,
429 ) -> WasmResult<ir::Value> {
430 Ok(pos.ins().iconst(I32, -1))
431 }
432
translate_table_grow( &mut self, mut pos: FuncCursor, _table_index: u32, _delta: ir::Value, _init_value: ir::Value, ) -> WasmResult<ir::Value>433 fn translate_table_grow(
434 &mut self,
435 mut pos: FuncCursor,
436 _table_index: u32,
437 _delta: ir::Value,
438 _init_value: ir::Value,
439 ) -> WasmResult<ir::Value> {
440 Ok(pos.ins().iconst(I32, -1))
441 }
442
translate_table_get( &mut self, mut pos: FuncCursor, _table_index: u32, _index: ir::Value, ) -> WasmResult<ir::Value>443 fn translate_table_get(
444 &mut self,
445 mut pos: FuncCursor,
446 _table_index: u32,
447 _index: ir::Value,
448 ) -> WasmResult<ir::Value> {
449 Ok(pos.ins().null(self.reference_type()))
450 }
451
translate_table_set( &mut self, _pos: FuncCursor, _table_index: u32, _value: ir::Value, _index: ir::Value, ) -> WasmResult<()>452 fn translate_table_set(
453 &mut self,
454 _pos: FuncCursor,
455 _table_index: u32,
456 _value: ir::Value,
457 _index: ir::Value,
458 ) -> WasmResult<()> {
459 Ok(())
460 }
461
translate_table_copy( &mut self, _pos: FuncCursor, _dst_index: TableIndex, _dst_table: ir::Table, _src_index: TableIndex, _src_table: ir::Table, _dst: ir::Value, _src: ir::Value, _len: ir::Value, ) -> WasmResult<()>462 fn translate_table_copy(
463 &mut self,
464 _pos: FuncCursor,
465 _dst_index: TableIndex,
466 _dst_table: ir::Table,
467 _src_index: TableIndex,
468 _src_table: ir::Table,
469 _dst: ir::Value,
470 _src: ir::Value,
471 _len: ir::Value,
472 ) -> WasmResult<()> {
473 Ok(())
474 }
475
translate_table_fill( &mut self, _pos: FuncCursor, _table_index: u32, _dst: ir::Value, _val: ir::Value, _len: ir::Value, ) -> WasmResult<()>476 fn translate_table_fill(
477 &mut self,
478 _pos: FuncCursor,
479 _table_index: u32,
480 _dst: ir::Value,
481 _val: ir::Value,
482 _len: ir::Value,
483 ) -> WasmResult<()> {
484 Ok(())
485 }
486
translate_table_init( &mut self, _pos: FuncCursor, _seg_index: u32, _table_index: TableIndex, _table: ir::Table, _dst: ir::Value, _src: ir::Value, _len: ir::Value, ) -> WasmResult<()>487 fn translate_table_init(
488 &mut self,
489 _pos: FuncCursor,
490 _seg_index: u32,
491 _table_index: TableIndex,
492 _table: ir::Table,
493 _dst: ir::Value,
494 _src: ir::Value,
495 _len: ir::Value,
496 ) -> WasmResult<()> {
497 Ok(())
498 }
499
translate_elem_drop(&mut self, _pos: FuncCursor, _seg_index: u32) -> WasmResult<()>500 fn translate_elem_drop(&mut self, _pos: FuncCursor, _seg_index: u32) -> WasmResult<()> {
501 Ok(())
502 }
503
translate_ref_func( &mut self, mut pos: FuncCursor, _func_index: u32, ) -> WasmResult<ir::Value>504 fn translate_ref_func(
505 &mut self,
506 mut pos: FuncCursor,
507 _func_index: u32,
508 ) -> WasmResult<ir::Value> {
509 Ok(pos.ins().null(self.reference_type()))
510 }
511
translate_custom_global_get( &mut self, mut pos: FuncCursor, _global_index: GlobalIndex, ) -> WasmResult<ir::Value>512 fn translate_custom_global_get(
513 &mut self,
514 mut pos: FuncCursor,
515 _global_index: GlobalIndex,
516 ) -> WasmResult<ir::Value> {
517 Ok(pos.ins().iconst(I32, -1))
518 }
519
translate_custom_global_set( &mut self, _pos: FuncCursor, _global_index: GlobalIndex, _val: ir::Value, ) -> WasmResult<()>520 fn translate_custom_global_set(
521 &mut self,
522 _pos: FuncCursor,
523 _global_index: GlobalIndex,
524 _val: ir::Value,
525 ) -> WasmResult<()> {
526 Ok(())
527 }
528 }
529
530 impl TargetEnvironment for DummyEnvironment {
target_config(&self) -> TargetFrontendConfig531 fn target_config(&self) -> TargetFrontendConfig {
532 self.info.config
533 }
534 }
535
536 impl<'data> ModuleEnvironment<'data> for DummyEnvironment {
declare_signature(&mut self, sig: ir::Signature) -> WasmResult<()>537 fn declare_signature(&mut self, sig: ir::Signature) -> WasmResult<()> {
538 self.info.signatures.push(sig);
539 Ok(())
540 }
541
declare_func_import( &mut self, sig_index: SignatureIndex, module: &'data str, field: &'data str, ) -> WasmResult<()>542 fn declare_func_import(
543 &mut self,
544 sig_index: SignatureIndex,
545 module: &'data str,
546 field: &'data str,
547 ) -> WasmResult<()> {
548 assert_eq!(
549 self.info.functions.len(),
550 self.info.imported_funcs.len(),
551 "Imported functions must be declared first"
552 );
553 self.info.functions.push(Exportable::new(sig_index));
554 self.info
555 .imported_funcs
556 .push((String::from(module), String::from(field)));
557 Ok(())
558 }
559
declare_func_type(&mut self, sig_index: SignatureIndex) -> WasmResult<()>560 fn declare_func_type(&mut self, sig_index: SignatureIndex) -> WasmResult<()> {
561 self.info.functions.push(Exportable::new(sig_index));
562 Ok(())
563 }
564
declare_global(&mut self, global: Global) -> WasmResult<()>565 fn declare_global(&mut self, global: Global) -> WasmResult<()> {
566 self.info.globals.push(Exportable::new(global));
567 Ok(())
568 }
569
declare_global_import( &mut self, global: Global, module: &'data str, field: &'data str, ) -> WasmResult<()>570 fn declare_global_import(
571 &mut self,
572 global: Global,
573 module: &'data str,
574 field: &'data str,
575 ) -> WasmResult<()> {
576 self.info.globals.push(Exportable::new(global));
577 self.info
578 .imported_globals
579 .push((String::from(module), String::from(field)));
580 Ok(())
581 }
582
declare_table(&mut self, table: Table) -> WasmResult<()>583 fn declare_table(&mut self, table: Table) -> WasmResult<()> {
584 self.info.tables.push(Exportable::new(table));
585 Ok(())
586 }
587
declare_table_import( &mut self, table: Table, module: &'data str, field: &'data str, ) -> WasmResult<()>588 fn declare_table_import(
589 &mut self,
590 table: Table,
591 module: &'data str,
592 field: &'data str,
593 ) -> WasmResult<()> {
594 self.info.tables.push(Exportable::new(table));
595 self.info
596 .imported_tables
597 .push((String::from(module), String::from(field)));
598 Ok(())
599 }
600
declare_table_elements( &mut self, _table_index: TableIndex, _base: Option<GlobalIndex>, _offset: usize, _elements: Box<[FuncIndex]>, ) -> WasmResult<()>601 fn declare_table_elements(
602 &mut self,
603 _table_index: TableIndex,
604 _base: Option<GlobalIndex>,
605 _offset: usize,
606 _elements: Box<[FuncIndex]>,
607 ) -> WasmResult<()> {
608 // We do nothing
609 Ok(())
610 }
611
declare_passive_element( &mut self, _elem_index: ElemIndex, _segments: Box<[FuncIndex]>, ) -> WasmResult<()>612 fn declare_passive_element(
613 &mut self,
614 _elem_index: ElemIndex,
615 _segments: Box<[FuncIndex]>,
616 ) -> WasmResult<()> {
617 Ok(())
618 }
619
declare_passive_data( &mut self, _elem_index: DataIndex, _segments: &'data [u8], ) -> WasmResult<()>620 fn declare_passive_data(
621 &mut self,
622 _elem_index: DataIndex,
623 _segments: &'data [u8],
624 ) -> WasmResult<()> {
625 Ok(())
626 }
627
declare_memory(&mut self, memory: Memory) -> WasmResult<()>628 fn declare_memory(&mut self, memory: Memory) -> WasmResult<()> {
629 self.info.memories.push(Exportable::new(memory));
630 Ok(())
631 }
632
declare_memory_import( &mut self, memory: Memory, module: &'data str, field: &'data str, ) -> WasmResult<()>633 fn declare_memory_import(
634 &mut self,
635 memory: Memory,
636 module: &'data str,
637 field: &'data str,
638 ) -> WasmResult<()> {
639 self.info.memories.push(Exportable::new(memory));
640 self.info
641 .imported_memories
642 .push((String::from(module), String::from(field)));
643 Ok(())
644 }
645
declare_data_initialization( &mut self, _memory_index: MemoryIndex, _base: Option<GlobalIndex>, _offset: usize, _data: &'data [u8], ) -> WasmResult<()>646 fn declare_data_initialization(
647 &mut self,
648 _memory_index: MemoryIndex,
649 _base: Option<GlobalIndex>,
650 _offset: usize,
651 _data: &'data [u8],
652 ) -> WasmResult<()> {
653 // We do nothing
654 Ok(())
655 }
656
declare_func_export(&mut self, func_index: FuncIndex, name: &'data str) -> WasmResult<()>657 fn declare_func_export(&mut self, func_index: FuncIndex, name: &'data str) -> WasmResult<()> {
658 self.info.functions[func_index]
659 .export_names
660 .push(String::from(name));
661 Ok(())
662 }
663
declare_table_export( &mut self, table_index: TableIndex, name: &'data str, ) -> WasmResult<()>664 fn declare_table_export(
665 &mut self,
666 table_index: TableIndex,
667 name: &'data str,
668 ) -> WasmResult<()> {
669 self.info.tables[table_index]
670 .export_names
671 .push(String::from(name));
672 Ok(())
673 }
674
declare_memory_export( &mut self, memory_index: MemoryIndex, name: &'data str, ) -> WasmResult<()>675 fn declare_memory_export(
676 &mut self,
677 memory_index: MemoryIndex,
678 name: &'data str,
679 ) -> WasmResult<()> {
680 self.info.memories[memory_index]
681 .export_names
682 .push(String::from(name));
683 Ok(())
684 }
685
declare_global_export( &mut self, global_index: GlobalIndex, name: &'data str, ) -> WasmResult<()>686 fn declare_global_export(
687 &mut self,
688 global_index: GlobalIndex,
689 name: &'data str,
690 ) -> WasmResult<()> {
691 self.info.globals[global_index]
692 .export_names
693 .push(String::from(name));
694 Ok(())
695 }
696
declare_start_func(&mut self, func_index: FuncIndex) -> WasmResult<()>697 fn declare_start_func(&mut self, func_index: FuncIndex) -> WasmResult<()> {
698 debug_assert!(self.info.start_func.is_none());
699 self.info.start_func = Some(func_index);
700 Ok(())
701 }
702
define_function_body( &mut self, module_translation_state: &ModuleTranslationState, body_bytes: &'data [u8], body_offset: usize, ) -> WasmResult<()>703 fn define_function_body(
704 &mut self,
705 module_translation_state: &ModuleTranslationState,
706 body_bytes: &'data [u8],
707 body_offset: usize,
708 ) -> WasmResult<()> {
709 let func = {
710 let mut func_environ = DummyFuncEnvironment::new(&self.info, self.return_mode);
711 let func_index =
712 FuncIndex::new(self.get_num_func_imports() + self.info.function_bodies.len());
713 let name = get_func_name(func_index);
714 let sig = func_environ.vmctx_sig(self.get_func_type(func_index));
715 let mut func = ir::Function::with_name_signature(name, sig);
716 if self.debug_info {
717 func.collect_debug_info();
718 }
719 self.trans.translate(
720 module_translation_state,
721 body_bytes,
722 body_offset,
723 &mut func,
724 &mut func_environ,
725 )?;
726 func
727 };
728 self.func_bytecode_sizes.push(body_bytes.len());
729 self.info.function_bodies.push(func);
730 Ok(())
731 }
732
declare_module_name(&mut self, name: &'data str) -> WasmResult<()>733 fn declare_module_name(&mut self, name: &'data str) -> WasmResult<()> {
734 self.module_name = Some(String::from(name));
735 Ok(())
736 }
737
declare_func_name(&mut self, func_index: FuncIndex, name: &'data str) -> WasmResult<()>738 fn declare_func_name(&mut self, func_index: FuncIndex, name: &'data str) -> WasmResult<()> {
739 self.function_names[func_index] = String::from(name);
740 Ok(())
741 }
742 }
743