Files
BFM-decomp/tools/permuter/run_masked.py
T
Drew T 0abcd250ab feat(phase-24): T3 — permuter setup fixes (pins/GTE-asm, typedefs, -O0); flagship closed
- p16_permute.hide_asm: b64literal-pragma carrier for register pins + GTE __asm__ blocks.
  pycparser parses the pragma; decomp-permuter's process_pragmas decodes it back so cc1 sees
  the real pins/asm (regalloc steered, mvmva compiles). No submodule edit (reuses its own carrier).
- drop_preproc_and_scalar_typedefs: keep #define + custom struct/typedefs, drop only #include
  (fixes func_801412A8 'OTLINK undeclared'); +f32 typedef gap; make_base_c hides asm.
- compile.sh/compile_o0.sh: prepend .include "macro.inc" so GTE mvmva assembles (the real build
  gets it via include_asm.h, which base.c omits + -DPERMUTER disables). Byte-neutral for non-GTE.
  compile_o0.sh (-O0) auto-selected for _o0 targets.
- run_masked.py: expr_type->int fallback for hidden-pin vars -> 0 internal-permuter-failures
  (perm_split_assignment/perm_temp_for_expr no longer KeyError on pinned drafts).
- ALL 5 seeds parse+compile (base 4/110/36/52/77). FLAGSHIP func_80132784 (4/400) CLOSED to a
  masked-0 that match_one confirms MATCH (400 ins) -> .run/wave/func_80132784.win.c for T4 gate.
- no build-input changed (136/136 untouched)
2026-07-02 23:32:38 -06:00

41 lines
1.9 KiB
Python

#!/usr/bin/env python3
"""run_masked.py — run decomp-permuter with our floor-free relocation-masked scorer (Phase 24 T2).
Rebinds src.main.Scorer -> tools/masked_scorer.MaskedScorer BEFORE main() runs (main.py resolves the
`Scorer` global at instantiation time, line ~362), so the search scores true masked-.text closeness
(0 = reloc-masked byte match) instead of the stock mnemonic-diff floor. NO edit to the pinned
tools/decomp-permuter submodule (R3/R20) — the swap lives entirely in our layer.
Invoke exactly like tools/decomp-permuter/permuter.py:
run_masked.py <scratch_dir> -j N --stop-on-zero
"""
import os
import sys
_HERE = os.path.dirname(os.path.abspath(__file__)) # tools/permuter
_REPO = os.path.dirname(os.path.dirname(_HERE))
sys.path.insert(0, os.path.join(_REPO, "tools", "decomp-permuter")) # the `src` package
sys.path.insert(0, os.path.join(_REPO, "tools")) # masked_scorer / masked_diff
import src.main as pmain # noqa: E402
import src.ast_types as _at # noqa: E402
from masked_scorer import MaskedScorer # noqa: E402
pmain.Scorer = MaskedScorer # the drop-in swap
# Tolerate our hidden register-pin vars in the type-aware randomizer passes: a pin's declaration is
# carried in a b64literal pragma (so cc1 still binds the reg), which leaves the var absent from
# typemap.var_types -> perm_split_assignment / perm_temp_for_expr raise KeyError ("internal permuter
# failure"). Fall back to `int` for an unknown identifier so those passes MUTATE pinned drafts (the
# RC-2/RC-3 regalloc levers) instead of aborting. The whole-binary byte-gate remains the sole arbiter.
_orig_expr_type = _at.expr_type
def _pin_safe_expr_type(node, typemap):
try:
return _orig_expr_type(node, typemap)
except KeyError:
return _at.basic_type("int")
_at.expr_type = _pin_safe_expr_type
if __name__ == "__main__":
pmain.main()