Merged
Conversation
Fix multiple interacting bugs that caused stack underflow when calling user-defined functions: - Move copy-based read scratch from 0x60 to 0x00 to avoid collision with function call return PC storage - Track call terminator arguments and continuations in liveness analysis so values get memory allocations - Clean caller stack before setting up call arguments - Reset state stack tracking after call to match runtime - Insert STOP guard between main function and user functions to prevent fall-through - Spill call return values to memory at continuation blocks - Defer block/continuation jump patching for user functions to module level where absolute offsets are known - Save return PC to per-function memory slot in prologue so nested calls don't clobber it via 0x60 - Stagger memory allocations across functions so callee frames don't overlap with caller frames
Contributor
|
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.
Summary
Changes
Fixes addressed 8 separate issues in the EVMGen pipeline:
Scratch memory collision: copy-based reads (RETURNDATACOPY/CODECOPY) used 0x60 as scratch, same slot as function call return PC. Moved to 0x00 (Solidity scratch space 1).
Liveness analysis gaps: call terminator arguments and continuation blocks weren't tracked, so values needed for calls didn't get memory allocations.
Stack cleanup before calls: caller stack had leftover values from DUP-based loadValue. Added POP-all cleanup before loading call arguments from memory.
State stack tracking: after call terminator, state stack still tracked loaded arguments instead of reflecting runtime (function consumes args, returns value).
Fall-through into user functions: the
isLastBlockoptimization skipped STOP for void returns, but user functions are appended immediately after. Added STOP guard byte.Return value spilling: call return values weren't stored to memory, so subsequent call terminators lost them during stack cleanup. Added DUP+MSTORE at continuation blocks.
Relative jump targets: block/continuation patches within user functions used offsets relative to function start, but EVM JUMP needs absolute PC values. Deferred patching to module level where base offsets are known.
Return PC clobbering: nested function calls overwrote memory[0x60] with their own return PC. Added per-function
savedReturnPcOffsetin prologue and staggered memory allocations across functions.