Switch to wasmparser's create_binary_reader() API for reading function bodies.
A subtle difference here is that the `end` at the end of a function body now gets handled by translate_operator/translate_unreachable_operator, so we no longer have to do as much special-case cleanup at the end of the function body. This is a preperatory step for converting module_translator.rs to use the new FuncTranslator mechanism.
This commit is contained in:
@@ -27,7 +27,7 @@ use cretonne::ir::types::*;
|
|||||||
use cretonne::ir::immediates::{Ieee32, Ieee64};
|
use cretonne::ir::immediates::{Ieee32, Ieee64};
|
||||||
use cretonne::ir::condcodes::{IntCC, FloatCC};
|
use cretonne::ir::condcodes::{IntCC, FloatCC};
|
||||||
use cton_frontend::{ILBuilder, FunctionBuilder};
|
use cton_frontend::{ILBuilder, FunctionBuilder};
|
||||||
use wasmparser::{Parser, ParserState, Operator, WasmDecoder, MemoryImmediate};
|
use wasmparser::{Parser, Operator, WasmDecoder, MemoryImmediate};
|
||||||
use translation_utils::{f32_translation, f64_translation, type_to_type, translate_type, Local};
|
use translation_utils::{f32_translation, f64_translation, type_to_type, translate_type, Local};
|
||||||
use translation_utils::{TableIndex, SignatureIndex, FunctionIndex, MemoryIndex};
|
use translation_utils::{TableIndex, SignatureIndex, FunctionIndex, MemoryIndex};
|
||||||
use state::{TranslationState, ControlStackFrame};
|
use state::{TranslationState, ControlStackFrame};
|
||||||
@@ -91,37 +91,15 @@ pub fn translate_function_body(
|
|||||||
state.initialize(sig, end_ebb);
|
state.initialize(sig, end_ebb);
|
||||||
|
|
||||||
// Now the main loop that reads every wasm instruction and translates it
|
// Now the main loop that reads every wasm instruction and translates it
|
||||||
loop {
|
let mut reader = parser.create_binary_reader();
|
||||||
let parser_state = parser.read();
|
while let Ok(ref op) = reader.read_operator() {
|
||||||
match *parser_state {
|
|
||||||
ParserState::CodeOperator(ref op) => {
|
|
||||||
translate_operator(op, &mut builder, &mut state, runtime)
|
translate_operator(op, &mut builder, &mut state, runtime)
|
||||||
}
|
}
|
||||||
|
debug_assert!(state.control_stack.is_empty());
|
||||||
ParserState::EndFunctionBody => break,
|
debug_assert!(builder.is_pristine());
|
||||||
_ => return Err(String::from("wrong content in function body")),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// In WebAssembly, the final return instruction is implicit so we need to build it
|
|
||||||
// explicitely in Cretonne IL.
|
|
||||||
if !builder.is_filled() && (!builder.is_unreachable() || !builder.is_pristine()) {
|
|
||||||
let cut_index = state.stack.len() - sig.return_types.len();
|
|
||||||
builder.ins().return_(&state.stack[cut_index..]);
|
|
||||||
state.stack.truncate(cut_index);
|
|
||||||
}
|
|
||||||
// Because the function has an implicit block as body, we need to explicitely close it.
|
|
||||||
let frame = state.control_stack.pop().unwrap();
|
|
||||||
builder.switch_to_block(frame.following_code(), frame.return_values());
|
|
||||||
builder.seal_block(frame.following_code());
|
|
||||||
// If the block is reachable we also have to include a return instruction in it.
|
|
||||||
if !builder.is_unreachable() {
|
if !builder.is_unreachable() {
|
||||||
state.stack.truncate(frame.original_stack_size());
|
debug_assert!(state.stack.len() == sig.return_types.len());
|
||||||
state.stack.extend_from_slice(
|
builder.ins().return_(&state.stack);
|
||||||
builder.ebb_args(frame.following_code()),
|
|
||||||
);
|
|
||||||
let cut_index = state.stack.len() - sig.return_types.len();
|
|
||||||
builder.ins().return_(&state.stack[cut_index..]);
|
|
||||||
state.stack.truncate(cut_index);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(func)
|
Ok(func)
|
||||||
|
|||||||
Reference in New Issue
Block a user