Skip to content

feat(vm): add canonical basic-block frontend - #730

Open
Jon-Becker wants to merge 2 commits into
mainfrom
feat/canonical-basic-block-cfg
Open

feat(vm): add canonical basic-block frontend#730
Jon-Becker wants to merge 2 commits into
mainfrom
feat/canonical-basic-block-cfg

Conversation

@Jon-Becker

Copy link
Copy Markdown
Owner

What changed? Why?

Adds an execution-independent EVM program frontend as the first foundation for improving CFG and decompilation accuracy.

The new heimdall_vm::core::program module:

  • decodes bytecode once while keeping PUSH immediates out of the instruction stream
  • preserves and right-pads truncated PUSH operands according to EVM code-reading semantics
  • partitions instructions into canonical basic blocks at JUMPDEST, control-transfer, halt, and invalid-opcode boundaries
  • classifies block terminators
  • records statically-known fallthrough, conditional-false, and locally constant jump edges
  • validates constant jump targets against real decoded JUMPDEST instructions
  • deliberately leaves dynamic targets unresolved for a later abstract/symbolic value-flow pass

The disassembler now consumes this shared decoder instead of maintaining a second instruction-boundary implementation. This gives later CFG/worklist analysis a single structural representation to build on without changing the existing symbolic executor in this PR.

Notes to reviewers

Key files:

  • crates/vm/src/core/program.rs: decoded program, blocks, terminators, static edge skeleton, and focused tests
  • crates/vm/src/core/mod.rs: exports the frontend
  • crates/disassemble/src/core/mod.rs: adopts the shared decoder

This PR intentionally does not route dynamic CFG discovery through the new representation yet. Doing so safely requires the subsequent abstract-state/worklist analysis; forcing the current recursive executor to split at every unconditional jump reduced coverage because its global jump deduplication is not continuation-sensitive.

How has it been tested?

  • cargo +nightly fmt --check --all
  • cargo clippy -p heimdall-vm -p heimdall-disassembler --all-features -- --allow clippy::new_without_default --allow clippy::redundant_field_names --allow clippy::too_many_arguments --allow clippy::format_in_format_args --allow clippy::should_implement_trait
  • cargo test --workspace --lib --tests
  • Added six unit tests covering PUSH-data decoding, canonical boundaries, direct and unresolved conditional targets, truncated PUSH semantics, and hardfork-inactive opcodes.

@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

AI Evaluation Suite

Check the box below to run the heimdall-eval AI evaluation suite.

  • Run AI Evaluation Suite

@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

✅ Coverage Report for fefa83f

Metric Value
Base branch 70.88%
PR branch 71.27%
Diff +0.39%

@Jon-Becker
Jon-Becker force-pushed the feat/canonical-basic-block-cfg branch from 43a4944 to 0e7ab3a Compare September 6, 2026 23:40
@github-actions

github-actions Bot commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

Benchmark for fefa83f

Click to view benchmark
Test Base PR %
heimdall_cfg/complex 15.0±1.07ms 15.4±1.24ms +2.67%
heimdall_cfg/simple 1399.1±6.75µs 1396.9±38.50µs -0.16%
heimdall_decoder/seaport 57.3±2.25µs 57.6±2.65µs +0.52%
heimdall_decoder/transfer 4.0±0.38µs 4.0±0.35µs 0.00%
heimdall_decoder/uniswap 15.9±0.98µs 15.6±0.67µs -1.89%
heimdall_decompiler/abi_complex 59.7±2.44ms 54.9±0.39ms -8.04%
heimdall_decompiler/abi_simple 1493.5±24.24µs 1507.2±26.50µs +0.92%
heimdall_decompiler/sol_complex 76.9±1.37ms 75.3±1.77ms -2.08%
heimdall_decompiler/sol_simple 1933.2±19.66µs 1954.7±24.30µs +1.11%
heimdall_decompiler/yul_complex 66.0±1.31ms 64.4±1.75ms -2.42%
heimdall_decompiler/yul_simple 1692.3±10.52µs 1710.5±8.36µs +1.08%
heimdall_disassembler/complex 1254.1±34.46µs 1509.3±30.74µs +20.35%
heimdall_disassembler/simple 61.9±4.66µs 72.1±3.97µs +16.48%
heimdall_vm/erc20_transfer 267.7±6.95µs 270.0±12.97µs +0.86%
heimdall_vm/fib 852.8±11.00µs 848.3±17.95µs -0.53%
heimdall_vm/ten_thousand_hashes 720.0±12.99ms 694.0±9.21ms -3.61%

📊 View the full Criterion report

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.

1 participant