Interpret a [Block] in a [Function]. This drives the interpretation over sequences of instructions, which may continue in other blocks, until the function returns.
(&mut self, block: Block)
| 91 | /// Interpret a [Block] in a [Function]. This drives the interpretation over sequences of |
| 92 | /// instructions, which may continue in other blocks, until the function returns. |
| 93 | fn block(&mut self, block: Block) -> Result<ControlFlow<'a>, InterpreterError> { |
| 94 | trace!("Block: {block}"); |
| 95 | let function = self.state.current_frame_mut().function(); |
| 96 | let layout = &function.layout; |
| 97 | let mut maybe_inst = layout.first_inst(block); |
| 98 | while let Some(inst) = maybe_inst { |
| 99 | if self.consume_fuel() == FuelResult::Stop { |
| 100 | return Err(InterpreterError::FuelExhausted); |
| 101 | } |
| 102 | |
| 103 | let inst_context = DfgInstructionContext::new(inst, &function.dfg); |
| 104 | match step(&mut self.state, inst_context)? { |
| 105 | ControlFlow::Assign(values) => { |
| 106 | self.state |
| 107 | .current_frame_mut() |
| 108 | .set_all(function.dfg.inst_results(inst), values.to_vec()); |
| 109 | maybe_inst = layout.next_inst(inst) |
| 110 | } |
| 111 | ControlFlow::Continue => maybe_inst = layout.next_inst(inst), |
| 112 | ControlFlow::ContinueAt(block, block_arguments) => { |
| 113 | trace!("Block: {block}"); |
| 114 | self.state |
| 115 | .current_frame_mut() |
| 116 | .set_all(function.dfg.block_params(block), block_arguments.to_vec()); |
| 117 | maybe_inst = layout.first_inst(block) |
| 118 | } |
| 119 | ControlFlow::Call(called_function, arguments) => { |
| 120 | match self.call(called_function, &arguments)? { |
| 121 | ControlFlow::Return(rets) => { |
| 122 | self.state |
| 123 | .current_frame_mut() |
| 124 | .set_all(function.dfg.inst_results(inst), rets.to_vec()); |
| 125 | maybe_inst = layout.next_inst(inst) |
| 126 | } |
| 127 | ControlFlow::Trap(trap) => return Ok(ControlFlow::Trap(trap)), |
| 128 | cf => { |
| 129 | panic!("invalid control flow after call: {cf:?}") |
| 130 | } |
| 131 | } |
| 132 | } |
| 133 | ControlFlow::ReturnCall(callee, args) => { |
| 134 | self.state.pop_frame(); |
| 135 | |
| 136 | return match self.call(callee, &args)? { |
| 137 | ControlFlow::Return(rets) => Ok(ControlFlow::Return(rets)), |
| 138 | ControlFlow::Trap(trap) => Ok(ControlFlow::Trap(trap)), |
| 139 | cf => { |
| 140 | panic!("invalid control flow after return_call: {cf:?}") |
| 141 | } |
| 142 | }; |
| 143 | } |
| 144 | ControlFlow::Return(returned_values) => { |
| 145 | self.state.pop_frame(); |
| 146 | return Ok(ControlFlow::Return(returned_values)); |
| 147 | } |
| 148 | ControlFlow::Trap(trap) => return Ok(ControlFlow::Trap(trap)), |
| 149 | } |
| 150 | } |
no test coverage detected