From 9575aad2930e5c83c0b227282abe4fca86e7b00b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Tue, 28 Mar 2023 10:43:25 +0200 Subject: [PATCH] Remove gas_left from ExecutionState --- lib/evmone/advanced_analysis.hpp | 3 ++ lib/evmone/baseline.cpp | 37 ++++++++++--------------- lib/evmone/baseline.hpp | 2 +- lib/evmone/execution_state.hpp | 8 +----- test/bench/helpers.hpp | 2 +- test/unittests/execution_state_test.cpp | 2 -- 6 files changed, 21 insertions(+), 33 deletions(-) diff --git a/lib/evmone/advanced_analysis.hpp b/lib/evmone/advanced_analysis.hpp index 252a158981..53fc7a5b2c 100644 --- a/lib/evmone/advanced_analysis.hpp +++ b/lib/evmone/advanced_analysis.hpp @@ -80,6 +80,7 @@ class Stack /// The execution state specialized for the Advanced interpreter. struct AdvancedExecutionState : ExecutionState { + int64_t gas_left = 0; Stack stack; /// The gas cost of the current block. @@ -93,6 +94,7 @@ struct AdvancedExecutionState : ExecutionState const evmc_host_interface& host_interface, evmc_host_context* host_ctx, bytes_view _code) noexcept : ExecutionState{message, revision, host_interface, host_ctx, _code}, + gas_left{message.gas}, stack{stack_space.bottom()} {} @@ -109,6 +111,7 @@ struct AdvancedExecutionState : ExecutionState bytes_view _code) noexcept { ExecutionState::reset(message, revision, host_interface, host_ctx, _code); + gas_left = message.gas; stack.reset(stack_space.bottom()); analysis.advanced = nullptr; // For consistency with previous behavior. current_block_cost = 0; diff --git a/lib/evmone/baseline.cpp b/lib/evmone/baseline.cpp index 843f1b1bb2..b8463725c1 100644 --- a/lib/evmone/baseline.cpp +++ b/lib/evmone/baseline.cpp @@ -233,13 +233,11 @@ template template -void dispatch(const CostTable& cost_table, ExecutionState& state, const uint8_t* code, - Tracer* tracer = nullptr) noexcept +int64_t dispatch(const CostTable& cost_table, ExecutionState& state, int64_t gas, + const uint8_t* code, Tracer* tracer = nullptr) noexcept { const auto stack_bottom = state.stack_space.bottom(); - auto gas = state.gas_left; - // Code iterator and stack top pointer for interpreter loop. Position position{code, stack_bottom}; @@ -265,8 +263,7 @@ void dispatch(const CostTable& cost_table, ExecutionState& state, const uint8_t* if (const auto next = invoke(cost_table, stack_bottom, position, gas, state); \ next.code_it == nullptr) \ { \ - state.gas_left = gas; \ - return; \ + return gas; \ } \ else \ { \ @@ -281,16 +278,15 @@ void dispatch(const CostTable& cost_table, ExecutionState& state, const uint8_t* default: state.status = EVMC_UNDEFINED_INSTRUCTION; - state.gas_left = gas; - return; + return gas; } } INTX_UNREACHABLE(); } #if EVMONE_CGOTO_SUPPORTED -void dispatch_cgoto( - const CostTable& cost_table, ExecutionState& state, const uint8_t* code) noexcept +int64_t dispatch_cgoto( + const CostTable& cost_table, ExecutionState& state, int64_t gas, const uint8_t* code) noexcept { #pragma GCC diagnostic ignored "-Wpedantic" @@ -310,8 +306,6 @@ void dispatch_cgoto( // Code iterator and stack top pointer for interpreter loop. Position position{code, stack_bottom}; - auto gas = state.gas_left; - goto* cgoto_table[*position.code_it]; #define ON_OPCODE(OPCODE) \ @@ -319,8 +313,7 @@ void dispatch_cgoto( if (const auto next = invoke(cost_table, stack_bottom, position, gas, state); \ next.code_it == nullptr) \ { \ - state.gas_left = gas; \ - return; \ + return gas; \ } \ else \ { \ @@ -335,12 +328,13 @@ void dispatch_cgoto( TARGET_OP_UNDEFINED: state.status = EVMC_UNDEFINED_INSTRUCTION; - state.gas_left = gas; + return gas; } #endif } // namespace -evmc_result execute(const VM& vm, ExecutionState& state, const CodeAnalysis& analysis) noexcept +evmc_result execute( + const VM& vm, int64_t gas, ExecutionState& state, const CodeAnalysis& analysis) noexcept { state.analysis.baseline = &analysis; // Assign code analysis for instruction implementations. @@ -352,20 +346,19 @@ evmc_result execute(const VM& vm, ExecutionState& state, const CodeAnalysis& ana if (INTX_UNLIKELY(tracer != nullptr)) { tracer->notify_execution_start(state.rev, *state.msg, analysis.executable_code); - dispatch(cost_table, state, code.data(), tracer); + gas = dispatch(cost_table, state, gas, code.data(), tracer); } else { #if EVMONE_CGOTO_SUPPORTED if (vm.cgoto) - dispatch_cgoto(cost_table, state, code.data()); + gas = dispatch_cgoto(cost_table, state, gas, code.data()); else #endif - dispatch(cost_table, state, code.data()); + gas = dispatch(cost_table, state, gas, code.data()); } - const auto gas_left = - (state.status == EVMC_SUCCESS || state.status == EVMC_REVERT) ? state.gas_left : 0; + const auto gas_left = (state.status == EVMC_SUCCESS || state.status == EVMC_REVERT) ? gas : 0; const auto gas_refund = (state.status == EVMC_SUCCESS) ? state.gas_refund : 0; assert(state.output_size != 0 || state.output_offset == 0); @@ -385,6 +378,6 @@ evmc_result execute(evmc_vm* c_vm, const evmc_host_interface* host, evmc_host_co const auto jumpdest_map = analyze(rev, {code, code_size}); auto state = std::make_unique(*msg, rev, *host, ctx, bytes_view{code, code_size}); - return execute(*vm, *state, jumpdest_map); + return execute(*vm, msg->gas, *state, jumpdest_map); } } // namespace evmone::baseline diff --git a/lib/evmone/baseline.hpp b/lib/evmone/baseline.hpp index 1519534bc7..63ddae45ba 100644 --- a/lib/evmone/baseline.hpp +++ b/lib/evmone/baseline.hpp @@ -64,7 +64,7 @@ evmc_result execute(evmc_vm* vm, const evmc_host_interface* host, evmc_host_cont /// Executes in Baseline interpreter on the given external and initialized state. EVMC_EXPORT evmc_result execute( - const VM&, ExecutionState& state, const CodeAnalysis& analysis) noexcept; + const VM&, int64_t gas_limit, ExecutionState& state, const CodeAnalysis& analysis) noexcept; } // namespace baseline } // namespace evmone diff --git a/lib/evmone/execution_state.hpp b/lib/evmone/execution_state.hpp index 8aa54353ca..f8478516c7 100644 --- a/lib/evmone/execution_state.hpp +++ b/lib/evmone/execution_state.hpp @@ -125,7 +125,6 @@ class Memory class ExecutionState { public: - int64_t gas_left = 0; int64_t gas_refund = 0; Memory memory; const evmc_message* msg = nullptr; @@ -166,11 +165,7 @@ class ExecutionState ExecutionState(const evmc_message& message, evmc_revision revision, const evmc_host_interface& host_interface, evmc_host_context* host_ctx, bytes_view _code) noexcept - : gas_left{message.gas}, - msg{&message}, - host{host_interface, host_ctx}, - rev{revision}, - original_code{_code} + : msg{&message}, host{host_interface, host_ctx}, rev{revision}, original_code{_code} {} /// Resets the contents of the ExecutionState so that it could be reused. @@ -178,7 +173,6 @@ class ExecutionState const evmc_host_interface& host_interface, evmc_host_context* host_ctx, bytes_view _code) noexcept { - gas_left = message.gas; gas_refund = 0; memory.clear(); msg = &message; diff --git a/test/bench/helpers.hpp b/test/bench/helpers.hpp index ed4958b4e4..f978140e2b 100644 --- a/test/bench/helpers.hpp +++ b/test/bench/helpers.hpp @@ -65,7 +65,7 @@ inline evmc::Result baseline_execute(evmc::VM& c_vm, ExecutionState& exec_state, { const auto& vm = *static_cast(c_vm.get_raw_pointer()); exec_state.reset(msg, rev, host.get_interface(), host.to_context(), code); - return evmc::Result{baseline::execute(vm, exec_state, analysis)}; + return evmc::Result{baseline::execute(vm, msg.gas, exec_state, analysis)}; } inline evmc::Result evmc_execute(evmc::VM& vm, FakeExecutionState& /*exec_state*/, diff --git a/test/unittests/execution_state_test.cpp b/test/unittests/execution_state_test.cpp index 9e5f2c99f5..4be02355a5 100644 --- a/test/unittests/execution_state_test.cpp +++ b/test/unittests/execution_state_test.cpp @@ -28,7 +28,6 @@ TEST(execution_state, construct) const evmone::ExecutionState st{ msg, EVMC_MAX_REVISION, host_interface, nullptr, {code, std::size(code)}}; - EXPECT_EQ(st.gas_left, -1); EXPECT_EQ(st.memory.size(), 0); EXPECT_EQ(st.msg, &msg); EXPECT_EQ(st.rev, EVMC_MAX_REVISION); @@ -42,7 +41,6 @@ TEST(execution_state, default_construct) { const evmone::ExecutionState st; - EXPECT_EQ(st.gas_left, 0); EXPECT_EQ(st.memory.size(), 0); EXPECT_EQ(st.msg, nullptr); EXPECT_EQ(st.rev, EVMC_FRONTIER);