Conversation
EIP-7979 adds a per-frame return stack and three instructions to the EVM. This implements them in the Baseline interpreter, available from the EVMC_EXPERIMENTAL revision. - CALLSUB (0xB0, 8 gas) pops a destination, which must be a CALLDEST, pushes the position of the next instruction onto the return stack and transfers control. The return stack holds at most 1024 entries. - CALLDEST (0xB1, 1 gas) marks a subroutine entry; it is a no-op like JUMPDEST and, from EVMC_EXPERIMENTAL on, also a valid JUMP/JUMPI destination. - RETURNSUB (0xB2, 5 gas) pops the return stack into the program counter. The code analysis computes a second bitset of CALLDEST positions next to the JUMPDEST one in a single pass. Because the analysis is cached per code independently of the revision, CALLDESTs are kept out of the jumpdest bitset; jump_impl consults the CALLDEST bitset only when the JUMPDEST test fails and the revision has EIP-7979, so ordinary jumps are unaffected and pre-EIP behaviour is unchanged. Return-stack overflow and underflow report EVMC_STACK_OVERFLOW and EVMC_STACK_UNDERFLOW; an invalid CALLSUB destination reports EVMC_BAD_JUMP_DESTINATION. The Advanced interpreter does not implement the instructions, as for EIP-8024. Tests: the EIP's five test cases with their gas totals, invalid destinations, JUMP/JUMPI to a CALLDEST, tail call, the 1024 limit from both sides, and pre-EIP behaviour.
This was referenced Sep 12, 2026
Draft
This file contains hidden or 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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Draft. Implements EIP-7979 (proposed for Hegotá) in the Baseline interpreter, gated on
EVMC_EXPERIMENTAL, so that compilers targeting the EIP have an EVM to test against. Solidity's IR pipeline can already emit these instructions under--evm-version @future(argotorg/solidity#17005), and its CI runs on evmone: with this change those tests can execute.The instructions
CALLSUB0xB0CALLDEST), push next position to the return stack, jumpCALLDEST0xB1JUMPDEST; also a validJUMP/JUMPIdestinationRETURNSUB0xB2Return stack limit 1024 per frame. Failures: invalid destination →
EVMC_BAD_JUMP_DESTINATION; return-stack overflow / underflow →EVMC_STACK_OVERFLOW/EVMC_STACK_UNDERFLOW.Design notes
CALLDESTpositions in the same pass as theJUMPDESTone, sharing the same allocation.CodeAnalysisis cached per code independently of revision,CALLDESTs are kept out of the jumpdest bitset.jump_implconsults theCALLDESTbitset only when theJUMPDESTtest fails and the revision has EIP-7979, so ordinary jumps are unchanged and behaviour before the EIP is byte-for-byte what it was (a jump to a0xB1byte is still a bad jump destination).std::vector<uint32_t>onExecutionState, cleared byreset(), so it is per frame by construction.op_undefined, as EIP-8024's instructions are.Tests
evm_eip7979_callsub_test.cpp: the EIP's five test cases with their gas totals (17, 34, 29), invalid destinations (JUMPDEST, PUSH data, out of range, uint64 overflow, stack underflow),JUMP/JUMPIlanding on aCALLDEST,RETURNSUBafter an unframed jump, tail call,CALLDESTby fall-through, a value returned through a subroutine, the 1024 limit from both sides (1023-deep recursion succeeds, 1024 halts), return-stack reset between executions, and pre-EIP behaviour (undefined instruction,0xB1not a jump destination). All 1285 unit tests pass.End to end
The demo contract from the Solidity PR, compiled with subroutines and run on this build with the mocked host:
compute(a, b)EVMC_EXPERIMENTAL