Skip to content

Commit

Permalink
subroutines (ethereum#2484)
Browse files Browse the repository at this point in the history
* subroutines

* redirect discussions to new magicians thread

* yet more concise

* thanks holiman

* thanks again holiman

* specify stack size, require jumpdest target for retsub, fix testcase and pseudocode
  • Loading branch information
gcolvin authored and Arachnid committed Mar 6, 2021
1 parent 94e9cbd commit 1a86d07
Showing 1 changed file with 88 additions and 0 deletions.
88 changes: 88 additions & 0 deletions EIPS/eip-2315.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
---
eip: 2315
title: Simple Subroutines for the EVM
status: Draft
type: Standards Track
category: Core
author: Greg Colvin
discussions-to: https://ethereum-magicians.org/t/eip-2315-simple-subroutines-for-the-evm/3941
created: 2019-10-17
---
## 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, which must be a `JUMPDEST`

A program may jump at most 1024 times without returning.

## 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 JUMPDEST []
5 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]
push(return_stack, PC)
PC = 0
while PC < code_size {
opcode = bytecode[PC]
...
switch opcode {
...
case JUMPSUB:
push(return_stack, PC + 1)
PC = pop(data_stack)
continue
case RETSUB:
PC = pop(return_stack)
continue
}
++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

This proposal introduces no new security considerations to the EVM.

**Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).**

0 comments on commit 1a86d07

Please sign in to comment.