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