revm_interpreter/interpreter/
loop_control.rs

1use crate::interpreter_types::LoopControl as LoopControlTr;
2use crate::{Gas, InstructionResult, InterpreterAction};
3#[cfg(feature = "serde")]
4use serde::{Deserialize, Serialize};
5
6#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
7pub struct LoopControl {
8    /// The execution control flag.
9    ///
10    /// If this is not set to [`Continue`][InstructionResult::Continue], the interpreter will stop execution.
11    pub instruction_result: InstructionResult,
12    /// Actions that the EVM should do.
13    ///
14    /// Set inside `CALL` or `CREATE` instructions and `RETURN` or `REVERT` instructions.
15    ///
16    /// Additionally those instructions will set [`InstructionResult`] to
17    /// [`CallOrCreate`][InstructionResult::CallOrCreate]/[`Return`][InstructionResult::Return]/[`Revert`][InstructionResult::Revert]
18    /// so we know the reason.
19    pub next_action: InterpreterAction,
20    pub gas: Gas,
21}
22
23impl LoopControl {
24    pub fn new(gas_limit: u64) -> Self {
25        Self {
26            instruction_result: InstructionResult::Continue,
27            next_action: InterpreterAction::None,
28            gas: Gas::new(gas_limit),
29        }
30    }
31}
32
33impl LoopControlTr for LoopControl {
34    fn set_instruction_result(&mut self, result: InstructionResult) {
35        self.instruction_result = result;
36    }
37
38    fn set_next_action(&mut self, action: InterpreterAction, result: InstructionResult) {
39        self.next_action = action;
40        self.instruction_result = result;
41    }
42
43    fn gas(&self) -> &Gas {
44        &self.gas
45    }
46
47    fn gas_mut(&mut self) -> &mut Gas {
48        &mut self.gas
49    }
50
51    fn instruction_result(&self) -> InstructionResult {
52        self.instruction_result
53    }
54    fn take_next_action(&mut self) -> InterpreterAction {
55        core::mem::take(&mut self.next_action)
56    }
57}