-
Notifications
You must be signed in to change notification settings - Fork 830
Open
Description
src/interpreter.rs
/// EVM bytecode interpreter.
#[derive(Debug)]
pub struct Interpreter {
/// The current instruction pointer.
pub instruction_pointer: *const u8,
/// The gas state.
pub gas: Gas,
/// Contract information and invoking data
pub contract: Contract,
/// The execution control flag. If this is not set to `Continue`, the interpreter will stop
/// execution.
pub instruction_result: InstructionResult,
/// Currently run Bytecode that instruction result will point to.
/// Bytecode is owned by the contract.
pub bytecode: Bytes,
/// Whether we are Interpreting the Ethereum Object Format (EOF) bytecode.
/// This is local field that is set from `contract.is_eof()`.
pub is_eof: bool,
/// Is init flag for eof create
pub is_eof_init: bool,
/// Shared memory.
///
/// Note: This field is only set while running the interpreter loop.
/// Otherwise it is taken and replaced with empty shared memory.
pub shared_memory: SharedMemory,
/// Stack.
pub stack: Stack,
/// EOF function stack.
pub function_stack: FunctionStack,
/// The return data buffer for internal calls.
/// It has multi usage:
///
/// * It contains the output bytes of call sub call.
/// * When this interpreter finishes execution it contains the output bytes of this contract.
pub return_data_buffer: Bytes,
/// Whether the interpreter is in "staticcall" mode, meaning no state changes can happen.
pub is_static: bool,
/// Actions that the EVM should do.
///
/// Set inside CALL or CREATE instructions and RETURN or REVERT instructions. Additionally those instructions will set
/// InstructionResult to CallOrCreate/Return/Revert so we know the reason.
pub next_action: InterpreterAction,
}
impl Interpreter {
/// Returns the opcode at the current instruction pointer.
#[inline]
pub fn current_opcode(&self) -> u8 {
unsafe { *self.instruction_pointer }
}
/// Returns the current program counter.
#[inline]
pub fn program_counter(&self) -> usize {
// SAFETY: `instruction_pointer` should be at an offset from the start of the bytecode.
// In practice this is always true unless a caller modifies the `instruction_pointer` field manually.
unsafe { self.instruction_pointer.offset_from(self.bytecode.as_ptr()) as usize }
}
As the function comment, if caller modifies the instruction_pointer
field manually, then we can easily violate the safety requirement of offset_from
mentioned at here by calling safe function program_counter
. For function current_opcode
, since the field instruction_pointer
is also public, we can dereference any pointer by using safe function.
Metadata
Metadata
Assignees
Labels
No labels