EOF - JUMPF and non-returning functions
The EIP-6206 proposal introduces a new instruction called JUMPF for chaining function calls in Ethereum. It allows for tail call optimizations in EOF functions (EIP-4750) by jumping to a code section without adding a new return stack frame. JUMPF has one immediate argument, code_section_index, encoded as a 16-bit unsigned big-endian value, and costs 5 gas. It neither pops nor pushes anything to the operand stack. The proposal also includes specifications for execution semantics, code validation, rationale, backwards compatibility, and security considerations.
Video
Original
Abstract
This EIP allows for tail call optimizations in EOF functions (EIP-4750) by introducing a new instruction JUMPF
, which jumps to a code section without adding a new return stack frame.
Additionally the format of the type sections is extended to allow declaring sections as non-returning, with simplified stack validation for JUMPF
to such section.
Motivation
It is common for functions to make a call at the end of the routine only to then return. JUMPF
optimizes this behavior by changing code sections without needing to update the return stack.
Knowing at validation time that a function will never return control allows for JUMPF
to such function to be treated similar to terminating instructions, where extra items may be left on the operand stack at execution termination. This provides opportunities for compilers to generate more optimal code, both in code size and in spent gas. It is particularly beneficial for small error handling helpers, that end execution with REVERT
: they are commonly reused in multiple branches and extracting them into a helper function is efficient, when there is no need to pop extra stack items before JUMPF
to such helper.
Specification
Type section changes
We define a non-returning section as one that cannot return control to its caller section.
Type section outputs
field contains a special value 0x80
when corresponding code section is non-returning. See Non-returning status validation below for validation details.
The first code section MUST have 0 inputs and be non-returning.
Execution Semantics
A new instruction, JUMPF (0xe5)
, is introduced.
JUMPF
has one immediate argument,target_section_index
, encoded as a 16-bit unsigned big-endian value.- If the operand stack size exceeds
1024 - type[target_section_index].max_stack_height + type[target_section_index].inputs
(i.e. if the called function may exceed the global stack height limit), execution results in an exceptional halt. This guarantees that the target function does not exceed global stack height limit. JUMPF
setscurrent_section_index
totarget_section_index
andPC
to0
, but does not change the return stack. Execution continues in the target section.JUMPF
costs 5 gas.JUMPF
neither pops nor pushes anything to the operand stack.
Code Validation
Let the definition of type[i]
be inherited from EIP-4750 and define stack_height_min
and stack_height_max
to be the stack height bounds at a certain instruction during the instruction flow traversal.
- The immediate argument of
JUMPF
MUST be less than the total number of code sections. - For each
JUMPF
instruction:- either
type[current_section_index].outputs
MUST be greater or equaltype[target_section_index].outputs
, - or
type[target_section_index].outputs
MUST be0x80
- either
- The stack height validation at
JUMPF
depends on whether the target section is non-returning:JUMPF
into returning section (type[target_section_index].outputs
does not equal0x80
):stack_height_min
andstack_height_max
MUST be equal totype[current_section_index].outputs - type[target_section_index].outputs + type[target_section_index].inputs
. This means that target section can output less stack elements than the original code section called by the top element on the return stack, if the current code section leaves the deltatype[current_section_index].outputs - type[target_section_index].outputs
element(s) on the stack.JUMPF
into non-returning section (type[target_section_index].outputs
equals0x80
):stack_height_min
MUST be greater than or equal totype[target_section_index].inputs
.
- Stack overflow check at
JUMPF
:stack_height_max
MUST be less than or equal to1024 - types[target_section_index].max_stack_height + types[target_section_index].inputs
. JUMPF
is considered terminating instruction, i.e. does not have successor instructions in code validation and MAY be final instruction in the section.- The code validation defined in EIP-4200 also fails if any
RJUMP*
offset points to one of the two bytes directly following aJUMPF
instruction.
CALLF
instruction validation is extended to include the rule:
- Code section is invalid in case an immediate argument
target_section_index
of anyCALLF
targets a non-returning section, i.e.type[target_section_index].outputs
equals0x80
.
Non-returning status validation
Section type MUST be non-returning if and only if the section contains no RETF
instructions and no JUMPF
instructions targeting returning sections (target section's status is checked via its output value in type section.)
Note: This implies that section containing only JUMPF
s into non-returning sections is non-returning itself.
Rationale
Allowing JUMPF
to section with less outputs
An alternative rule for JUMPF
stack validation could require the target section's outputs to be exactly equal to the current section's outputs. Under such rule, a particular target section (a shared "helper" piece of code) would only "match" sections (requiring some shared "helper" code to execute before returning) with the same number of outputs.
Instead, we allow a given JUMPF
target section to be called from sections with more outputs, as long as these sections provide these extra stack elements (the "delta") themselves. This will reduce duplicated code as it will allow compilers more flexibility during code generation such that certain helpers can be used generically by functions, regardless of their output values.
Backwards Compatibility
This change is backward compatible as EOF does not allow undefined instructions to be used or deployed, meaning no contracts will be affected.
Security Considerations
Needs discussion.
Copyright
Copyright and related rights waived via CC0.
Not miss a beat of EIPs' update?
Subscribe EIPs Fun to receive the latest updates of EIPs Good for Buidlers to follow up.
View all