Thanks for the feedback @SamWilsn. Things have changed a bit since this merge and it will be a few days before the new version is ready. Your points are well taken and I’ll try to incorporate them.
It feels like ENTERSUB behaving as a JUMPDEST just complicates static analysis, and I’m not sure the Rationale’s note does a good enough job explaining why that is desired behaviour:
At this point the core validation function is less than 100 lines of Python, so complexity isn’t an issue, but conceptual clarity is.
The ability to jump into subroutines when it is safe to do so is essential to important optimizations, and the newest Rationale is specific about that:
A JUMP to an ENTERSUB enters the subroutine without pushing a return address: where a CALLSUB would be the last action before a RETURNSUB, the jump does the same work and the call is eliminated. Call elimination supports tail recursion, mutual recursion and state machines, shared epilogues, and the outlining of repeated code — the transformations optimizing compilers rely on.
[…] an ENTERSUB marks an entry, where the baseline resets and a jump eliminates a call. Without the distinction, the validator could not tell a merge from an entrance.
If someone wants to allow jumps and subroutines to the same “place”, then they could do a JUMPDEST followed by an ENTERSUB, making the added analysis complexity more visible.
They could, but this amounts to de-optimizing an optimization.
The mnemonic ENTERSUB is a verb, when the actual behaviour is more a place/label. JUMPDESTis a noun.
I’d recommend naming it SUBROUTINE (or some contraction) instead because that doesn’t imply taking an action.
Good point. SUBROUTINE doesn’t seem right, as it obscures the fact that subroutines need not be contiguous stretches of code and can have multiple entry points, and doesn’t make clear that it marks a destination.
CALLDEST might be good. Makes clear that it’s the same sort of label as a JUMPDEST, so it’s less surprising that you can only jump to a JUMPDEST, but you can call or jump to a CALLDEST.
Having a third CALLORJUMPDEST or such would be a mistake – nothing different happens at the CALLDEST site when you jump to it rather than call it, so it shouldn’t need to be changed just because some caller decided to optimize a call to a jump. It’s the validators job to tell whether the optimization is safe.