Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(codegen): stack limitation should be 1024 #295

Merged
merged 1 commit into from
Dec 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 14 additions & 10 deletions codegen/src/asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
use crate::{Buffer, Error, Result};
use opcodes::{for_each_cancun_operator, Cancun as OpCode, OpCode as _};

const MAX_STACK_SIZE: u16 = 1024;

/// Low level assembler implementation for EVM.
#[derive(Default, Clone, Debug)]
pub struct Assembler {
Expand All @@ -18,8 +20,8 @@ pub struct Assembler {
gas: u128,
/// Memory pointer for byte offset.
pub mp: usize,
/// Stack pointer, maximum 1024 items.
pub sp: u8,
/// Stack pointer, maximum `MAX_STACK_SIZE` items.
pub sp: u16,
}

impl Assembler {
Expand All @@ -41,7 +43,7 @@ impl Assembler {
}

/// Increment stack pointer
pub fn increment_sp(&mut self, items: u8) -> Result<()> {
pub fn increment_sp(&mut self, items: u16) -> Result<()> {
if items == 0 {
return Ok(());
}
Expand All @@ -51,18 +53,20 @@ impl Assembler {
self.sp,
self.sp + items
);
self.sp += items;
self.sp = self
.sp
.checked_add(items)
.ok_or(Error::StackOverflow(self.sp, items))?;

// TODO: fix this limitation: should be 1024. (#127)
if self.sp > 254 {
return Err(Error::StackOverflow(self.sp));
if self.sp > MAX_STACK_SIZE {
return Err(Error::StackOverflow(self.sp, items));
}

Ok(())
}

/// Decrement stack pointer
pub fn decrement_sp(&mut self, items: u8) -> Result<()> {
pub fn decrement_sp(&mut self, items: u16) -> Result<()> {
if items == 0 {
return Ok(());
}
Expand Down Expand Up @@ -118,10 +122,10 @@ impl Assembler {
/// the stack usages.
pub fn emit_op(&mut self, opcode: OpCode) -> Result<()> {
tracing::trace!("emit opcode: {:?}", opcode);
self.decrement_sp(opcode.stack_in() as u8)?;
self.decrement_sp(opcode.stack_in())?;
self.emit(opcode.into());
self.increment_gas(opcode.gas().into());
self.increment_sp(opcode.stack_out() as u8)?;
self.increment_sp(opcode.stack_out())?;

Ok(())
}
Expand Down
2 changes: 1 addition & 1 deletion codegen/src/codegen/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ impl Function {
/// Finish code generation.
pub fn finish(self, jump_table: &mut JumpTable, pc: u16) -> Result<Buffer> {
let sp = self.masm.sp();
if !self.is_main && self.abi.is_none() && self.masm.sp() != self.ty.results().len() as u8 {
if !self.is_main && self.abi.is_none() && self.masm.sp() != self.ty.results().len() as u16 {
return Err(Error::StackNotBalanced(sp));
}

Expand Down
4 changes: 2 additions & 2 deletions codegen/src/control.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,15 @@ pub struct ControlStackFrame {
result: BlockType,

/// Original stack pointer.
pub original_sp: u8,
pub original_sp: u16,
}

impl ControlStackFrame {
/// Create a new control stack frame.
pub fn new(
ty: ControlStackFrameType,
original_pc_offset: u16,
original_sp: u8,
original_sp: u16,
result: BlockType,
) -> Self {
Self {
Expand Down
10 changes: 5 additions & 5 deletions codegen/src/masm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ impl MacroAssembler {
30 => self.asm._push30(),
31 => self.asm._push31(),
32 => self.asm._push32(),
_ => return Err(Error::StackIndexOutOfRange(len as u8)),
_ => return Err(Error::StackIndexOutOfRange(len as u16)),
}?;

self.asm.emitn(bytes);
Expand All @@ -155,12 +155,12 @@ impl MacroAssembler {
}

/// Get the stack pointer.
pub fn sp(&self) -> u8 {
pub fn sp(&self) -> u16 {
self.asm.sp
}

/// Swap memory by target index.
pub fn swap(&mut self, index: u8) -> Result<()> {
pub fn swap(&mut self, index: u16) -> Result<()> {
tracing::trace!("swap index: {}", index);
match index {
0 => Ok(()),
Expand All @@ -185,7 +185,7 @@ impl MacroAssembler {
}

/// Duplicate stack item by target index.
pub fn dup(&mut self, index: u8) -> Result<()> {
pub fn dup(&mut self, index: u16) -> Result<()> {
tracing::trace!("dup index: {}", index);
match index {
0 => Ok(()),
Expand All @@ -212,7 +212,7 @@ impl MacroAssembler {
/// Shift the program counter to the bottom or the top of the
/// parameters. This is used by the callee function for jumping
/// back to the caller function.
pub fn shift_stack(&mut self, count: u8, from_top: bool) -> Result<()> {
pub fn shift_stack(&mut self, count: u16, from_top: bool) -> Result<()> {
let mut swaps = 0;

if from_top {
Expand Down
2 changes: 1 addition & 1 deletion codegen/src/masm/ret.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ impl MacroAssembler {

/// Handle the return of a call.
pub fn call_return(&mut self, results: &[ValType]) -> Result<()> {
let len = results.len() as u8;
let len = results.len() as u16;

tracing::trace!("cleaning frame stack, target: {}", len + 1);
// TODO: clean stacks via the count of nested control stacks.
Expand Down
10 changes: 5 additions & 5 deletions codegen/src/result.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,16 +86,16 @@ pub enum Error {
SelectorNotFound,
/// Failed to index data on stack.
#[error("Stack index is out of range {0}, max is 255 (0x400)")]
StackIndexOutOfRange(u8),
StackIndexOutOfRange(u16),
/// Failed to increment stack pointer.
#[error("Stack overflow, max is 1024 stack items, got {0}")]
StackOverflow(u8),
#[error("Stack overflow, max is 1024 stack items, but add {1} to {0}")]
StackOverflow(u16, u16),
/// Failed to decrement stack pointer.
#[error("Stack underflow, current stack items {0}, expect at least {1}")]
StackUnderflow(u8, u8),
StackUnderflow(u16, u16),
/// Failed to pop stack.
#[error("Stack not balanced, current stack items {0}")]
StackNotBalanced(u8),
StackNotBalanced(u16),
/// Failed to queue host functions.
#[error("Unsupported host function {0:?}")]
UnsupportedHostFunc(crate::wasm::HostFunc),
Expand Down
2 changes: 1 addition & 1 deletion codegen/src/visitor/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ impl Function {

// Adjust the stack pointer for the results.
self.masm._jumpdest()?;
self.masm.increment_sp(*results as u8)?;
self.masm.increment_sp(*results as u16)?;
Ok(())
}

Expand Down
Loading