Skip to main content

Interpreter

Struct Interpreter 

pub struct Interpreter { /* private fields */ }
Expand description

Core CIL instruction interpreter.

The interpreter executes CIL instructions one at a time, managing the evaluation stack, local variables, and control flow. It uses a step-based execution model where each call to Self::step executes a single instruction.

§Example

use dotscope::emulation::{Interpreter, EmulationContext, EmulationLimits};

let limits = EmulationLimits::default();
let mut interpreter = Interpreter::new(limits, address_space, PointerSize::Bit64);

// Execute instructions one at a time
loop {
    match interpreter.step(&mut thread, &instruction)? {
        StepResult::Continue => continue,
        StepResult::Return { value } => break,
        StepResult::Branch { target } => {
            // Handle branch...
        }
        _ => {}
    }
}

Implementations§

§

impl Interpreter

pub fn new( limits: EmulationLimits, address_space: Arc<AddressSpace>, pointer_size: PointerSize, ) -> Self

Creates a new interpreter with the given execution limits, address space, and target pointer size.

§Arguments
  • limits - Execution limits to enforce during emulation.
  • address_space - Shared address space for all memory operations.
  • pointer_size - Target pointer size for native int/uint types.
§Returns

A new interpreter ready for execution.

pub fn address_space(&self) -> &Arc<AddressSpace>

Returns a reference to the address space.

pub fn ip(&self) -> &InstructionPointer

Returns a reference to the current instruction pointer.

pub fn ip_mut(&mut self) -> &mut InstructionPointer

Returns a mutable reference to the instruction pointer.

pub fn stats(&self) -> &ExecutionStats

Returns a reference to the execution statistics.

pub fn stats_mut(&mut self) -> &mut ExecutionStats

Returns a mutable reference to the execution statistics.

pub fn limits(&self) -> &EmulationLimits

Returns a reference to the execution limits.

pub fn set_method(&mut self, method: Token)

Sets the current method being executed.

§Arguments
  • method - The metadata token of the method to execute.

pub fn set_offset(&mut self, offset: u32)

Sets the instruction pointer to a specific offset within the current method.

§Arguments
  • offset - The bytecode offset to branch to.

pub fn start(&mut self)

Starts execution timing for statistics tracking.

Call this before beginning instruction execution to enable timeout checks and elapsed time tracking.

pub fn reset(&mut self)

Resets the interpreter state for a new execution.

Clears execution statistics and all active prefixes. The instruction pointer is not modified; use set_method to change the target method.

pub fn check_limits(&self, call_depth: usize) -> Result<()>

Checks execution limits and returns an error if exceeded.

§Arguments
  • call_depth - Current call depth from the thread’s call stack.
§Errors

Returns an error if any execution limit has been exceeded.

pub fn step( &mut self, thread: &mut EmulationThread, instruction: &Instruction, ) -> Result<StepResult>

Executes a single instruction.

This is the main dispatch method that examines the instruction and delegates to the appropriate handler based on the opcode.

§Arguments
  • memory - The memory state containing stack, locals, and heap.
  • _context - The emulation context (currently unused but reserved for future use).
  • instruction - The instruction to execute.
§Returns

A StepResult indicating the outcome:

  • Continue - Proceed to the next instruction
  • Branch { target } - Branch to the specified offset
  • Return { value } - Return from the current method
  • Call { method, args, is_virtual } - Call another method
  • Various other results for specific operations
§Errors

Returns an error if:

  • Execution limits are exceeded (instruction count, call depth, timeout, memory)
  • The instruction operand is invalid or missing
  • A type mismatch occurs during execution
  • The opcode is unsupported

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, A> IntoAst<A> for T
where T: Into<A>, A: Ast,

Source§

fn into_ast(self, _a: &A) -> A

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.