5

I'm trying to analyze some EVM bytecode, comparing it with Java bytecode.

The Java specification states the following in the JVM specification §4.9.2. Structural Constraints:

If an instruction can be executed along several different execution paths, the operand stack must have the same depth (§2.6.2) prior to the execution of the instruction, regardless of the path taken.

So for any given instruction the operand stack has a well-defined size.

Now I wonder whether the same is true for EVM bytecode?

2

No, this does not hold for the EVM.

A simple counterexample is a recursive function:

function f(int a) {
    f(a);
}

That would get compiled to:

tag 5
  JUMPDEST          ; method entry
  PUSH [tag] 7      ; push return address
  DUP2              ; push argument `a`
  PUSH [tag] 5      ; push method address
  JUMP [in]         ; call method
tag 7
  JUMPDEST          ; method return

For each recursive call the stack gets two more items. So the stack size is different for each call.


Now how does Java handle recursion and maintain a fixed operand stack size? The difference between the JVM and EVM is that the JVM creates a new frame with a new operand stack for each method call, whereas the EVM just has one global operand stack. The EVM doesn't even know the concept of methods, although subroutines have been proposed.


This leaves an open question though... Does it hold for the stack size for code beside recursive calls? E.g. for an if-else block, would the stack size be the same afterwards, independent of the executed branch?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.