Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: refactor child context to be child context return data #388

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 25 additions & 24 deletions crates/evm/src/context.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,14 @@ impl CallContextImpl of CallContextTrait {

impl DefaultBoxCallContext of Default<Box<CallContext>> {
fn default() -> Box<CallContext> {
let call_context: CallContext = Default::default();
BoxTrait::new(call_context)
let call_ctx: CallContext = Default::default();
BoxTrait::new(call_ctx)
}
}

impl DefaultOptionSpanU8 of Default<Option<Span<u8>>> {
fn default() -> Option<Span<u8>> {
Option::None
}
}

Expand All @@ -130,13 +136,13 @@ struct ExecutionContext {
starknet_address: ContractAddress,
program_counter: u32,
status: Status,
call_context: Box<CallContext>,
call_ctx: Box<CallContext>,
destroyed_contracts: Array<EthAddress>,
events: Array<Event>,
create_addresses: Array<EthAddress>,
return_data: Array<u8>,
parent_context: Nullable<ExecutionContext>,
child_context: Nullable<ExecutionContext>,
parent_ctx: Nullable<ExecutionContext>,
child_return_data: Option<Span<u8>>,
}

impl DefaultBoxExecutionContext of Default<Box<ExecutionContext>> {
Expand All @@ -157,9 +163,9 @@ impl ExecutionContextImpl of ExecutionContextTrait {
id: usize,
evm_address: EthAddress,
starknet_address: ContractAddress,
call_context: CallContext,
parent_context: Nullable<ExecutionContext>,
child_context: Nullable<ExecutionContext>,
call_ctx: CallContext,
parent_ctx: Nullable<ExecutionContext>,
child_return_data: Option<Span<u8>>,
return_data: Array<u8>,
) -> ExecutionContext {
ExecutionContext {
Expand All @@ -168,23 +174,13 @@ impl ExecutionContextImpl of ExecutionContextTrait {
starknet_address,
program_counter: Default::default(),
status: Status::Active,
call_context: BoxTrait::new(
CallContextTrait::new(
call_context.caller,
call_context.bytecode,
call_context.calldata,
call_context.value,
call_context.read_only,
call_context.gas_limit,
call_context.gas_price,
)
),
call_ctx: BoxTrait::new(call_ctx),
destroyed_contracts: Default::default(),
events: Default::default(),
create_addresses: Default::default(),
return_data,
parent_context,
child_context,
parent_ctx,
child_return_data,
}
}

Expand All @@ -210,8 +206,8 @@ impl ExecutionContextImpl of ExecutionContextTrait {
}

#[inline(always)]
fn call_context(self: @ExecutionContext) -> CallContext {
(*self.call_context).unbox()
fn call_ctx(self: @ExecutionContext) -> CallContext {
(*self.call_ctx).unbox()
}

#[inline(always)]
Expand Down Expand Up @@ -280,7 +276,7 @@ impl ExecutionContextImpl of ExecutionContextTrait {
#[inline(always)]
fn read_code(self: @ExecutionContext, len: usize) -> Span<u8> {
// Copy code slice from [pc, pc+len]
let code = (*self.call_context).unbox().bytecode().slice(self.pc(), len);
let code = (*self.call_ctx).unbox().bytecode().slice(self.pc(), len);

code
}
Expand Down Expand Up @@ -314,4 +310,9 @@ impl ExecutionContextImpl of ExecutionContextTrait {
fn pc(self: @ExecutionContext) -> u32 {
*self.program_counter
}

#[inline(always)]
fn child_return_data(self: @ExecutionContext) -> Option<Span<u8>> {
*self.child_return_data
}
}
2 changes: 1 addition & 1 deletion crates/evm/src/interpreter.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ impl EVMInterpreterImpl of EVMInterpreterTrait {
fn decode_and_execute(ref self: EVMInterpreter, ref machine: Machine) -> Result<(), EVMError> {
// Retrieve the current program counter.
let pc = machine.pc();
let bytecode = machine.call_context().bytecode();
let bytecode = machine.call_ctx().bytecode();
let bytecode_len = bytecode.len();

// Check if PC is not out of bounds.
Expand Down
100 changes: 55 additions & 45 deletions crates/evm/src/machine.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ struct Journal {

#[derive(Destruct)]
struct Machine {
current_context: Box<ExecutionContext>,
current_ctx: Box<ExecutionContext>,
ctx_count: usize,
stack: Stack,
memory: Memory,
Expand All @@ -33,7 +33,7 @@ struct Machine {
impl DefaultMachine of Default<Machine> {
fn default() -> Machine {
Machine {
current_context: Default::default(),
current_ctx: Default::default(),
ctx_count: 1,
stack: Default::default(),
memory: Default::default(),
Expand All @@ -43,7 +43,7 @@ impl DefaultMachine of Default<Machine> {
}

/// A set of getters and setters for the current context
/// Since current_context is a pointer to the current context being executed by the machine we're forced into the following pattern:
/// Since current_ctx is a pointer to the current context being executed by the machine we're forced into the following pattern:
///
/// For getters:
/// Unbox the current ExecutionContext
Expand All @@ -67,155 +67,155 @@ impl MachineCurrentContextImpl of MachineCurrentContextTrait {
/// to divide a unique Stack/Memory simulated by a dict into
/// multiple sub-structures relative to a single context.
#[inline(always)]
fn set_current_context(ref self: Machine, ctx: ExecutionContext) {
fn set_current_ctx(ref self: Machine, ctx: ExecutionContext) {
self.memory.set_active_segment(ctx.id);
self.stack.set_active_segment(ctx.id);
self.current_context = BoxTrait::new(ctx);
self.current_ctx = BoxTrait::new(ctx);
}

#[inline(always)]
fn pc(ref self: Machine) -> usize {
let current_execution_ctx = self.current_context.unbox();
let current_execution_ctx = self.current_ctx.unbox();
let pc = current_execution_ctx.pc();
self.current_context = BoxTrait::new(current_execution_ctx);
self.current_ctx = BoxTrait::new(current_execution_ctx);
pc
}

#[inline(always)]
fn set_pc(ref self: Machine, new_pc: u32) {
let mut current_execution_ctx = self.current_context.unbox();
let mut current_execution_ctx = self.current_ctx.unbox();
current_execution_ctx.program_counter = new_pc;
self.current_context = BoxTrait::new(current_execution_ctx);
self.current_ctx = BoxTrait::new(current_execution_ctx);
}

#[inline(always)]
fn revert(ref self: Machine, revert_reason: Span<u8>) {
let mut current_execution_ctx = self.current_context.unbox();
let mut current_execution_ctx = self.current_ctx.unbox();
current_execution_ctx.revert(revert_reason);
self.current_context = BoxTrait::new(current_execution_ctx);
self.current_ctx = BoxTrait::new(current_execution_ctx);
}

#[inline(always)]
fn reverted(ref self: Machine) -> bool {
let current_execution_ctx = self.current_context.unbox();
let current_execution_ctx = self.current_ctx.unbox();
let reverted = current_execution_ctx.reverted();
self.current_context = BoxTrait::new(current_execution_ctx);
self.current_ctx = BoxTrait::new(current_execution_ctx);
reverted
}

#[inline(always)]
fn stopped(ref self: Machine) -> bool {
let current_execution_ctx = self.current_context.unbox();
let current_execution_ctx = self.current_ctx.unbox();
let stopped = current_execution_ctx.stopped();
self.current_context = BoxTrait::new(current_execution_ctx);
self.current_ctx = BoxTrait::new(current_execution_ctx);
stopped
}


#[inline(always)]
fn call_context(ref self: Machine) -> CallContext {
let current_execution_ctx = self.current_context.unbox();
let call_context = current_execution_ctx.call_context.unbox();
self.current_context = BoxTrait::new(current_execution_ctx);
call_context
fn call_ctx(ref self: Machine) -> CallContext {
let current_execution_ctx = self.current_ctx.unbox();
let call_ctx = current_execution_ctx.call_ctx.unbox();
self.current_ctx = BoxTrait::new(current_execution_ctx);
call_ctx
}

#[inline(always)]
fn destroyed_contracts(ref self: Machine) -> Span<EthAddress> {
let current_execution_ctx = self.current_context.unbox();
let current_execution_ctx = self.current_ctx.unbox();
let destroyed_contracts = current_execution_ctx.destroyed_contracts.span();
self.current_context = BoxTrait::new(current_execution_ctx);
self.current_ctx = BoxTrait::new(current_execution_ctx);
destroyed_contracts
}

#[inline(always)]
fn events(ref self: Machine) -> Span<Event> {
let current_execution_ctx = self.current_context.unbox();
let current_execution_ctx = self.current_ctx.unbox();
let events = current_execution_ctx.events.span();
self.current_context = BoxTrait::new(current_execution_ctx);
self.current_ctx = BoxTrait::new(current_execution_ctx);
events
}

#[inline(always)]
fn create_addresses(ref self: Machine) -> Span<EthAddress> {
let current_execution_ctx = self.current_context.unbox();
let current_execution_ctx = self.current_ctx.unbox();
let create_addresses = current_execution_ctx.create_addresses.span();
self.current_context = BoxTrait::new(current_execution_ctx);
self.current_ctx = BoxTrait::new(current_execution_ctx);
create_addresses
}

#[inline(always)]
fn return_data(ref self: Machine) -> Span<u8> {
let current_execution_ctx = self.current_context.unbox();
let current_execution_ctx = self.current_ctx.unbox();
let return_data = current_execution_ctx.return_data.span();
self.current_context = BoxTrait::new(current_execution_ctx);
self.current_ctx = BoxTrait::new(current_execution_ctx);
return_data
}

/// Stops the current execution context.
#[inline(always)]
fn stop(ref self: Machine) {
let mut current_execution_ctx = self.current_context.unbox();
let mut current_execution_ctx = self.current_ctx.unbox();
current_execution_ctx.status = Status::Stopped;
self.current_context = BoxTrait::new(current_execution_ctx);
self.current_ctx = BoxTrait::new(current_execution_ctx);
}


#[inline(always)]
fn evm_address(ref self: Machine) -> EthAddress {
let current_execution_ctx = self.current_context.unbox();
let current_execution_ctx = self.current_ctx.unbox();
let evm_address = current_execution_ctx.evm_address();
self.current_context = BoxTrait::new(current_execution_ctx);
self.current_ctx = BoxTrait::new(current_execution_ctx);
evm_address
}

#[inline(always)]
fn starknet_address(ref self: Machine) -> ContractAddress {
let current_execution_ctx = self.current_context.unbox();
let current_execution_ctx = self.current_ctx.unbox();
let starknet_address = current_execution_ctx.starknet_address();
self.current_context = BoxTrait::new(current_execution_ctx);
self.current_ctx = BoxTrait::new(current_execution_ctx);
starknet_address
}

#[inline(always)]
fn caller(ref self: Machine) -> EthAddress {
let current_call_ctx = self.call_context();
let current_call_ctx = self.call_ctx();
current_call_ctx.caller()
}

#[inline(always)]
fn read_only(ref self: Machine) -> bool {
let current_call_ctx = self.call_context();
let current_call_ctx = self.call_ctx();
current_call_ctx.read_only()
}

#[inline(always)]
fn gas_limit(ref self: Machine) -> u64 {
let current_call_ctx = self.call_context();
let current_call_ctx = self.call_ctx();
current_call_ctx.gas_limit()
}

#[inline(always)]
fn gas_price(ref self: Machine) -> u64 {
let current_call_ctx = self.call_context();
let current_call_ctx = self.call_ctx();
current_call_ctx.gas_price()
}

#[inline(always)]
fn value(ref self: Machine) -> u256 {
let current_call_ctx = self.call_context();
let current_call_ctx = self.call_ctx();
current_call_ctx.value()
}

#[inline(always)]
fn bytecode(ref self: Machine) -> Span<u8> {
let current_call_ctx = self.call_context();
let current_call_ctx = self.call_ctx();
current_call_ctx.bytecode()
}

#[inline(always)]
fn calldata(ref self: Machine) -> Span<u8> {
let current_call_ctx = self.call_context();
let current_call_ctx = self.call_ctx();
current_call_ctx.calldata()
}

Expand All @@ -240,16 +240,26 @@ impl MachineCurrentContextImpl of MachineCurrentContextTrait {
/// The root is always the first context to be executed, and thus has id 0.
#[inline(always)]
fn is_root(ref self: Machine) -> bool {
let current_execution_ctx = self.current_context.unbox();
let current_execution_ctx = self.current_ctx.unbox();
let is_root = current_execution_ctx.id == 0;
self.current_context = BoxTrait::new(current_execution_ctx);
self.current_ctx = BoxTrait::new(current_execution_ctx);
is_root
}

#[inline(always)]
fn set_return_data(ref self: Machine, value: Array<u8>) {
let mut current_execution_ctx = self.current_context.unbox();
let mut current_execution_ctx = self.current_ctx.unbox();
current_execution_ctx.return_data = value;
self.current_context = BoxTrait::new(current_execution_ctx);
self.current_ctx = BoxTrait::new(current_execution_ctx);
}

/// Getter for the return data of a child context, accessed from its parent context
/// Enabler for RETURNDATASIZE and RETURNDATACOPY opcodes
#[inline(always)]
fn child_return_data(ref self: Machine) -> Option<Span<u8>> {
let mut current_execution_ctx = self.current_ctx.unbox();
let child_return_data = current_execution_ctx.child_return_data();
self.current_ctx = BoxTrait::new(current_execution_ctx);
child_return_data
}
}
Loading
Loading