Skip to content

feat(decompiler): wire cooperative analysis budget into flow_analysis (#35-3b)#233

Merged
CryptoJones merged 1 commit into
masterfrom
feat/rec35-3b-flow-budget
Jun 1, 2026
Merged

feat(decompiler): wire cooperative analysis budget into flow_analysis (#35-3b)#233
CryptoJones merged 1 commit into
masterfrom
feat/rec35-3b-flow-budget

Conversation

@CryptoJones
Copy link
Copy Markdown
Owner

Closes #232.

Summary

Wires the DecompileBudgetTracker (shipped inert in #35-3a) into the flow_analysis yield point. Each processed instruction counts as one per-pass iteration; when the budget is engaged and the per-pass cap is reached, flow truncates exactly as the existing max-instruction cap does (artificial HALT, no fall-through) and records a one-time partial-result diagnostic (Exceeded decompilation budget: Some flow is truncated).

A new console option decompilebudget <N> engages the tracker with an N-iteration per-pass cap. Architecture gains an inert DecompileBudgetTracker member — nothing in production engages it, so the disengaged default adds only a single bool test per instruction and leaves every existing decompile byte-identical.

Incidental fix

The new option surfaced an ElementId id collision: decompilebudget was assigned id 289, already held by ELEM_BITFIELD, so the console option lookup dispatched to the wrong optionmap entry and silently never engaged the budget. Reassigned decompilebudget to 290 (the prior next-open index) and bumped ELEM_UNKNOWN's sentinel to 291.

Test plan

  • make decomp_test_dbg — clean build, no warnings
  • ./decomp_test_dbg unittests — 315/315 (incl. new budget_engage_and_caps_survive_reset)
  • ./decomp_test_dbg datatests — 678/678 (incl. new decompbudget)
  • gradle cppRaiiAudit — 229 protected files clean
  • gradle :Decompiler:ip — green (new datatests/decompbudget.xml manifest entry)

Proudly Made in Nebraska. Go Big Red! 🌽 https://xkcd.com/2347/

…#35-3b)

Consult the DecompileBudgetTracker (shipped inert in #35-3a) at the
flow-following yield point. Each processed instruction counts as one
per-pass iteration; when the budget is engaged and the per-pass cap is
reached, flow truncates exactly as the existing max-instruction cap does
(artificial HALT, no fall-through) and records a one-time partial-result
diagnostic ("Exceeded decompilation budget: Some flow is truncated").

A new console option `decompilebudget <N>` engages the tracker with an
N-iteration per-pass cap. Architecture gains an inert DecompileBudgetTracker
member that nothing in production engages, so the disengaged default costs a
single bool test per instruction and leaves every existing decompile
byte-identical (full 678-case datatest suite stays green).

Also fixes an ElementId id collision the new option surfaced: decompilebudget
was assigned id 289, already held by ELEM_BITFIELD, so the console `option`
lookup dispatched to the wrong optionmap entry and never engaged the budget.
Reassigned decompilebudget to 290 (the prior next-open index) and bumped
ELEM_UNKNOWN's sentinel to 291.

Tests: new functional datatest datatests/decompbudget.xml asserts the
truncation warning header end-to-end; new testbudget.cc case
budget_engage_and_caps_survive_reset pins that engage()/caps survive a
per-function reset(). certification.manifest gains the datatest entry.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@CryptoJones CryptoJones merged commit 4cc832b into master Jun 1, 2026
16 checks passed
@CryptoJones CryptoJones deleted the feat/rec35-3b-flow-budget branch June 1, 2026 13:06
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.

Rec 35 #35-3b: wire cooperative analysis budget into flow_analysis

1 participant