@@ -42,7 +42,7 @@ namespace
4242// / or EVMC_SUCCESS if everything is fine.
4343template <Opcode Op>
4444inline evmc_status_code check_requirements (const CostTable& cost_table, int64_t & gas_left,
45- const uint256* stack_top, const uint256* stack_bottom) noexcept
45+ const uint256* stack_end, [[maybe_unused]] const uint256* stack_bottom) noexcept
4646{
4747 static_assert (
4848 !instr::has_const_gas_cost (Op) || instr::gas_costs[EVMC_FRONTIER][Op] != instr::undefined,
@@ -63,20 +63,36 @@ inline evmc_status_code check_requirements(const CostTable& cost_table, int64_t&
6363 }
6464 }
6565
66+ const auto stack_end_u = reinterpret_cast <uintptr_t >(stack_end);
67+
68+ const auto stack_height = stack_end_u % StackSpace::alignment / sizeof (uint256);
69+
70+ assert (stack_height == static_cast <uintptr_t >(stack_end - stack_bottom));
71+
6672 // Check stack requirements first. This order is not required,
6773 // but it is nicer because a complete gas check may need to inspect operands.
6874 if constexpr (instr::traits[Op].stack_height_change > 0 )
6975 {
7076 static_assert (instr::traits[Op].stack_height_change == 1 ,
7177 " unexpected instruction with multiple results" );
72- if (INTX_UNLIKELY (stack_top == stack_bottom + StackSpace::limit))
78+
79+ const auto overflow = (stack_end_u & 0x8000 ) != 0 ;
80+ [[maybe_unused]] const auto expected_overflow = stack_height == StackSpace::limit;
81+ assert (overflow == expected_overflow);
82+
83+ if (INTX_UNLIKELY (overflow))
7384 return EVMC_STACK_OVERFLOW;
7485 }
7586 if constexpr (instr::traits[Op].stack_height_required > 0 )
7687 {
7788 // Check stack underflow using pointer comparison <= (better optimization).
7889 static constexpr auto min_offset = instr::traits[Op].stack_height_required - 1 ;
79- if (INTX_UNLIKELY (stack_top <= stack_bottom + min_offset))
90+ const auto arg0 = stack_end - 1 - min_offset;
91+
92+ const auto underflow = (reinterpret_cast <uintptr_t >(arg0) & 0x8000 ) != 0 ;
93+ assert (underflow == (stack_height <= min_offset));
94+
95+ if (INTX_UNLIKELY (underflow))
8096 return EVMC_STACK_UNDERFLOW;
8197 }
8298
0 commit comments