From ca0c24e346df1b078220bddf840d8abf6b1d0543 Mon Sep 17 00:00:00 2001 From: Andrew Brown Date: Sat, 23 May 2020 20:55:47 -0700 Subject: [PATCH] Avoid recursion in `Interpreter::block` --- cranelift/interpreter/src/interpreter.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/cranelift/interpreter/src/interpreter.rs b/cranelift/interpreter/src/interpreter.rs index 2790a78d7a..3caf6e560e 100644 --- a/cranelift/interpreter/src/interpreter.rs +++ b/cranelift/interpreter/src/interpreter.rs @@ -117,16 +117,20 @@ impl Interpreter { self.block(&mut frame, first_block) } - /// Interpret a single [Block] in a [Function]. + /// Interpret a [Block] in a [Function]. This drives the interpretation over sequences of + /// instructions, which may continue in other blocks, until the function returns. fn block(&self, frame: &mut Frame, block: Block) -> Result { debug!("Block: {}", block); - for inst in frame.function.layout.block_insts(block) { + let layout = &frame.function.layout; + let mut maybe_inst = layout.first_inst(block); + while let Some(inst) = maybe_inst { match self.inst(frame, inst)? { - ControlFlow::Continue => continue, + ControlFlow::Continue => maybe_inst = layout.next_inst(inst), ControlFlow::ContinueAt(block, old_names) => { + debug!("Block: {}", block); let new_names = frame.function.dfg.block_params(block); frame.rename(&old_names, new_names); - return self.block(frame, block); + maybe_inst = layout.first_inst(block) } ControlFlow::Return(rs) => return Ok(ControlFlow::Return(rs)), }