1 //! Translation skeleton that traverses the whole WebAssembly module and call helper functions
2 //! to deal with each part of it.
3 use crate::environ::{ModuleEnvironment, WasmError, WasmResult};
4 use crate::sections_translator::{
5     parse_code_section, parse_data_section, parse_element_section, parse_export_section,
6     parse_function_section, parse_global_section, parse_import_section, parse_memory_section,
7     parse_name_section, parse_start_section, parse_table_section, parse_type_section,
8 };
9 use cranelift_codegen::timing;
10 use wasmparser::{CustomSectionContent, ModuleReader, SectionContent};
11 
12 /// Translate a sequence of bytes forming a valid Wasm binary into a list of valid Cranelift IR
13 /// [`Function`](cranelift_codegen::ir::Function).
translate_module<'data>( data: &'data [u8], environ: &mut dyn ModuleEnvironment<'data>, ) -> WasmResult<()>14 pub fn translate_module<'data>(
15     data: &'data [u8],
16     environ: &mut dyn ModuleEnvironment<'data>,
17 ) -> WasmResult<()> {
18     let _tt = timing::wasm_translate_module();
19     let mut reader = ModuleReader::new(data)?;
20 
21     while !reader.eof() {
22         let section = reader.read()?;
23         match section.content()? {
24             SectionContent::Type(types) => {
25                 parse_type_section(types, environ)?;
26             }
27 
28             SectionContent::Import(imports) => {
29                 parse_import_section(imports, environ)?;
30             }
31 
32             SectionContent::Function(functions) => {
33                 parse_function_section(functions, environ)?;
34             }
35 
36             SectionContent::Table(tables) => {
37                 parse_table_section(tables, environ)?;
38             }
39 
40             SectionContent::Memory(memories) => {
41                 parse_memory_section(memories, environ)?;
42             }
43 
44             SectionContent::Global(globals) => {
45                 parse_global_section(globals, environ)?;
46             }
47 
48             SectionContent::Export(exports) => {
49                 parse_export_section(exports, environ)?;
50             }
51 
52             SectionContent::Start(start) => {
53                 parse_start_section(start, environ)?;
54             }
55 
56             SectionContent::Element(elements) => {
57                 parse_element_section(elements, environ)?;
58             }
59 
60             SectionContent::Code(code) => {
61                 parse_code_section(code, environ)?;
62             }
63 
64             SectionContent::Data(data) => {
65                 parse_data_section(data, environ)?;
66             }
67 
68             SectionContent::DataCount(_) => {
69                 return Err(WasmError::InvalidWebAssembly {
70                     message: "don't know how to handle the data count section yet",
71                     offset: reader.current_position(),
72                 });
73             }
74 
75             SectionContent::Custom {
76                 name,
77                 binary,
78                 content,
79             } => match content {
80                 Some(CustomSectionContent::Name(names)) => {
81                     parse_name_section(names, environ)?;
82                 }
83                 _ => {
84                     let mut reader = binary.clone();
85                     let len = reader.bytes_remaining();
86                     let payload = reader.read_bytes(len)?;
87                     environ.custom_section(name, payload)?;
88                 }
89             },
90         }
91     }
92 
93     Ok(())
94 }
95