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

Subroutines #2527

Merged
merged 30 commits into from
Feb 21, 2020
Merged
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
8bd5166
Merge pull request #1 from gcolvin/gcolvin-simd
gcolvin Apr 25, 2017
5c77e0a
Merge pull request #2 from ethereum/master
gcolvin Feb 23, 2019
6aafe90
Merge pull request #3 from ethereum/master
gcolvin Feb 25, 2019
4389b81
Update eip-615.md
gcolvin Feb 26, 2019
48bd2d0
Update eip-615.md
gcolvin Feb 26, 2019
444162c
Update eip-615.md
gcolvin Feb 26, 2019
cb89b58
Update eip-615.md
gcolvin Feb 26, 2019
b117602
Update eip-615.md
gcolvin Feb 26, 2019
a919d63
mystery conflict
gcolvin Feb 2, 2020
17569ff
Merge branch 'master' of https://github.com/ethereum/EIPs into subrou…
gcolvin Feb 2, 2020
e1c156f
Add security issue caught by @holiman
gcolvin Feb 2, 2020
ffedd2d
Reconcile opcodes and names with eip-615
gcolvin Feb 2, 2020
2e30e37
Merge branch 'master' into subroutines
gcolvin Feb 2, 2020
d56747e
nudge
gcolvin Feb 2, 2020
64b4f21
Merge branch 'subroutines' of https://github.com/gcolvin/EIPs into su…
gcolvin Feb 2, 2020
b24a409
email
gcolvin Feb 2, 2020
3c46d2f
test cases
gcolvin Feb 3, 2020
1a30312
Merge branch 'master' into subroutines
gcolvin Feb 3, 2020
2a1331d
Merge branch 'master' of https://github.com/ethereum/EIPs into subrou…
gcolvin Feb 3, 2020
3731b79
references
gcolvin Feb 3, 2020
d0d375d
conflict
gcolvin Feb 3, 2020
6cb0b10
geth
gcolvin Feb 4, 2020
4ed1292
Merge branch 'master' into subroutines
gcolvin Feb 4, 2020
b1032b1
Add BEGINSUB and example bytecode for motivation
gcolvin Feb 17, 2020
2657efd
Merge branch 'subroutines' of https://github.com/gcolvin/EIPs into su…
gcolvin Feb 17, 2020
13028e9
spelling
gcolvin Feb 19, 2020
095c17e
Fix BEGINSUB in test cases
gcolvin Feb 20, 2020
0a3ba97
Merge branch 'master' into subroutines
gcolvin Feb 20, 2020
81e2285
don't let labels swallow destinations
gcolvin Feb 21, 2020
6656af5
Merge branch 'subroutines' of https://github.com/gcolvin/EIPs into su…
gcolvin Feb 21, 2020
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
33 changes: 20 additions & 13 deletions EIPS/eip-2315.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ This proposal introduces three opcodes to support subroutines: `BEGINSUB`, `JUM

The EVM does not provide subroutines as a primitive. Instead, calls can be synthesized by fetching and pushing the current program counter on the data stack and jumping to the subroutine address; returns can be synthesized by contriving to get the return address back to the top of stack and jumping back to it. Complex calling conventions are then needed to use the same stack for computation and control flow. Code becomes harder to read and write, and tools may need to pattern-match the conventions to identify the use of subroutines. Complex calling conventions like these can be avoided using memory, but regardless, it costs a lot of gas.

Having opcodes to directly support subroutines can eliminate this complexity and cost, just as for other machines and interpreters going back at least 60 years.
Having opcodes to directly support subroutines can eliminate this complexity and cost, just as for other physical and virtual machines going back at least 50 years.

In the Appendix we show example solc output for a simple program that uses over three times as much gas just calling and returning from subroutines as comparable code using these opcodes.

Expand Down Expand Up @@ -49,7 +49,7 @@ offset step opcode stack stack
0 0 PUSH1 3 [] []
1 1 JUMPSUB [3] [1]
2 4 STOP [] [1]
3 2 JUMPDEST [] [1]
3 2 BEGINSUB [] [1]
4 3 RETURNSUB [] []
```
The above code should terminate after 4 steps with an empty stack.
Expand All @@ -58,7 +58,7 @@ The above code should terminate after 4 steps with an empty stack.
offset step opcode stack stack
0 0 PUSH1 2 [] []
1 1 JUMPSUB [2] [1]
2 2 JUMPDEST [] [1]
2 2 BEGINSUB [] [1]
3 3 RETURNSUB [] []
```
The above code should terminate after 4 steps with an empty stack.
Expand All @@ -68,11 +68,11 @@ offset step opcode stack stack
0 0 PUSH1 3 [] []
1 1 JUMPSUB [3] [1]
2 8 STOP [] []
3 2 JUMPDEST [] [1]
3 2 BEGINSUB [] [1]
4 3 PUSH1 7 [] [1]
5 4 JUMPSUB [7] [1,5]
6 7 RETURNSUB [] [1]
7 5 JUMPDEST [] [1]
7 5 BEGINSUB [] [1]
8 6 RETURNSUB [] [1]
```
The above code should terminate after 8 steps with an empty stack. The above code should terminate after 8 steps with an empty stack.
Expand Down Expand Up @@ -118,7 +118,7 @@ We suggest that the cost of `BEGINSUB` be _base_, `JUMPSUB` be _low_, and `RETUR
```
## 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 - `RETURNSUB` - which will cause a jump to a destination which is a `JUMPSUB`, not a `JUMPDEST`.
Program flow analysis frameworks will need to be updated to allow for a new type of branch - `JUMPSUB` - which will cause a jump to a destination which is a `BEGINSUB`, not a `JUMPDEST`.

## Appendix: Comparative costs.

Expand All @@ -138,28 +138,32 @@ contract fun {
```
Here is solc 0.6.3 assembly code with labeled destinations.
```
TEST:
TEST:
jumpdest
0x00
RTN
0x02
0x03
TEST_MUL
jump
TEST_MUL:
TEST_MUL:
jumpdest
0x00
RTN
dup4
dup4
MULTIPLY
jump
RTN:
RTN:
jumpdest
swap4
swap3
pop
pop
pop
jump
MULTIPLY:
MULTIPLY:
jumpdest
mul
swap1
jump
Expand All @@ -168,17 +172,20 @@ solc does a good job with the multiply() function, which is a leaf. Non-leaf fu

This is the same code written using `jumpsub` and `returnsub`. Calling `fun.test()` will cost _34 gas_ (plus 5).
```
TEST:
TEST:
beginsub
0x02
0x03
TEST_MUL
jumpsub
returnsub
TEST_MUL:
TEST_MUL:
beginsub
MULTIPLY
jumpsub
returnsub
MULTIPLY:
MULTIPLY:
beginsub
mul
returnsub
```
Expand Down