forked from ethereum/EIPs
-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* 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
Showing
1 changed file
with
88 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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/).** |