diff --git a/lib/wasm/src/code_translator.rs b/lib/wasm/src/code_translator.rs index b057aa11c8..0ffa89806e 100644 --- a/lib/wasm/src/code_translator.rs +++ b/lib/wasm/src/code_translator.rs @@ -108,17 +108,11 @@ pub fn translate_function_body( } } - let mut state = TranslationState::new(); - // We initialize the control stack with the implicit function block + let mut state = TranslationState::new(); let end_ebb = builder.create_ebb(); - state.push_block( - end_ebb, - sig.return_types - .iter() - .map(|argty| argty.value_type) - .collect(), - ); + state.initialize(sig, end_ebb); + // Now the main loop that reads every wasm instruction and translates it loop { let parser_state = parser.read(); diff --git a/lib/wasm/src/state.rs b/lib/wasm/src/state.rs index 99e9678562..5e9d0186e5 100644 --- a/lib/wasm/src/state.rs +++ b/lib/wasm/src/state.rs @@ -3,7 +3,7 @@ //! The `TranslationState` struct defined in this module is used to keep track of the WebAssembly //! value and control stacks during the translation of a single function. -use cretonne::ir::{Ebb, Inst, Type, Value}; +use cretonne::ir::{self, Ebb, Inst, Type, Value}; /// A control stack frame can be an `if`, a `block` or a `loop`, each one having the following /// fields: @@ -116,6 +116,29 @@ impl TranslationState { } } + fn clear(&mut self) { + self.stack.clear(); + self.control_stack.clear(); + self.phantom_unreachable_stack_depth = 0; + self.real_unreachable_stack_depth = 0; + } + + /// Initialize the state for compiling a function with the given signature. + /// + /// This resets the state to containing only a single block representing the whole function. + /// The exit block is the last block in the function which will contain the return instruction. + pub fn initialize(&mut self, sig: &ir::Signature, exit_block: Ebb) { + self.clear(); + self.push_block( + exit_block, + sig.return_types + .iter() + .filter(|arg| arg.purpose == ir::ArgumentPurpose::Normal) + .map(|argty| argty.value_type) + .collect(), + ); + } + /// Push a value. pub fn push1(&mut self, val: Value) { self.stack.push(val);