revm_interpreter/interpreter/
subroutine_stack.rs1use std::vec::Vec;
2
3use crate::interpreter_types::SubRoutineStack;
4
5#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash)]
9#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
10pub struct SubRoutineReturnFrame {
11 pub idx: usize,
13 pub pc: usize,
15}
16
17impl SubRoutineReturnFrame {
18 pub fn new(idx: usize, pc: usize) -> Self {
20 Self { idx, pc }
21 }
22}
23
24#[derive(Clone, Debug, Default, PartialEq, Eq)]
26#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
27pub struct SubRoutineImpl {
28 pub return_stack: Vec<SubRoutineReturnFrame>,
29 pub current_code_idx: usize,
30}
31
32impl SubRoutineImpl {
33 pub fn new() -> Self {
35 Self {
36 return_stack: Vec::new(),
37 current_code_idx: 0,
38 }
39 }
40
41 pub fn len(&self) -> usize {
42 self.return_stack.len()
43 }
44
45 pub fn is_empty(&self) -> bool {
46 self.return_stack.is_empty()
47 }
48
49 pub fn return_stack_len(&self) -> usize {
51 self.return_stack.len()
52 }
53
54 pub fn set_current_code_idx(&mut self, idx: usize) {
56 self.current_code_idx = idx;
57 }
58}
59
60impl SubRoutineStack for SubRoutineImpl {
61 fn len(&self) -> usize {
62 self.return_stack.len()
63 }
64
65 fn routine_idx(&self) -> usize {
66 self.current_code_idx
67 }
68
69 fn push(&mut self, program_counter: usize, new_idx: usize) -> bool {
70 if self.return_stack.len() >= 1024 {
71 return false;
72 }
73 self.return_stack.push(SubRoutineReturnFrame {
74 idx: self.current_code_idx,
75 pc: program_counter,
76 });
77 self.current_code_idx = new_idx;
78 true
79 }
80
81 fn pop(&mut self) -> Option<usize> {
82 self.return_stack.pop().map(|i| {
83 self.current_code_idx = i.idx;
84 i.pc
85 })
86 }
87
88 fn set_routine_idx(&mut self, idx: usize) {
89 self.current_code_idx = idx;
90 }
91}