Files
wasmtime/cranelift/wasm/src/module_translator.rs
Alex Crichton 89ccc56e46 Update the wasm-tools family of crates (#4165)
* Update the wasm-tools family of crates

This commit updates these crates as used by Wasmtime for the recently
published versions to pull in changes necessary to support the component
model. I've split this out from #4005 to make it clear what's impacted
here and #4005 can simply rebase on top of this to pick up the necessary
changes.

* More test fixes
2022-05-19 14:13:04 -05:00

130 lines
4.7 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;
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_tag_section, parse_type_section,
};
use crate::state::ModuleTranslationState;
use crate::WasmResult;
use cranelift_codegen::timing;
use std::prelude::v1::*;
use wasmparser::{NameSectionReader, Parser, Payload, Validator};
/// 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();
let mut validator = Validator::new_with_features(environ.wasm_features());
for payload in Parser::new(0).parse_all(data) {
match payload? {
Payload::Version {
num,
encoding,
range,
} => {
validator.version(num, encoding, &range)?;
}
Payload::End(offset) => {
validator.end(offset)?;
}
Payload::TypeSection(types) => {
validator.type_section(&types)?;
parse_type_section(types, &mut module_translation_state, environ)?;
}
Payload::ImportSection(imports) => {
validator.import_section(&imports)?;
parse_import_section(imports, environ)?;
}
Payload::FunctionSection(functions) => {
validator.function_section(&functions)?;
parse_function_section(functions, environ)?;
}
Payload::TableSection(tables) => {
validator.table_section(&tables)?;
parse_table_section(tables, environ)?;
}
Payload::MemorySection(memories) => {
validator.memory_section(&memories)?;
parse_memory_section(memories, environ)?;
}
Payload::TagSection(tags) => {
validator.tag_section(&tags)?;
parse_tag_section(tags, environ)?;
}
Payload::GlobalSection(globals) => {
validator.global_section(&globals)?;
parse_global_section(globals, environ)?;
}
Payload::ExportSection(exports) => {
validator.export_section(&exports)?;
parse_export_section(exports, environ)?;
}
Payload::StartSection { func, range } => {
validator.start_section(func, &range)?;
parse_start_section(func, environ)?;
}
Payload::ElementSection(elements) => {
validator.element_section(&elements)?;
parse_element_section(elements, environ)?;
}
Payload::CodeSectionStart { count, range, .. } => {
validator.code_section_start(count, &range)?;
environ.reserve_function_bodies(count, range.start as u64);
}
Payload::CodeSectionEntry(body) => {
let func_validator = validator.code_section_entry(&body)?;
environ.define_function_body(func_validator, body)?;
}
Payload::DataSection(data) => {
validator.data_section(&data)?;
parse_data_section(data, environ)?;
}
Payload::DataCountSection { count, range } => {
validator.data_count_section(count, &range)?;
// NOTE: the count here is the total segment count, not the passive segment count
environ.reserve_passive_data(count)?;
}
Payload::CustomSection(s) if s.name() == "name" => {
let result = NameSectionReader::new(s.data(), s.data_offset())
.map_err(|e| e.into())
.and_then(|s| parse_name_section(s, environ));
if let Err(e) = result {
log::warn!("failed to parse name section {:?}", e);
}
}
Payload::CustomSection(s) => environ.custom_section(s.name(), s.data())?,
other => {
validator.payload(&other)?;
panic!("unimplemented section {:?}", other);
}
}
}
Ok(module_translation_state)
}