1#[cfg(not(feature = "std"))]
4pub mod prelude {
5 pub use alloc::{borrow::Cow, rc::Rc, vec, vec::Vec};
6}
7#[cfg(feature = "std")]
8pub mod prelude {
9 pub use std::{borrow::Cow, rc::Rc, vec::Vec};
10}
11
12mod error;
13mod eval;
14mod external;
15mod memory;
16mod opcode;
17mod stack;
18pub mod utils;
19mod valids;
20
21pub use error::{Capture, ExitError, ExitFatal, ExitReason, ExitRevert, ExitSucceed, Trap};
22pub use external::ExternalOperation;
23pub use memory::Memory;
24pub use opcode::Opcode;
25pub use stack::Stack;
26pub use valids::Valids;
27
28use core::ops::Range;
29use eval::{eval, Control};
30use prelude::*;
31use primitive_types::{H160, U256};
32use utils::USIZE_MAX;
33
34pub struct Machine {
36 data: Rc<Vec<u8>>,
38 code: Rc<Vec<u8>>,
40 position: Result<usize, ExitReason>,
42 return_range: Range<U256>,
44 valids: Valids,
46 memory: Memory,
48 stack: Stack,
50}
51
52pub trait InterpreterHandler {
54 fn before_eval(&mut self);
55
56 fn after_eval(&mut self);
57
58 fn before_bytecode(
61 &mut self,
62 opcode: Opcode,
63 pc: usize,
64 machine: &Machine,
65 address: &H160,
66 ) -> Result<(), ExitError>;
67
68 fn after_bytecode(&mut self, result: &Result<(), Capture<ExitReason, Trap>>, machine: &Machine);
70}
71
72impl Machine {
73 #[must_use]
75 pub const fn stack(&self) -> &Stack {
76 &self.stack
77 }
78 pub fn stack_mut(&mut self) -> &mut Stack {
80 &mut self.stack
81 }
82 #[must_use]
84 pub const fn memory(&self) -> &Memory {
85 &self.memory
86 }
87 pub fn memory_mut(&mut self) -> &mut Memory {
89 &mut self.memory
90 }
91 pub const fn position(&self) -> &Result<usize, ExitReason> {
93 &self.position
94 }
95
96 #[must_use]
98 pub fn new(
99 code: Rc<Vec<u8>>,
100 data: Rc<Vec<u8>>,
101 stack_limit: usize,
102 memory_limit: usize,
103 ) -> Self {
104 let valids = Valids::new(&code[..]);
105
106 Self {
107 data,
108 code,
109 position: Ok(0),
110 return_range: U256::zero()..U256::zero(),
111 valids,
112 memory: Memory::new(memory_limit),
113 stack: Stack::new(stack_limit),
114 }
115 }
116
117 pub fn exit(&mut self, reason: ExitReason) {
119 self.position = Err(reason);
120 }
121
122 #[must_use]
124 pub fn inspect(&self) -> Option<(Opcode, &Stack)> {
125 let Ok(position) = self.position else {
126 return None;
127 };
128 self.code.get(position).map(|v| (Opcode(*v), &self.stack))
129 }
130
131 #[must_use]
133 pub fn return_value(&self) -> Vec<u8> {
134 if self.return_range.start > USIZE_MAX {
135 vec![0; (self.return_range.end - self.return_range.start).as_usize()]
136 } else if self.return_range.end > USIZE_MAX {
137 let mut ret = self.memory.get(
138 self.return_range.start.as_usize(),
139 usize::MAX - self.return_range.start.as_usize(),
140 );
141
142 let new_len = (self.return_range.end - self.return_range.start).as_usize();
143 if ret.len() < new_len {
144 ret.resize(new_len, 0);
145 }
146 ret
147 } else {
148 self.memory.get(
149 self.return_range.start.as_usize(),
150 (self.return_range.end - self.return_range.start).as_usize(),
151 )
152 }
153 }
154
155 pub fn run(&mut self) -> Capture<ExitReason, Trap> {
157 let mut handler = SimpleInterpreterHandler::default();
158 let address = H160::default();
159 loop {
160 match self.step(&mut handler, &address) {
161 Ok(()) => (),
162 Err(res) => return res,
163 }
164 }
165 }
166
167 #[inline]
172 pub fn step<H: InterpreterHandler>(
173 &mut self,
174 handler: &mut H,
175 address: &H160,
176 ) -> Result<(), Capture<ExitReason, Trap>> {
177 let position = *self
178 .position
179 .as_ref()
180 .map_err(|reason| Capture::Exit(reason.clone()))?;
181 match eval(self, position, handler, address) {
182 Control::Exit(e) => {
183 self.position = Err(e.clone());
184 Err(Capture::Exit(e))
185 }
186 Control::Trap(opcode) => Err(Capture::Trap(opcode)),
187 Control::Continue(_) | Control::Jump(_) => Ok(()),
188 }
189 }
190}
191
192pub struct SimpleInterpreterHandler {
193 pub executed: u64,
194 pub profile: [u64; 256],
195 pub address: H160,
196}
197
198impl SimpleInterpreterHandler {
199 #[must_use]
200 pub const fn new(address: H160) -> Self {
201 Self {
202 executed: 0,
203 profile: [0; 256],
204 address,
205 }
206 }
207}
208
209impl Default for SimpleInterpreterHandler {
210 fn default() -> Self {
211 Self {
212 executed: 0,
213 profile: [0; 256],
214 address: H160::default(),
215 }
216 }
217}
218
219impl InterpreterHandler for SimpleInterpreterHandler {
220 fn before_eval(&mut self) {}
221
222 fn after_eval(&mut self) {}
223
224 #[inline]
225 fn before_bytecode(
226 &mut self,
227 opcode: Opcode,
228 _pc: usize,
229 _machine: &Machine,
230 _address: &H160,
231 ) -> Result<(), ExitError> {
232 self.executed += 1;
233 self.profile[opcode.as_usize()] += 1;
234 Ok(())
235 }
236
237 #[inline]
238 fn after_bytecode(
239 &mut self,
240 _result: &Result<(), Capture<ExitReason, Trap>>,
241 _machine: &Machine,
242 ) {
243 }
244}