From bd982eab2cf2d2e17d2fd267a79443a719d81629 Mon Sep 17 00:00:00 2001 From: Evgeny Ukhanov Date: Fri, 13 Dec 2024 21:47:43 +0100 Subject: [PATCH] EIP-4750: RETF --- gasometer/src/lib.rs | 3 +++ runtime/src/eval/eof/call.rs | 17 +++++++++++++++++ runtime/src/eval/mod.rs | 2 +- runtime/src/eval/system.rs | 5 ----- 4 files changed, 21 insertions(+), 6 deletions(-) diff --git a/gasometer/src/lib.rs b/gasometer/src/lib.rs index 9fd669d9..eaa0844a 100644 --- a/gasometer/src/lib.rs +++ b/gasometer/src/lib.rs @@ -893,6 +893,9 @@ pub fn dynamic_opcode_cost( Opcode::CALLF if config.has_eof => GasCost::Low, Opcode::CALLF => GasCost::Invalid(opcode), + Opcode::RETF if config.has_eof => GasCost::VeryLow, + Opcode::RETF => GasCost::Invalid(opcode), + _ => GasCost::Invalid(opcode), }; diff --git a/runtime/src/eval/eof/call.rs b/runtime/src/eval/eof/call.rs index f3327f2c..1f8be0e4 100644 --- a/runtime/src/eval/eof/call.rs +++ b/runtime/src/eval/eof/call.rs @@ -46,3 +46,20 @@ pub fn callf(runtime: &mut Runtime, _handler: &mut H) -> Control Control::Continue } + +pub fn retf(runtime: &mut Runtime, _handler: &mut H) -> Control { + let eof = require_eof!(runtime); + let Some(function_return_state) = runtime.context.eof_function_stack.pop() else { + return Control::Exit(ExitFatal::CallErrorAsFatal(ExitError::EOFUnexpectedCall).into()); + }; + + let Some(code_section) = eof.body.code_section.get(function_return_state.index) else { + return Control::Exit(ExitFatal::CallErrorAsFatal(ExitError::EOFUnexpectedCall).into()); + }; + // Set machine code to target code section + runtime.machine.set_code(code_section); + // Set PC to position 0 + runtime.machine.set_pc(function_return_state.pc); + + Control::Continue +} diff --git a/runtime/src/eval/mod.rs b/runtime/src/eval/mod.rs index a6cfec75..4bfdded8 100644 --- a/runtime/src/eval/mod.rs +++ b/runtime/src/eval/mod.rs @@ -78,7 +78,7 @@ pub fn eval(state: &mut Runtime, opcode: Opcode, handler: &mut H) -> Opcode::RJUMPI => eof::control::rjumpi(state, handler), Opcode::RJUMPV => eof::control::rjumpv(state, handler), Opcode::CALLF => eof::call::callf(state, handler), - Opcode::RETF => system::retf(state, handler), + Opcode::RETF => eof::call::retf(state, handler), Opcode::JUMPF => system::jumpf(state, handler), Opcode::DUPN => eof::stack::dupn(state), Opcode::SWAPN => eof::stack::swapn(state), diff --git a/runtime/src/eval/system.rs b/runtime/src/eval/system.rs index aee7ebbc..281d5292 100644 --- a/runtime/src/eval/system.rs +++ b/runtime/src/eval/system.rs @@ -586,11 +586,6 @@ pub fn call(runtime: &mut Runtime, scheme: CallScheme, handler: &mut //=========================== // EOF related functions -#[allow(dead_code)] -pub fn retf(_runtime: &mut Runtime, _handler: &mut H) -> Control { - todo!() -} - #[allow(dead_code)] pub fn jumpf(_runtime: &mut Runtime, _handler: &mut H) -> Control { todo!()