From 36bd599287c39f7b0600b946292d8bf91ad22829 Mon Sep 17 00:00:00 2001 From: Jon-Becker Date: Sun, 6 Sep 2026 16:11:16 -0500 Subject: [PATCH] feat(decompile): retain canonical SSA sidecar --- crates/decompile/src/core/canonical.rs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/crates/decompile/src/core/canonical.rs b/crates/decompile/src/core/canonical.rs index 9261581c..ef43f9f9 100644 --- a/crates/decompile/src/core/canonical.rs +++ b/crates/decompile/src/core/canonical.rs @@ -7,6 +7,7 @@ use heimdall_vm::core::{ context::{analyze_contextual, ContextualCfg, ContextualPoint}, hardfork::HardFork, program::{BlockId, Program}, + ssa::{build_contextual_ssa, ContextualSsa}, }; /// Existing selector discovery mapped onto canonical basic blocks. @@ -28,6 +29,8 @@ pub struct CanonicalAnalysis { pub program: Program, /// Context-sensitive abstract CFG, including all uncertainty diagnostics. pub cfg: ContextualCfg, + /// Contextual stack SSA and effect operands derived from `cfg`. + pub ssa: ContextualSsa, /// Legacy-discovered selectors annotated with canonical entry blocks. pub function_entries: BTreeMap, } @@ -47,6 +50,7 @@ pub(crate) fn build_canonical_analysis( ) -> CanonicalAnalysis { let program = Program::decode(bytecode, hardfork); let cfg = analyze_contextual(&program); + let ssa = build_contextual_ssa(&cfg); let function_entries = selectors .iter() .map(|(selector, &entry_pc)| { @@ -57,7 +61,7 @@ pub(crate) fn build_canonical_analysis( (selector.clone(), CanonicalFunctionEntry { entry_pc, block }) }) .collect(); - CanonicalAnalysis { program, cfg, function_entries } + CanonicalAnalysis { program, cfg, ssa, function_entries } } #[cfg(test)] @@ -97,5 +101,13 @@ mod tests { assert!(!analysis.cfg.expressions.is_empty()); assert!(analysis.cfg.state_versions.version_count() > 3); assert_eq!(analysis.cfg.exit_states.len(), analysis.cfg.entry_states.len()); + assert_eq!(analysis.ssa.blocks.len(), analysis.cfg.entry_states.len()); + assert!(analysis + .ssa + .blocks + .values() + .flat_map(|block| &block.effects) + .any(|effect| effect.kind == + heimdall_vm::core::analysis::InstructionEffectKind::StorageWrite)); } }