* cranelift-wasm: replace `WasmTypesMap` with `ModuleTranslationState`
The `ModuleTranslationState` contains information decoded from the Wasm module
that must be referenced during each Wasm function's translation.
This is only for data that is maintained by `cranelift-wasm` itself, as opposed
to being maintained by the embedder. Data that is maintained by the embedder is
represented with `ModuleEnvironment`.
A `ModuleTranslationState` is returned by `translate_module`, and can then be
used when translating functions from that module.
* cranelift-wasm: rename `TranslationState` to `FuncTranslationState`
To disambiguate a bit with the new `ModuleTranslationState`.
* cranelift-wasm: Reorganize the internal `state` module into submodules
One module for the `ModuleTranslationState` and another for the
`FuncTranslationState`.
* cranelift-wasm: replace `FuncTranslator` with methods on `ModuleTranslationState`
`FuncTranslator` was two methods that always took ownership of `self`, so it
didn't really make sense as an object as opposed to two different functions, or
in this case methods on the object that actually persists for a longer time.
I think this improves ergonomics nicely.
Before:
```rust
let module_translation = translate_module(...)?;
for body in func_bodies {
let mut translator = FuncTranslator::new();
translator.translate(body, ...)?;
}
```
After:
```rust
let module_translation = translate_module(...)?;
for body in func_bodies {
module_translation.translate_func(body, ...)?;
}
```
Note that this commit does not remove `FuncTranslator`. It still exists, but is
just a wrapper over the `ModuleTranslationState` methods, and it is marked
deprecated, so that downstream users get a heads up. This should make the
transition easier.
* Revert "cranelift-wasm: replace `FuncTranslator` with methods on `ModuleTranslationState`"
This reverts commit 075f9ae933bcaae39348b61287c8f78a4009340d.
97 lines
3.4 KiB
Rust
97 lines
3.4 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, WasmError, WasmResult};
|
|
use crate::sections_translator::{
|
|
parse_code_section, 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::{CustomSectionContent, ModuleReader, SectionContent};
|
|
|
|
/// 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 reader = ModuleReader::new(data)?;
|
|
let mut module_translation_state = ModuleTranslationState::new();
|
|
|
|
while !reader.eof() {
|
|
let section = reader.read()?;
|
|
match section.content()? {
|
|
SectionContent::Type(types) => {
|
|
parse_type_section(types, &mut module_translation_state, environ)?;
|
|
}
|
|
|
|
SectionContent::Import(imports) => {
|
|
parse_import_section(imports, environ)?;
|
|
}
|
|
|
|
SectionContent::Function(functions) => {
|
|
parse_function_section(functions, environ)?;
|
|
}
|
|
|
|
SectionContent::Table(tables) => {
|
|
parse_table_section(tables, environ)?;
|
|
}
|
|
|
|
SectionContent::Memory(memories) => {
|
|
parse_memory_section(memories, environ)?;
|
|
}
|
|
|
|
SectionContent::Global(globals) => {
|
|
parse_global_section(globals, environ)?;
|
|
}
|
|
|
|
SectionContent::Export(exports) => {
|
|
parse_export_section(exports, environ)?;
|
|
}
|
|
|
|
SectionContent::Start(start) => {
|
|
parse_start_section(start, environ)?;
|
|
}
|
|
|
|
SectionContent::Element(elements) => {
|
|
parse_element_section(elements, environ)?;
|
|
}
|
|
|
|
SectionContent::Code(code) => {
|
|
parse_code_section(code, &module_translation_state, environ)?;
|
|
}
|
|
|
|
SectionContent::Data(data) => {
|
|
parse_data_section(data, environ)?;
|
|
}
|
|
|
|
SectionContent::DataCount(_) => {
|
|
return Err(WasmError::InvalidWebAssembly {
|
|
message: "don't know how to handle the data count section yet",
|
|
offset: reader.current_position(),
|
|
});
|
|
}
|
|
|
|
SectionContent::Custom {
|
|
name,
|
|
binary,
|
|
content,
|
|
} => match content {
|
|
Some(CustomSectionContent::Name(names)) => {
|
|
parse_name_section(names, environ)?;
|
|
}
|
|
_ => {
|
|
let mut reader = binary.clone();
|
|
let len = reader.bytes_remaining();
|
|
let payload = reader.read_bytes(len)?;
|
|
environ.custom_section(name, payload)?;
|
|
}
|
|
},
|
|
}
|
|
}
|
|
|
|
Ok(module_translation_state)
|
|
}
|