ECIP 1085: Simple Subroutines for the EVM Source

AuthorGreg Colvin, Bob Summerwill
Discussions-Tohttps://ethereum-magicians.org/t/eip-2315-simple-subroutines-for-the-evm/3941
StatusDraft
TypeStandards Track
CategoryCore
Created2020-02-02

Abstract

This proposal introduces two opcodes to support subroutines: JUMPSUB and RETSUB.

Motivation

The EVM does not provide subroutines as a primitive. Instead, calls must be synthesized by fetching and pushing the current program counter on the data stack and jumping to the subroutine address; returns must be synthesized by getting the return address to the top of stack and jumping back to it.

Specification

JUMPSUB

Jumps to the address on top of the stack, which must be the offset of a JUMPDEST.

RETSUB

Returns to the instruction after the most recently executed JUMPSUB instruction.

A program may JUMPSUB at most 1023 times without an intervening RETSUB.

Rationale

This is the smallest possible change that provides native subroutines without breaking backwards compatibility.

Backwards Compatibility

These changes do not affect the semantics of existing EVM code.

Test Cases

step op       stack
0    PUSH1 3  []
1    JUMPSUB  [3]
4    STOP     []
2    JUMPDEST []
3    RETSUB   []

This code should terminate after 5 steps with an empty stack.

Implementations

No clients have implemented this proposal as of yet.

The new operators proposed here are implemented by the following pseudocode, which adds cases for JUMPSUB and RETSUB to a simple loop-and-switch interpreter.

bytecode[code_size]
data_stack[1024]
return_stack[1024]
PC = 0
push(return_stack, PC)
loop: while PC < code_size {
   opcode = bytecode[PC]
   switch opcode {
   ...
   case JUMPSUB:
      push(return_stack, PC)
      PC = pop(data_stack)
      continue loop
   case RETSUB:
      PC = pop(return_stack)
   }
   ++PC
}

Execution of EVM bytecode begins with one value on the return stack—the size of the bytecode. The virtual byte of 0 at this offset is the EVM STOP opcode, so executing a RETSUB with no prior JUMPSUB executes a STOP. A STOP or RETURN ends the execution of the subroutine and the program.

We suggest the cost of JUMPSUB should be low, and RETSUB should be verylow. Measurement will tell. We suggest the following opcodes:

0xbe JUMPSUB
0xbf RETSUB

Security Considerations

Program flow analysis frameworks will need to be updated to allow for a new type of branch -JUMPSUB - and new type of branching, since a RETSUB will cause a jump to a destination which is not a JUMPDEST.

This proposal is licensed under the Creative Commons Attribution-ShareAlike 4.0 International license based on specifications developed by Greg Colvin within the Ethereum improvement process as EIP 2315: Simple Subroutines for the EVM.

Bob Summerwill, the author of this proposal attests that his is the sole author of this specific document based on Greg Colvin’s work and that he is able to contribute this work to the ECIP process under the CC-BY-SA-4.0 licence. He further attests that he neither holds nor is aware of any patents, trademarks, copyright issues or other IP hinderances associated with this work.