Files
wasmtime/cranelift/wasm/src/module_translator.rs
Alex Crichton 1000f21338 Update wasmparser to 0.59.0 (#2013)
This commit is intended to update wasmparser to 0.59.0. This primarily
includes bytecodealliance/wasm-tools#40 which is a large update to how
parsing and validation works. The impact on Wasmtime is pretty small at
this time, but over time I'd like to refactor the internals here to lean
more heavily on that upstream wasmparser refactoring.

For now, though, the intention is to get on the train of wasmparser's
latest `main` branch to ensure we get bug fixes and such.

As part of this update a few other crates and such were updated. This is
primarily to handle the new encoding of `ref.is_null` where the type is
not part of the instruction encoding any more.
2020-07-13 16:22:41 -05:00

104 lines
3.6 KiB
Rust

//! Translation skeleton that traverses the whole WebAssembly module and call helper functions
//! to deal with each part of it.
use crate::environ::{ModuleEnvironment, WasmResult};
use crate::sections_translator::{
parse_data_section, parse_element_section, parse_export_section, parse_function_section,
parse_global_section, parse_import_section, parse_memory_section, parse_name_section,
parse_start_section, parse_table_section, parse_type_section,
};
use crate::state::ModuleTranslationState;
use cranelift_codegen::timing;
use wasmparser::{NameSectionReader, Parser, Payload};
/// Translate a sequence of bytes forming a valid Wasm binary into a list of valid Cranelift IR
/// [`Function`](cranelift_codegen::ir::Function).
pub fn translate_module<'data>(
data: &'data [u8],
environ: &mut dyn ModuleEnvironment<'data>,
) -> WasmResult<ModuleTranslationState> {
let _tt = timing::wasm_translate_module();
let mut module_translation_state = ModuleTranslationState::new();
for payload in Parser::new(0).parse_all(data) {
match payload? {
Payload::Version { .. } | Payload::End => {}
Payload::TypeSection(types) => {
parse_type_section(types, &mut module_translation_state, environ)?;
}
Payload::ImportSection(imports) => {
parse_import_section(imports, environ)?;
}
Payload::FunctionSection(functions) => {
parse_function_section(functions, environ)?;
}
Payload::TableSection(tables) => {
parse_table_section(tables, environ)?;
}
Payload::MemorySection(memories) => {
parse_memory_section(memories, environ)?;
}
Payload::GlobalSection(globals) => {
parse_global_section(globals, environ)?;
}
Payload::ExportSection(exports) => {
parse_export_section(exports, environ)?;
}
Payload::StartSection { func, .. } => {
parse_start_section(func, environ)?;
}
Payload::ElementSection(elements) => {
parse_element_section(elements, environ)?;
}
Payload::CodeSectionStart { .. } => {}
Payload::CodeSectionEntry(code) => {
let mut code = code.get_binary_reader();
let size = code.bytes_remaining();
let offset = code.original_position();
environ.define_function_body(
&module_translation_state,
code.read_bytes(size)?,
offset,
)?;
}
Payload::DataSection(data) => {
parse_data_section(data, environ)?;
}
Payload::DataCountSection { count, .. } => {
environ.reserve_passive_data(count)?;
}
Payload::ModuleSection(_)
| Payload::InstanceSection(_)
| Payload::AliasSection(_)
| Payload::ModuleCodeSectionStart { .. }
| Payload::ModuleCodeSectionEntry { .. } => {
unimplemented!("module linking not implemented yet")
}
Payload::CustomSection {
name: "name",
data,
data_offset,
} => parse_name_section(NameSectionReader::new(data, data_offset)?, environ)?,
Payload::CustomSection { name, data, .. } => environ.custom_section(name, data)?,
Payload::UnknownSection { .. } => unreachable!(),
}
}
Ok(module_translation_state)
}