Skip to content

Commit

Permalink
Track stack size explicitly in dispatcher function
Browse files Browse the repository at this point in the history
  • Loading branch information
HerbertJordan committed Sep 11, 2023
1 parent ec90e4f commit 10c39e1
Showing 1 changed file with 26 additions and 30 deletions.
56 changes: 26 additions & 30 deletions cpp/vm/evmzero/interpreter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1690,11 +1690,10 @@ struct Result {
RunState state = RunState::kDone;
const uint8_t* pc = nullptr;
int64_t gas_left = 0;
uint256_t* top = nullptr;
};

template <op::OpCode op_code>
inline Result Run(const uint8_t* pc, int64_t gas, uint256_t* top, const uint8_t* code, Context& ctx) {
inline Result Run(const uint8_t* pc, int64_t gas, uint256_t* top, int32_t stack_size, const uint8_t* code, Context& ctx) {
using Impl = op::Impl<op_code>;

if constexpr (Impl::kInfo.introduced_in) {
Expand All @@ -1708,17 +1707,13 @@ inline Result Run(const uint8_t* pc, int64_t gas, uint256_t* top, const uint8_t*
return {.state = RunState::kErrorStaticCall};
}

// Check stack requirements. Since the stack is aligned to 64k boundaries, we
// can compute the stack size directly from the stack pointer.
auto size = Stack::kStackSize - (reinterpret_cast<size_t>(top) & 0xFFFF) / sizeof(*top);

if constexpr (Impl::kInfo.pops > 0) {
if (size < Impl::kInfo.pops) [[unlikely]] {
if (stack_size < Impl::kInfo.pops) [[unlikely]] {
return Result{.state = RunState::kErrorStackUnderflow};
}
}
if constexpr (Impl::kInfo.GetStackDelta() > 0) {
if (Stack::kStackSize - size < Impl::kInfo.GetStackDelta()) [[unlikely]] {
if (static_cast<int32_t>(Stack::kStackSize) - stack_size < Impl::kInfo.GetStackDelta()) [[unlikely]] {
return Result{.state = RunState::kErrorStackOverflow};
}
}
Expand Down Expand Up @@ -1759,12 +1754,10 @@ inline Result Run(const uint8_t* pc, int64_t gas, uint256_t* top, const uint8_t*
}

// Update the stack.
top -= Impl::kInfo.GetStackDelta();
return Result{
.state = state,
.pc = pc,
.gas_left = gas,
.top = top,
};
}

Expand All @@ -1777,6 +1770,7 @@ void RunInterpreter(Context& ctx, Profiler<ProfilingEnabled>& profiler) {
RunState state = RunState::kRunning;
int64_t gas = ctx.gas;
uint256_t* top = ctx.stack.Top();
int32_t size = static_cast<int32_t>(ctx.stack.GetSize());

auto* padded_code = ctx.padded_code.data();
auto* pc = padded_code;
Expand Down Expand Up @@ -1819,28 +1813,30 @@ void RunInterpreter(Context& ctx, Profiler<ProfilingEnabled>& profiler) {
// A valid op code is executed, followed by another DISPATCH call. Since the
// profiler currently doesn't work with recursive op codes, we don't profile
// CREATE and CALL op codes.
#define RUN_OPCODE(opcode) \
op_##opcode : { \
EVMZERO_PROFILE_ZONE_N(#opcode); \
profiler.template Start<Marker::opcode>(); \
auto res = Run<op::opcode>(pc, gas, top, padded_code, ctx); \
state = res.state; \
pc = res.pc; \
gas = res.gas_left; \
top = res.top; \
profiler.template End<Marker::opcode>(); \
} \
#define RUN_OPCODE(opcode) \
op_##opcode : { \
EVMZERO_PROFILE_ZONE_N(#opcode); \
profiler.template Start<Marker::opcode>(); \
auto res = Run<op::opcode>(pc, gas, top, size, padded_code, ctx); \
state = res.state; \
pc = res.pc; \
gas = res.gas_left; \
top -= op::Impl<op::opcode>::kInfo.GetStackDelta(); \
size += op::Impl<op::opcode>::kInfo.GetStackDelta(); \
profiler.template End<Marker::opcode>(); \
} \
DISPATCH();

#define RUN_OPCODE_NO_PROFILE(opcode) \
op_##opcode : { \
EVMZERO_PROFILE_ZONE(); \
auto res = Run<op::opcode>(pc, gas, top, padded_code, ctx); \
state = res.state; \
pc = res.pc; \
gas = res.gas_left; \
top = res.top; \
} \
#define RUN_OPCODE_NO_PROFILE(opcode) \
op_##opcode : { \
EVMZERO_PROFILE_ZONE(); \
auto res = Run<op::opcode>(pc, gas, top, size, padded_code, ctx); \
state = res.state; \
pc = res.pc; \
gas = res.gas_left; \
top -= op::Impl<op::opcode>::kInfo.GetStackDelta(); \
size += op::Impl<op::opcode>::kInfo.GetStackDelta(); \
} \
DISPATCH();

#define EVMZERO_OPCODE(name, value) RUN_OPCODE(name)
Expand Down

0 comments on commit 10c39e1

Please sign in to comment.