-
Couldn't load subscription status.
- Fork 5.9k
Description
eip: 2315
title: Simple Subroutines for the EVM
status: Draft
type: Standards Track
category: Core
author: Greg Colvin
discussions-to: https://github.com/ethereum/EIPs/issues/2315
created: 2019-10-17
Simple Summary
Subroutines.
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, adjusting and pushing the current program counter 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
Proposal
JUMPSUB
Jumps to the address on top of the stack. This must be a
JUMPDEST.
RETSUB
Returns to the most recently executed
JUMPSUBinstruction.
Backwards Compatibility
These changes do not affect existing VM code..
Rationale
This is the smallest possible change that provides native subroutines without breaking backwards compatibility. It does not enforce validity like #615, but code that
_ pushes constants argument before every JUMP and JUMPI and
_ ensures that the data stack is the same size at the end of every basic block
is valid and will meet all of the #615 safety conditions. In particular, the Yellow paper defines five exceptional halting states. Valid code cannot violate states 3, 4, or 5.
1 Insufficient gas
2 More than 1024 stack items
3 Insufficient stack items
4 Invalid jump destination
5 Invalid instruction
Implementation
Jumps to and returns from subroutines are described here in terms of
- The EVM data stack, (as defined in the Yellow Paper).
- A return stack of program counters.
- The program counter
PCwhich is the byte offset of the currently executing instruction.
Execution of EVM bytecode begins with one value on the return stack—code_size. Executing the virtual byte of 0 at this offset causes an EVM to stop. Thus executing a RETSUB with no prior JUMPSUB executes a STOP. A STOP or RETURN ends the execution of a subroutine.
Semantics are defined by the following pseudo-C code.
uint256 data_stack[1024];
uint16 return_stack[1024] = {code_size};
byte code[code_size];
while (PC < code_size) {
switch opcode = code[PC];
case jumpsub:
push(return_stack,PC);
PC = pop(data_stack);
break;
cast retsub:
PC = pop(return_stack);
break;
...
case 0:
stop();
default:
invalid_instruction();
}
++PC;
}
Costs & Codes
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
Copyright and related rights waived via CC0.