Skip to content

fix(evm): preserve CALL operand provenance with logical stack in low revision#502

Open
starwarfan wants to merge 7 commits into
DTVMStack:mainfrom
starwarfan:pr-500
Open

fix(evm): preserve CALL operand provenance with logical stack in low revision#502
starwarfan wants to merge 7 commits into
DTVMStack:mainfrom
starwarfan:pr-500

Conversation

@starwarfan
Copy link
Copy Markdown
Contributor

1. Does this PR affect any open issues?(Y/N) and add issue references (e.g. "fix #123", "re #123".):

  • N
  • Y

2. What is the scope of this PR (e.g. component or file name):

3. Provide a description of the PR(e.g. more details, effects, motivations or doc link):

  • Affects user behaviors
  • Contains CI/CD configuration changes
  • Contains documentation changes
  • Contains experimental features
  • Performance regression: Consumes more CPU
  • Performance regression: Consumes more Memory
  • Other

4. Are there any breaking changes?(Y/N) and describe the breaking changes(e.g. more details, motivations or doc link):

  • N
  • Y

5. Are there test cases for these changes?(Y/N) select and add more details, references or doc links:

  • Unit test
  • Integration test
  • Benchmark (add benchmark stats below)
  • Manual test (add detailed scripts or steps below)
  • Other

6. Release note

None

starwarfan and others added 7 commits May 14, 2026 02:41
- Fix EVMCallThreadState::setJITTraces inverted Inst guard (was no-op for all
  real instances); align trap backtrace behavior with the WASM handler pattern.
- Harden SAVE_EVM_HOSTAPI_FRAME_POINTER_TO_TLS with a do/while wrapper and
  assert an active TLS before UD2-based JIT traps; add required semicolon at
  the throwInstanceExceptionOnJIT call site.
- dt_evmc_vm: per-VM recursive_mutex around execute(), clear per-instance message
  cache on top-level entry, empty-code CALL fast paths for multipass JIT, and
  default DisableMultipassGreedyRA with DTVM_EVM_DISABLE_MULTIPASS_GREEDYRA
  override.
- Execution cache / CREATE path hardening (evm_cache, evm_instance, evm_imported)
  from Silkworm integration stress testing.

Validated: cmake --build build --target dtvmapi; multipass staged_pipeline
forward past former crash block on mainnet snapshot data.
Legacy pre-Tangerine revisions can lose deep stack operands when lifted logical stack materialization is used, which zeros CALL-family arguments and undercharges gas. Route legacy stack operations through runtime stack access and add regression coverage so multipass matches interpreter gas on known failing blocks.
Add env-gated lifted-stack diagnostics across visitor, MIR lowering, and runtime call helper to trace logical stack materialization and CALL-family argument propagation. Extend frontend tests with a modern deep-merge DUP/SWAP->CALL regression and document why the legacy runtime-stack path test fails when fallback branches are removed.
…ions

Add a runtime-backed state regression that executes the same CALL-heavy bytecode in interpreter and multipass for Frontier, Tangerine Whistle, and Cancun, asserting revision-expected account-creation gas deltas and mode parity of those deltas.
…revisions

Remove the revision-based logical stack bypass so low revisions keep the same stack model, and make deep DUP/SWAP fallback logic provenance-safe when logical depth is insufficient. Add low-revision frontend regression coverage around merge+deep DUP/SWAP CALL lowering so account-creation gas behavior remains parity-stable across interpreter and multipass.

Co-authored-by: Cursor <cursoragent@cursor.com>
@starwarfan starwarfan marked this pull request as ready for review May 14, 2026 03:19
@github-actions
Copy link
Copy Markdown

⚡ Performance Regression Check Results

⚠️ Performance Regression Detected (interpreter)

No benchmark summary available.


⚠️ Performance Regression Detected (multipass)

No benchmark summary available.


Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR addresses a legacy EVM multipass CALL operand-provenance regression by preserving logical stack operands through DUP/SWAP and CALL-family lowering, with added regression coverage and repro notes.

Changes:

  • Updates multipass CALL lowering to pass the full 256-bit address operand into runtime helpers.
  • Adjusts logical-stack DUP/SWAP handling and adds CALL operand provenance regression tests.
  • Adds VM/runtime cache, execution serialization, debug logging, and legacy repro documentation/fixtures.

Reviewed changes

Copilot reviewed 17 out of 17 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
tests/evm/fixtures/legacy_multipass_call/legacy_call_gas_cases.json Adds reference legacy CALL gas replay cases.
src/vm/dt_evmc_vm.cpp Adds execution locking, empty-code handling, cache clearing, and greedy RA env defaulting.
src/utils/logging.h Adds standard includes required by logging helpers.
src/tests/evm_jit_frontend_tests.cpp Extends mock builder and adds DUP/SWAP/CALL provenance tests.
src/tests/evm_interp_tests.cpp Adds gas accounting helpers and cross-mode CALL gas regression coverage.
src/runtime/evm_instance.h Changes execution-cache containers and adds CREATE address caching.
src/runtime/evm_instance.cpp Fixes trap-handler macro invocation syntax.
src/platform/platform.h Adds standard C I/O include.
src/evm/opcode_handlers.cpp Adds optional CALL provenance debug logging.
src/evm/evm_cache.cpp Adds defensive bounds checks in gas CFG analysis.
src/compiler/evm_frontend/evm_mir_compiler.cpp Updates CALL-family runtime-call signatures and debug logging.
src/compiler/evm_frontend/evm_imported.h Updates imported CALL helper type declarations.
src/compiler/evm_frontend/evm_imported.cpp Updates CALL helper address handling and CREATE address return caching.
src/common/evm_traphandler.h Wraps trap-frame save macro in a safe do/while block.
src/common/evm_traphandler.cpp Adjusts EVM signal-handler behavior.
src/action/evm_bytecode_visitor.h Preserves logical/runtime stack operands through DUP/SWAP and CALL lowering.
docs/legacy_multipass_call_repro.md Documents legacy CALL gas reproduction cases and commands.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +1018 to 1021
.code_address = TargetAddr,
.code = nullptr,
.code_size = 0,
};
Comment on lines +164 to +166
std::list<evmc::bytes32> ExtcodeHashes;
std::list<evmc::bytes32> Keccak256Results;
std::list<evmc::bytes32> CreateAddresses;
Comment on lines +161 to +163
// Use std::list (not std::deque) for values whose .bytes pointers are
// returned to JIT and may outlive further push_back calls; deque can
// reallocate and invalidate earlier element addresses.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants