From 47ae17cebcd0de5298d2309be502046b25a2ab30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Wed, 22 May 2024 09:24:06 +0200 Subject: [PATCH] Track EVM stack "end" instead of "top" --- lib/evmone/advanced_analysis.hpp | 4 ++-- lib/evmone/baseline.cpp | 28 ++++++++++++++-------------- lib/evmone/execution_state.hpp | 5 +---- lib/evmone/instructions.hpp | 15 +++++++++------ 4 files changed, 26 insertions(+), 26 deletions(-) diff --git a/lib/evmone/advanced_analysis.hpp b/lib/evmone/advanced_analysis.hpp index f7d8eeaa42..c3a22525f6 100644 --- a/lib/evmone/advanced_analysis.hpp +++ b/lib/evmone/advanced_analysis.hpp @@ -57,11 +57,11 @@ struct AdvancedExecutionState : ExecutionState /// Computes the current EVM stack height. [[nodiscard]] int stack_size() noexcept { - return static_cast((&stack.top() - stack_space.bottom())); + return static_cast(stack.end() - stack_space.bottom()); } /// Adjust the EVM stack height by given change. - void adjust_stack_size(int change) noexcept { stack = &stack.top() + change; } + void adjust_stack_size(int change) noexcept { stack = stack.end() + change; } /// Terminates the execution with the given status code. const Instruction* exit(evmc_status_code status_code) noexcept diff --git a/lib/evmone/baseline.cpp b/lib/evmone/baseline.cpp index 94a79bdc66..b27084e8a6 100644 --- a/lib/evmone/baseline.cpp +++ b/lib/evmone/baseline.cpp @@ -153,7 +153,7 @@ inline evmc_status_code check_requirements(const CostTable& cost_table, int64_t& struct Position { code_iterator code_it; ///< The position in the code. - uint256* stack_top; ///< The pointer to the stack top. + uint256* stack_end; ///< The pointer to the stack end. }; /// Helpers for invoking instruction implementations of different signatures. @@ -161,7 +161,7 @@ struct Position [[release_inline]] inline code_iterator invoke(void (*instr_fn)(StackTop) noexcept, Position pos, int64_t& /*gas*/, ExecutionState& /*state*/) noexcept { - instr_fn(pos.stack_top); + instr_fn(pos.stack_end); return pos.code_it + 1; } @@ -169,7 +169,7 @@ struct Position Result (*instr_fn)(StackTop, int64_t, ExecutionState&) noexcept, Position pos, int64_t& gas, ExecutionState& state) noexcept { - const auto o = instr_fn(pos.stack_top, gas, state); + const auto o = instr_fn(pos.stack_end, gas, state); gas = o.gas_left; if (o.status != EVMC_SUCCESS) { @@ -182,7 +182,7 @@ struct Position [[release_inline]] inline code_iterator invoke(void (*instr_fn)(StackTop, ExecutionState&) noexcept, Position pos, int64_t& /*gas*/, ExecutionState& state) noexcept { - instr_fn(pos.stack_top, state); + instr_fn(pos.stack_end, state); return pos.code_it + 1; } @@ -190,21 +190,21 @@ struct Position code_iterator (*instr_fn)(StackTop, ExecutionState&, code_iterator) noexcept, Position pos, int64_t& /*gas*/, ExecutionState& state) noexcept { - return instr_fn(pos.stack_top, state, pos.code_it); + return instr_fn(pos.stack_end, state, pos.code_it); } [[release_inline]] inline code_iterator invoke( code_iterator (*instr_fn)(StackTop, code_iterator) noexcept, Position pos, int64_t& /*gas*/, ExecutionState& /*state*/) noexcept { - return instr_fn(pos.stack_top, pos.code_it); + return instr_fn(pos.stack_end, pos.code_it); } [[release_inline]] inline code_iterator invoke( TermResult (*instr_fn)(StackTop, int64_t, ExecutionState&) noexcept, Position pos, int64_t& gas, ExecutionState& state) noexcept { - const auto result = instr_fn(pos.stack_top, gas, state); + const auto result = instr_fn(pos.stack_end, gas, state); gas = result.gas_left; state.status = result.status; return nullptr; @@ -214,7 +214,7 @@ struct Position Result (*instr_fn)(StackTop, int64_t, ExecutionState&, code_iterator&) noexcept, Position pos, int64_t& gas, ExecutionState& state) noexcept { - const auto result = instr_fn(pos.stack_top, gas, state, pos.code_it); + const auto result = instr_fn(pos.stack_end, gas, state, pos.code_it); gas = result.gas_left; if (result.status != EVMC_SUCCESS) { @@ -228,7 +228,7 @@ struct Position TermResult (*instr_fn)(StackTop, int64_t, ExecutionState&, code_iterator) noexcept, Position pos, int64_t& gas, ExecutionState& state) noexcept { - const auto result = instr_fn(pos.stack_top, gas, state, pos.code_it); + const auto result = instr_fn(pos.stack_end, gas, state, pos.code_it); gas = result.gas_left; state.status = result.status; return nullptr; @@ -239,14 +239,14 @@ template [[release_inline]] inline Position invoke(const CostTable& cost_table, const uint256* stack_bottom, Position pos, int64_t& gas, ExecutionState& state) noexcept { - if (const auto status = check_requirements(cost_table, gas, pos.stack_top, stack_bottom); + if (const auto status = check_requirements(cost_table, gas, pos.stack_end, stack_bottom); status != EVMC_SUCCESS) { state.status = status; - return {nullptr, pos.stack_top}; + return {nullptr, pos.stack_end}; } const auto new_pos = invoke(instr::core::impl, pos, gas, state); - const auto new_stack_top = pos.stack_top + instr::traits[Op].stack_height_change; + const auto new_stack_top = pos.stack_end + instr::traits[Op].stack_height_change; return {new_pos, new_stack_top}; } @@ -265,11 +265,11 @@ int64_t dispatch(const CostTable& cost_table, ExecutionState& state, int64_t gas if constexpr (TracingEnabled) { const auto offset = static_cast(position.code_it - code); - const auto stack_height = static_cast(position.stack_top - stack_bottom); + const auto stack_height = static_cast(position.stack_end - stack_bottom); if (offset < state.original_code.size()) // Skip STOP from code padding. { tracer->notify_instruction_start( - offset, position.stack_top, stack_height, gas, state); + offset, position.stack_end - 1, stack_height, gas, state); } } diff --git a/lib/evmone/execution_state.hpp b/lib/evmone/execution_state.hpp index e78056e3c1..f84162e4e1 100644 --- a/lib/evmone/execution_state.hpp +++ b/lib/evmone/execution_state.hpp @@ -32,10 +32,7 @@ class StackSpace static constexpr auto limit = 1024; /// Returns the pointer to the "bottom", i.e. below the stack space. - [[nodiscard, clang::no_sanitize("bounds")]] uint256* bottom() noexcept - { - return m_stack_space - 1; - } + [[nodiscard]] uint256* bottom() noexcept { return m_stack_space; } private: /// The storage allocated for maximum possible number of items. diff --git a/lib/evmone/instructions.hpp b/lib/evmone/instructions.hpp index 12d57b397a..e77bcc3fee 100644 --- a/lib/evmone/instructions.hpp +++ b/lib/evmone/instructions.hpp @@ -18,25 +18,28 @@ using code_iterator = const uint8_t*; /// and allows retrieving stack items and manipulating the pointer. class StackTop { - uint256* m_top; + uint256* m_end; ///< Pointer to the stack end (1 slot above the stack top item). public: - StackTop(uint256* top) noexcept : m_top{top} {} + explicit(false) StackTop(uint256* end) noexcept : m_end{end} {} + + /// Returns the pointer to the stack end (the stack slot above the top item). + [[nodiscard]] uint256* end() noexcept { return m_end; } /// Returns the reference to the stack item by index, where 0 means the top item /// and positive index values the items further down the stack. /// Using [-1] is also valid, but .push() should be used instead. - [[nodiscard]] uint256& operator[](int index) noexcept { return m_top[-index]; } + [[nodiscard]] uint256& operator[](int index) noexcept { return m_end[-1 - index]; } /// Returns the reference to the stack top item. - [[nodiscard]] uint256& top() noexcept { return *m_top; } + [[nodiscard]] uint256& top() noexcept { return m_end[-1]; } /// Returns the current top item and move the stack top pointer down. /// The value is returned by reference because the stack slot remains valid. - [[nodiscard]] uint256& pop() noexcept { return *m_top--; } + [[nodiscard]] uint256& pop() noexcept { return *--m_end; } /// Assigns the value to the stack top and moves the stack top pointer up. - void push(const uint256& value) noexcept { *++m_top = value; } + void push(const uint256& value) noexcept { *m_end++ = value; } };