mirror of
https://github.com/Druthulu/BFM-decomp
synced 2026-09-27 05:56:00 -04:00
a0cf302e5bdf426c19c6ce2eba7c8a7303514879
7 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
9ab9120e04 |
feat(phase-30 S47-B): conform 8 declaration axes (~10,930 sites); 3 guard defects fixed; 213/213
Task B, re-scoped from evidence. The 129 dedup_extend failures are 106 conflicting-types / 21 CC1-FAIL / 4 undefined-ref / 3 DIFF — real byte divergence is 2%, and memcpy is 17 of 106, not the story. Direction reversed too: the byte-true DEF of func_80128ED8 is what the target .c files already declare; engine_core.h's macro-local extern was the stub-era guess. Conformed 8 axes to byte-truth (func_8012F14C 2843, func_8012E5CC 2052, func_8012F038 2214, func_8014C568 1816, func_80128ED8 1524, func_8012C750 406, func_8012C0EC 50, func_80144A04 25). R22 clean-fleet: check-all 213 passed / 0 failed of 213. Zero functions banked by design. Tooling (R33/R35) — three guards that asserted completeness over a narrowed population: - NEW tools/macro_draft.py: a deduped fn has no definition in any .c (body lives in a DEFINE_ macro), so conform_decls had been refusing the largest class it was built for. - conform_decls skipped engine_core.h wholesale as "a defining TU": 10 stale externs survived while 1,514 fleet sites moved, and it still printed "axis complete". Skip now scoped to the defining macro's span. - Return-axis compare was literal: typedef int/s32 and a missing `extern` faked a return change. Now compares normalized types. - §85 consumer scan under-reported (the dangerous direction): a cast between `=` and the call hid `s0 = (s32 *)func_80144A04(...)`. Now classified by position, validated both ways. Corrections to my own predictions (R14): the documented scalar-narrowing hazard was benign across 2,052 sites; the breaks were arity (6 call sites, fixed with §17a-1 fn-ptr casts) and the consumer-guard gap. A header-only first probe broke ov_SC01_000 — §85 is literal. Not done, named: memcpy (builtin codegen), ApplyMatrixSV (no DEF), gte_SetRotMatrix (link bug), func_80147364 (unparseable macro), D_800AE620/D_80126CC4 (data axis). Cookbook §159. |
||
|
|
2f1aa8659d |
feat(phase-29): func_801789AC banked — conform_decls can now FIX the arity precondition it diagnoses
STUCK SINCE SESSION-21, and conform_decls was RIGHT to refuse it: the byte-true signature takes a parameter while 138 zero-arg CALL SITES exist across 138 files, so conforming the declarations alone would turn every one into `too few arguments` — a fleet-wide compile break the per-binary gate cannot see. The tool printed the exact remedy in its refusal message and could not perform it, so the function sat blocked for two sessions. NEW --cast-zero-arg-calls: cast every 0-arg call site to ((s32 (*)(void))func_801789AC)() — gcc folds the cast of a known symbol to a direct jal, so caller bytes are unchanged — then re-run the conform normally. PLAN -> VALIDATE -> WRITE like the decl axis, because a partial cast set is itself a fleet-wide compile break. Not a macro this time (unlike func_8015B950's single shared site): 138 genuine per-overlay call sites, one each. VERIFIED IN STAGES, not all at once: the 138 casts ALONE are byte-neutral (d19c9580); then the 660-site declaration conform (axis complete, 0 remaining); then the gate -> verified 1 / failed 0; then R22 clean-fleet 140 passed / 0 failed of 140. Reach 138 x 91 ins = 12,558 templated instructions unlocked for the sweep. |
||
|
|
ee55bd5cae |
feat(phase-29): func_801330E0 banked — conform_decls taught to read K&R definitions
THE GAP: conform_decls could not parse a K&R definition at all — it exited "no DEFINITION found, refusing to guess". Honest, but §43 (a narrow param declared K&R-style, producing the in-place `sll $a2,$a2,16` tell) is a documented, load-bearing idiom here for exactly the narrow-param class. So the tool was silently refusing the drafts that most need it: a whole idiom family read as "nothing to conform" (R32 coverage). THE SUBTLE PART IS PROMOTION (C89 6.3.2.2). A K&R definition promotes each narrow parameter, so a prototype in scope must declare the PROMOTED type or gcc rejects the pair with `argument 'x' doesn't match prototype`. That is why the fleet prototype reads `s32 a2` for a parameter the definition declares `s16` — and why emitting the declared (unpromoted) type would RE-CREATE the narrow-param conflict this tool exists to remove. The parser now promotes s8/u8/char/s16/u16/short -> s32 and float -> f64, pointers untouched, and reports (R32) any K&R param with no declaration. RESULT: byte-true signature read as `void func_801330E0(void *, s16 *, s32)`; the only real change vs the fleet's 973 declarations was param_1 `s16 *` -> `void *` (a pointer shape, caller-neutral). 973 sites / 973 files rewritten, axis complete. Gate: verified 1 / failed 0, d19c9580 BYTE-IDENTICAL. R22 clean-fleet 140 passed / 0 failed of 140. Reach 138 x 110 ins = 15,180 templated instructions unlocked for the family sweep. |
||
|
|
ad57c16e61 |
feat(phase-29): func_8014CF04 + func_8015D1B8 banked; conform_decls had 3 defects R22 caught (§98)
THE BANK: the T14 PLUMBING census showed func_8014CF04 blocking THREE drafts at once. Conforming its
decl axis banked func_8014CF04 + func_8015D1B8 (func_80135260 is a genuine DIFF, agreeing with its
independent SESSION-21 diagnosis). R22 clean-fleet 140/140; report fail-closed green (dedup 1886/0,
0 NON_MATCHING). fn-count 317,896 -> 317,898; distinct 66,110 -> 66,111.
BUT THE AXIS WAS A 1,748-FILE T2 WRITE SET (the --check per-form counts read "1"), and R22 came back
139/140 -- TWICE -- on a change the per-binary gate called BYTE-IDENTICAL. Three defects (§98):
1. THE REGEX CROSSED NEWLINES. `[^;]*` matches '\n', so a match starting at a DEFINITION line ran
past the `{` to the first `;`, swallowing `s32 func_8014CF04(...) {` PLUS the register pin on the
next line and replacing both with a prototype -> undefined reference. Fixed to `[^;{\n]*`: a
definition is now unmatchable by construction.
2. IT REWROTE INSIDE COMMENTS (H5, 3 lines). Now scans cdecl._mask() and rewrites by SPAN (R33 --
that length-preserving primitive already existed for exactly this).
3. THE REAL CAUSE -- IT ASSUMED ONE SIGNATURE FITS THE FLEET. ov_SC07_006 carries its own banked
definition with a DIFFERENT byte-true signature ((s32,s32,void*) vs (s32,void*,void*)), under a
decl marked "per-overlay-local decl (byte-true sig); do NOT re-macroize". That is the Phase-16
loose-typing wall inside a tool that structurally assumes it away. NEW RULE: a TU that DEFINES the
function owns its own declarations; a fleet axis is meaningful only for CONSUMING TUs. This grows
more common as banking proceeds -- every overlay that banks a function becomes an exception.
Then the R32 completion assertion cried wolf on its own by-design skip ("HALF-AXIS -- DO NOT BUILD"
for a complete rewrite): an assertion must be exact about its DOMAIN, not just its condition. Scoped
to consuming TUs -> 1,747 sites, 1 excluded by design. Also hardened to PLAN -> VALIDATE -> WRITE;
the refusal path had aborted mid-write while claiming nothing was modified, creating the very
half-axis §85 calls a guaranteed break.
META (R22's premise, re-earned): after fixing defect 1 I EXPECTED R22 to pass; it failed again for an
unrelated reason, and an individual `make build` of the failing binary SUCCEEDED by reusing objects
the clean run rebuilds. An incremental pass does not refute a clean-tree failure.
|
||
|
|
7d9dd6deca |
feat(phase-29): func_8014D820 banked (41,952 ins) + conform_decls scalar-narrowing guard
WAVE 2 (9 never-drafted exemplars, ultracode): 9/9 returned, 5 MATCH / 4 near, 2.25M tokens. BANKED: func_8014D820 (304 ins ×138) — and its agent ROOT-CAUSED the failure I left undiagnosed. It was never an assembler problem: cc1 exit 33, `conflicting types for 'Ent'` vs engine_types.h:434, surfaced by the recipe's `set -o pipefail` and MISATTRIBUTED to `as` because `as` is the last stage in the pipe (Makefile:560). Fixed by moving V4/Desc/Ent to BLOCK scope — byte-neutral and collision-proof across all 138 member TUs. Vindicates flagging it to the agent as UNVERIFIED rather than passing my own guess forward as fact (§88e). R22 clean-fleet 140/140. NEW GUARD — SCALAR NARROWING IS NOT CALLER-NEUTRAL (byte-proven, and it cost 3 gate cycles): conform_decls treated all decl type changes alike. A POINTER change is caller-neutral (func_80179B74 conformed 1,600 sites s16*/short* -> u16* and stayed byte-identical fleet-wide). A SCALAR WIDTH change is NOT: narrowing `s32 a0` -> `u16 param_1` changes argument promotion at every call site. MEASURED on func_80175DA8: decls reverted -> gate says PLUMBING; conform applied -> gate says DIFF. The conform did not fix the draft, it changed the CALLERS. Now warned explicitly (not refused — the draft's sig is still byte-truth for the callee and the gate arbitrates), with the instruction that a DIFF after this conform means examine the callers (§17a-1 pair), not the body. Verified the guard discriminates: fires on func_80175DA8 (s32->u16), silent on func_80179B74. STILL OPEN from wave 2: func_80176218 + func_80175AB8 (DATA-symbol conflicts, D_80078EB4 / D_8011F7BC -> reconcile_decls) · func_80175DA8 + func_80135EB0 (need the §17a-1 caller pair, not a bare conform) · 4 near-misses with precise residuals recorded (func_80176734 129 length-drift, func_80140958 49 inverted-hoist, func_80177B5C 19 sched tie, func_8017C974 83 -> permuter). |
||
|
|
e721452526 |
feat(phase-29): 3 more exemplars banked + 3 family sweeps; conform_decls extern-optional fix
BANKED: func_8015B950 (271 ins) · func_8016AE5C (85) · func_80179B74 (111).
SWEPT: func_8015B950 137/137 · func_8016AE5C 136/137 (ov_SC03_108 refused, left a stub rather than
forced). Three full family sweeps this session, all unblocked by the --like role guard.
FLEET 82.4% instr · 70.4% distinct-code (crossed 70%) · 89.72% fn-count. R22 140/140 throughout.
conform_decls has now been right in BOTH directions: it REFUSED func_8015B950 (which by hand broke
138 binaries) and CLEARED func_80179B74 (1,600 sites / 523 files, three decl forms, pointer-type
only). Then it found its OWN coverage gap: it required a leading `extern`, so it reported "no
declaration found" for a TU declaring the function on line 23 without one — a silent miss that reads
exactly like "nothing to do" (R32). `extern` is now optional and PRESERVED where present.
⚠️ INSTRUMENT FAILURE, recorded: mid-session `grep <pat> <file> | head` began printing NOTHING while
exiting rc=0 (i.e. matching). Read showed the line plainly; re-done in Python the file has 3
occurrences including a CALL at line 68. It cost one wrong intermediate claim ("no extern anywhere"),
which conform_decls immediately contradicted. NO banked result is affected — every bank passed the
whole-binary byte-gate and a clean-tree R22, neither of which reads shell output. A broken diagnostic
wastes time; it cannot manufacture a match. Diagnostics moved to Python. §90a, aimed at the shell.
func_8013BD74 is NOT a wall: its byte-true def takes a draft-LOCAL struct `A`, conforming the
prototype fails `parse error before '*'` (A undeclared that early), and the prototype cannot be
deleted because a call at line 68 precedes the definition at 71. Needs the §20/§64 type-lift.
|
||
|
|
7c1640888f |
feat(phase-29): func_8016AE5C banked + tools/conform_decls.py; a 138-binary break R22 caught
BANKED: func_8016AE5C (85 ins ×138). R22 clean-fleet 140/140.
⚠️ I BROKE 138 OF 140 BINARIES AND R22 CAUGHT IT — the per-binary gate could not.
Conforming func_8015B950's decl from `(void)` to its byte-true `(s32 arg0)` across 926 sites gated
BYTE-IDENTICAL on ov_SC01_077 and broke 138 other binaries with Error 33. §63/§85 exactly: a T2
write set is provable only by R22, and the binary the gate authorises is not the binary that breaks.
MECHANISM: conforming a decl to a signature that TAKES parameters makes every existing 0-ARG CALL
SITE a hard `too few arguments` error once a prototype is in scope. Not a declaration-only change.
PROCESS NOTE (mine): a first R22 reported 138 failures, an individual rebuild of a "failing" binary
said BYTE-IDENTICAL, and I nearly filed it as a flake. The second clean R22 reproduced it exactly —
the individual build passed only by reusing objects the clean run rebuilds. An incremental pass does
not refute a clean-tree failure; that is R22's whole premise, pointed at me. Reverted to a known-good
baseline (a stray jr_isolate region file was also in the tree) and redid the one good bank cleanly.
NEW tools/conform_decls.py — because applying this axis by hand three times in one session is how a
half-axis happens. Derives the byte-true signature from the DRAFT's definition (§58b), rewrites EVERY
site, asserts completion (R32). Encodes both preconditions: the §85 return axis (refuse if any caller
consumes the return) and a NEW arity precondition (refuse if 0-arg call sites exist, naming the cost).
The guard immediately gave a better diagnosis than my hand-fix had: func_8015B950's 0-arg call is in
ONE place — src/shared/engine_core.h, a DEFINE macro body — expanded into all 926 TUs. That fix is a
SINGLE cast, not 926 edits. Named as the next step rather than run on tired context.
Also lands cookbook §91 (the --like role trap) from the previous step.
|