evm_interpreter/machine/
mod.rs

1mod memory;
2mod stack;
3
4use alloc::{rc::Rc, vec::Vec};
5
6pub use self::{memory::Memory, stack::Stack};
7
8pub trait AsMachine {
9	type State;
10
11	fn as_machine(&self) -> &Machine<Self::State>;
12}
13
14pub trait AsMachineMut: AsMachine {
15	fn as_machine_mut(&mut self) -> &mut Machine<Self::State>;
16}
17
18/// Core execution layer for EVM.
19pub struct Machine<S> {
20	/// Program data.
21	pub(crate) data: Rc<Vec<u8>>,
22	/// Program code.
23	pub(crate) code: Rc<Vec<u8>>,
24	/// Return value. Note the difference between `retbuf`.
25	/// A `retval` holds what's returned by the current machine, with `RETURN` or `REVERT` opcode.
26	/// A `retbuf` holds the buffer of returned value by sub-calls.
27	pub retval: Vec<u8>,
28	/// Memory.
29	pub memory: Memory,
30	/// Stack.
31	pub stack: Stack,
32	/// Extra state,
33	pub state: S,
34}
35
36impl<S> Machine<S> {
37	/// Create a new machine with given code and data.
38	pub fn new(
39		code: Rc<Vec<u8>>,
40		data: Rc<Vec<u8>>,
41		stack_limit: usize,
42		memory_limit: usize,
43		state: S,
44	) -> Self {
45		Self {
46			data,
47			code,
48			retval: Vec::new(),
49			memory: Memory::new(memory_limit),
50			stack: Stack::new(stack_limit),
51			state,
52		}
53	}
54
55	/// Machine code.
56	pub fn code(&self) -> &[u8] {
57		&self.code
58	}
59
60	/// Whether the machine has empty code.
61	#[must_use]
62	pub fn is_empty(&self) -> bool {
63		self.code.is_empty()
64	}
65}