From e112eff601297c22e4702be0f236ae82a3e65290 Mon Sep 17 00:00:00 2001 From: Drew T <50529377+Druthulu@users.noreply.github.com> Date: Sat, 25 Jul 2026 00:17:08 -0600 Subject: [PATCH] =?UTF-8?q?fix(phase-29):=20find=5Fsite=20=E2=80=94=20a=20?= =?UTF-8?q?comment-only=20line=20halted=20the=20extern=20scan=20(=C2=A768)?= =?UTF-8?q?;=20func=5F80174CB0=20x1=20->=20x3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit TWO mislabels in one tool, both found by making it print what the compiler actually said. 1) compiles_standalone() returned a bare False and the caller filed EVERY failure under "overlay-local TYPE (the real cap)". The dominant real cause is undeclared FILE-SCOPE EXTERNS. Now returns (ok, stderr) and the skip is classified by actual cc1 output. 2) find_site()'s backward walk over "preceding contiguous externs" skipped BLANK lines but not COMMENT-ONLY lines, so a full-line /* ---- */ between two extern groups dropped every extern above it. Comment lines are now skipped like blanks and filtered out of the emitted body so make_macro never meets a `//`. RESULT, measured honestly: func_80174CB0 went from "not self-contained" to a 138-member PLAN, but --recover banked only x3 (ov_SC07_006/007/011); 135 overlays excluded. Those exclusions are NOT byte divergence (all 138 share h_exact) -- they are the CARRIED EXTERNS colliding with each target overlay's own decls. The carry is necessary but not sufficient: it must reconcile per-target-TU (cdecl.compatible(), the shape reconcile_tu already uses). Spec updated in CURRENT_PHASE.md. - R22 clean-fleet 140/140, 0 failed. dedup-check 1883 validated / 0 failed, C1 coverage complete. - fleet instr 79.9% (10,501,384 / 13,141,652); +246 ins from the x3. - WHY THIS MATTERS beyond the numbers: the Phase-21 backlog already prescribed "macro-extern- injection frees them x134 (~+0.3%)" and it was never built, because the mislabel told every later session these were the known-hard type wall. A wrong diagnostic label cost ~4 phases. - cookbook §68. NOTE the exclusion message is ALSO mislabelled ("byte-diverge / irreconcilable" conflates differing bytes with a non-compiling instantiation) -- logged to fix. --- config/dedup.us.yaml | 7 +++ docs/progress.fleet.md | 16 +++---- src/ov_SC07_006/ov_SC07_006_jr_8015C32C.c | 52 +---------------------- src/ov_SC07_007/ov_SC07_007_jr_8015C32C.c | 2 +- src/ov_SC07_011/ov_SC07_011_jr_8015C32C.c | 2 +- src/shared/engine_core.h | 44 +++++++++++++++++++ tools/dedup_propagate.py | 17 ++++++-- 7 files changed, 76 insertions(+), 64 deletions(-) diff --git a/config/dedup.us.yaml b/config/dedup.us.yaml index 237a47d76..d8ff391f0 100644 --- a/config/dedup.us.yaml +++ b/config/dedup.us.yaml @@ -13298,3 +13298,10 @@ groups: func: DEFINE_func_80169228 vram: 0x80169228 binaries: [ov_SC01_077, ov_SC01_005, ov_SC01_006, ov_SC03_001, ov_SC01_000, ov_SC01_001, ov_SC02_000, ov_SC02_003, ov_SC03_002, ov_SC03_006, ov_SC04_000, ov_SC04_018, ov_SC04_019, ov_SC05_000, ov_SC06_000, ov_SC07_000, ov_SC01_004, ov_SC01_008, ov_SC01_009, ov_SC01_074, ov_SC01_080, ov_SC01_084, ov_SC02_004, ov_SC02_005, ov_SC02_011, ov_SC02_015, ov_SC02_016, ov_SC02_017, ov_SC02_021, ov_SC02_026, ov_SC02_027, ov_SC02_028, ov_SC02_031, ov_SC02_035, ov_SC02_039, ov_SC02_041, ov_SC03_003, ov_SC03_007, ov_SC03_010, ov_SC03_011, ov_SC03_012, ov_SC03_013, ov_SC03_014, ov_SC03_015, ov_SC03_023, ov_SC03_024, ov_SC03_028, ov_SC03_029, ov_SC03_030, ov_SC03_031, ov_SC03_089, ov_SC03_090, ov_SC03_091, ov_SC03_092, ov_SC03_093, ov_SC03_094, ov_SC03_095, ov_SC03_096, ov_SC03_097, ov_SC03_098, ov_SC03_099, ov_SC03_100, ov_SC03_101, ov_SC03_102, ov_SC03_103, ov_SC03_104, ov_SC03_105, ov_SC03_108, ov_SC03_109, ov_SC03_110, ov_SC03_111, ov_SC03_112, ov_SC03_113, ov_SC03_114, ov_SC03_115, ov_SC03_116, ov_SC03_117, ov_SC03_118, ov_SC03_119, ov_SC03_121, ov_SC03_124, ov_SC03_125, ov_SC03_126, ov_SC04_002, ov_SC04_003, ov_SC04_004, ov_SC04_005, ov_SC04_006, ov_SC04_007, ov_SC04_008, ov_SC04_009, ov_SC04_010, ov_SC04_011, ov_SC04_012, ov_SC04_015, ov_SC04_016, ov_SC04_020, ov_SC04_021, ov_SC05_001, ov_SC05_002, ov_SC05_003, ov_SC05_004, ov_SC05_005, ov_SC05_006, ov_SC05_007, ov_SC05_008, ov_SC05_009, ov_SC05_010, ov_SC05_011, ov_SC05_017, ov_SC05_018, ov_SC05_019, ov_SC06_006, ov_SC06_008, ov_SC06_010, ov_SC06_011, ov_SC06_013, ov_SC06_014, ov_SC06_015, ov_SC06_016, ov_SC06_018, ov_SC06_020, ov_SC06_022, ov_SC06_024, ov_SC06_025, ov_SC06_027, ov_SC06_029, ov_SC06_030, ov_SC06_032, ov_SC06_033, ov_SC07_001, ov_SC07_002, ov_SC07_008, ov_SC07_009, ov_SC07_006, ov_SC07_007, ov_SC07_010, ov_SC07_011] + - id: E_func_80174CB0 + tier: h_exact + hash: 5fd1ad0684401984d032eb95861c100cf110768a + source: src/shared/engine_core.h + func: DEFINE_func_80174CB0 + vram: 0x80174CB0 + binaries: [ov_SC07_006, ov_SC07_007, ov_SC07_011] diff --git a/docs/progress.fleet.md b/docs/progress.fleet.md index b9e63628d..e45c69f5e 100644 --- a/docs/progress.fleet.md +++ b/docs/progress.fleet.md @@ -4,16 +4,16 @@ # cross-binary collapsible-byte leverage: docs/duplicates.cross.md. # THREE progress metrics (all matter — see the labels): -FLEET fn-count byte-ident: 314726 / 353717 = 88.98% (REAL+LINKED+empties; FUNCTION-count, ×134-inflated — one crack counts per overlay) -FLEET instr-weighted : 10501138 / 13141652 = 79.9% (shipped .text across main + resident + 138 overlays; the decomp.dev-DISPLAY number) +FLEET fn-count byte-ident: 314728 / 353717 = 88.98% (REAL+LINKED+empties; FUNCTION-count, ×134-inflated — one crack counts per overlay) +FLEET instr-weighted : 10501384 / 13141652 = 79.9% (shipped .text across main + resident + 138 overlays; the decomp.dev-DISPLAY number) FLEET distinct-code(uniq): 3813337 / 5634875 = 67.7% (64876/87459 unique fns; the DISTINCT-RE number) MAIN game-code weighted : 436 / 60201 = 0.7% (INCLUDED in the fleet numbers above since 2026-07-22 — roadmap §1 metrics contract; LINKED-excluding Ghidra sig dated 2026-06-14; caveat is R34: no independent second oracle for a PS-X EXE, NOT drift) - (fleet EXCLUDING main, for continuity with pre-2026-07-22 readings: 10500702 / 13081451 = 80.3%) + (fleet EXCLUDING main, for continuity with pre-2026-07-22 readings: 10500948 / 13081451 = 80.3%) -FLEET REAL substantive : 312871 (of which dedup-shared 238824 via 1882 groups / 238898 instances) +FLEET REAL substantive : 312873 (of which dedup-shared 238827 via 1883 groups / 238901 instances) FLEET LINKED PsyQ objs : 959 FLEET NON_MATCHING : 7 (0 in any default build — G4) -FLEET INCLUDE_ASM stubs : 38984 +FLEET INCLUDE_ASM stubs : 38982 FLEET matchable : 353717 | binary | REAL | shared | LINKED | byte-ident | matchable | byte-ident % | @@ -152,9 +152,9 @@ FLEET matchable : 353717 | ov_SC07_000 | 2266 | 1737 | 0 | 2268 | 2521 | 90.0% | | ov_SC07_001 | 2249 | 1733 | 0 | 2251 | 2454 | 91.7% | | ov_SC07_002 | 2277 | 1733 | 0 | 2281 | 2579 | 88.4% | -| ov_SC07_006 | 2047 | 1551 | 0 | 2127 | 2455 | 86.6% | -| ov_SC07_007 | 2037 | 1581 | 0 | 2121 | 2613 | 81.2% | +| ov_SC07_006 | 2047 | 1552 | 0 | 2127 | 2455 | 86.6% | +| ov_SC07_007 | 2038 | 1582 | 0 | 2122 | 2613 | 81.2% | | ov_SC07_008 | 2234 | 1733 | 0 | 2234 | 2386 | 93.6% | | ov_SC07_009 | 2243 | 1733 | 0 | 2245 | 2430 | 92.4% | | ov_SC07_010 | 2046 | 1581 | 0 | 2129 | 2524 | 84.4% | -| ov_SC07_011 | 2036 | 1580 | 0 | 2116 | 2449 | 86.4% | +| ov_SC07_011 | 2037 | 1581 | 0 | 2117 | 2449 | 86.4% | diff --git a/src/ov_SC07_006/ov_SC07_006_jr_8015C32C.c b/src/ov_SC07_006/ov_SC07_006_jr_8015C32C.c index 2132418ba..d155c6d93 100644 --- a/src/ov_SC07_006/ov_SC07_006_jr_8015C32C.c +++ b/src/ov_SC07_006/ov_SC07_006_jr_8015C32C.c @@ -8746,57 +8746,7 @@ DEFINE_func_80174C80() /* dedup: shared engine-core @0x80174c80 (src/shared) */ /* --- standalone-only scaffolding (bank-safe: names are unique to this function) --- */ -extern s16 D_80126940; -extern s16 D_80126942; -extern s16 D_80126944; -/* -------------------------------------------------------------------------------- */ - -extern s32 func_80012ABC(s32 a0, s32 a1, s32 a2); -extern s32 func_80012C6C(s32 a0, s32 a1, s32 a2); -extern void func_80013F3C(s32 a0); -extern void func_800123F0(s32 a0, s32 a1); -extern void func_80012558(s32 a0, s32 a1); -extern void func_800126C4(s32 a0, s32 a1); -extern void func_8012F14C(s32 a0, s32 a1, s32 a2); - -s32 func_80174CB0(s32 param_1, s32 param_2) -{ - s16 *pv = &D_80126940; - MATRIX mtx; - SVECTOR vec; - SVECTOR out; - - *(s32 *)(param_1 + 8) = (s16)((s16 (*)(s32, s32, s32))func_80012C6C)((s32)*(s16 *)(param_1 + 8), (s32)*(s16 *)(param_1 + 0xc), 4); - *(s32 *)(param_1 + 0x10) = (s16)((s16 (*)(s32, s32, s32))func_80012C6C)((s32)*(s16 *)(param_1 + 0x10), (s32)*(s16 *)(param_1 + 0x14), 4); - *(s16 *)(param_1 + 0x18) = ((s16 (*)(s32, s32, s32))func_80012ABC)((s32)*(s16 *)(param_1 + 0x18), (s32)*(s16 *)(param_1 + 0x20), 4); - *(s16 *)(param_1 + 0x1a) = ((s16 (*)(s32, s32, s32))func_80012ABC)((s32)*(s16 *)(param_1 + 0x1a), (s32)*(s16 *)(param_1 + 0x22), 4); - *(s16 *)(param_1 + 0x1c) = ((s16 (*)(s32, s32, s32))func_80012ABC)((s32)*(s16 *)(param_1 + 0x1c), (s32)*(s16 *)(param_1 + 0x24), 4); - *(s16 *)(param_1 + 0x28) = ((s16 (*)(s32, s32, s32))func_80012C6C)((s32)*(s16 *)(param_1 + 0x28), (s32)*(s16 *)(param_1 + 0x2e), 0x10); - *(s16 *)(param_1 + 0x2a) = ((s16 (*)(s32, s32, s32))func_80012C6C)((s32)*(s16 *)(param_1 + 0x2a), (s32)*(s16 *)(param_1 + 0x30), 0x10); - *(s16 *)(param_1 + 0x2c) = ((s16 (*)(s32, s32, s32))func_80012C6C)((s32)*(s16 *)(param_1 + 0x2c), (s32)*(s16 *)(param_1 + 0x32), 0x10); - - *(s32 *)(param_1 + 0x48) = (s32)*(s16 *)(param_1 + 0x28) + (s32)*pv; - *(s32 *)(param_1 + 0x4c) = (s32)*(s16 *)(param_1 + 0x2a) + (s32)D_80126942; - *(s32 *)(param_1 + 0x50) = (s32)*(s16 *)(param_1 + 0x2c) + (s32)D_80126944; - - func_80013F3C((s32)&mtx); - func_800123F0((s32)&mtx, (s32)*(s16 *)(param_1 + 0x1c)); - func_80012558((s32)&mtx, ((s32)*(s16 *)(param_1 + 0x1a) + (s32)(s16)param_2) & 0xFFF); - func_800126C4((s32)&mtx, (s32)*(s16 *)(param_1 + 0x18)); - - mtx.t[0] = (s32)*(s16 *)(param_1 + 0x28) + (s32)*pv; - mtx.t[1] = (s32)*(s16 *)(param_1 + 0x2a) + (s32)D_80126942; - mtx.t[2] = (s32)*(s16 *)(param_1 + 0x2c) + (s32)D_80126944; - vec.vx = 0; - vec.vy = 0; - vec.vz = (s16)*(s32 *)(param_1 + 0x10); - - func_8012F14C((s32)&mtx, (s32)&vec, (s32)&out); - - *(s32 *)(param_1 + 0x3c) = (s32)out.vx; - *(s32 *)(param_1 + 0x40) = (s32)out.vy; - *(s32 *)(param_1 + 0x44) = (s32)out.vz; -} +DEFINE_func_80174CB0() /* dedup: shared engine-core @0x80174CB0 (src/shared) */ DEFINE_func_80174E9C() /* dedup: shared engine-core @0x80174e9c (src/shared) */ diff --git a/src/ov_SC07_007/ov_SC07_007_jr_8015C32C.c b/src/ov_SC07_007/ov_SC07_007_jr_8015C32C.c index 7b2f57057..6fb1330de 100644 --- a/src/ov_SC07_007/ov_SC07_007_jr_8015C32C.c +++ b/src/ov_SC07_007/ov_SC07_007_jr_8015C32C.c @@ -8335,7 +8335,7 @@ DEFINE_func_80174C60() /* dedup: shared engine-core @0x80174c60 (src/shared) */ DEFINE_func_80174C80() /* dedup: shared engine-core @0x80174c80 (src/shared) */ -INCLUDE_ASM("asm/ov_SC07_007/nonmatchings/ov_SC07_007_jr_8015C32C", func_80174CB0); +DEFINE_func_80174CB0() /* dedup: shared engine-core @0x80174CB0 (src/shared) */ DEFINE_func_80174E9C() /* dedup: shared engine-core @0x80174e9c (src/shared) */ diff --git a/src/ov_SC07_011/ov_SC07_011_jr_8015C32C.c b/src/ov_SC07_011/ov_SC07_011_jr_8015C32C.c index d8a7c2744..acbe3cb1f 100644 --- a/src/ov_SC07_011/ov_SC07_011_jr_8015C32C.c +++ b/src/ov_SC07_011/ov_SC07_011_jr_8015C32C.c @@ -8360,7 +8360,7 @@ DEFINE_func_80174C60() /* dedup: shared engine-core @0x80174c60 (src/shared) */ DEFINE_func_80174C80() /* dedup: shared engine-core @0x80174c80 (src/shared) */ -INCLUDE_ASM("asm/ov_SC07_011/nonmatchings/ov_SC07_011_jr_8015C32C", func_80174CB0); +DEFINE_func_80174CB0() /* dedup: shared engine-core @0x80174CB0 (src/shared) */ DEFINE_func_80174E9C() /* dedup: shared engine-core @0x80174e9c (src/shared) */ diff --git a/src/shared/engine_core.h b/src/shared/engine_core.h index bbe678718..76645c8f4 100644 --- a/src/shared/engine_core.h +++ b/src/shared/engine_core.h @@ -29166,4 +29166,48 @@ func_80017758(buf + 0x00, p); \ } +#define DEFINE_func_80174CB0() \ + extern s16 D_80126940; \ + extern s16 D_80126942; \ + extern s16 D_80126944; \ + extern s32 func_80012ABC(s32 a0, s32 a1, s32 a2); \ + extern s32 func_80012C6C(s32 a0, s32 a1, s32 a2); \ + extern void func_80013F3C(s32 a0); \ + extern void func_800123F0(s32 a0, s32 a1); \ + extern void func_80012558(s32 a0, s32 a1); \ + extern void func_800126C4(s32 a0, s32 a1); \ + extern void func_8012F14C(s32 a0, s32 a1, s32 a2); \ + s32 func_80174CB0(s32 param_1, s32 param_2) \ + { \ + s16 *pv = &D_80126940; \ + MATRIX mtx; \ + SVECTOR vec; \ + SVECTOR out; \ + *(s32 *)(param_1 + 8) = (s16)((s16 (*)(s32, s32, s32))func_80012C6C)((s32)*(s16 *)(param_1 + 8), (s32)*(s16 *)(param_1 + 0xc), 4); \ + *(s32 *)(param_1 + 0x10) = (s16)((s16 (*)(s32, s32, s32))func_80012C6C)((s32)*(s16 *)(param_1 + 0x10), (s32)*(s16 *)(param_1 + 0x14), 4); \ + *(s16 *)(param_1 + 0x18) = ((s16 (*)(s32, s32, s32))func_80012ABC)((s32)*(s16 *)(param_1 + 0x18), (s32)*(s16 *)(param_1 + 0x20), 4); \ + *(s16 *)(param_1 + 0x1a) = ((s16 (*)(s32, s32, s32))func_80012ABC)((s32)*(s16 *)(param_1 + 0x1a), (s32)*(s16 *)(param_1 + 0x22), 4); \ + *(s16 *)(param_1 + 0x1c) = ((s16 (*)(s32, s32, s32))func_80012ABC)((s32)*(s16 *)(param_1 + 0x1c), (s32)*(s16 *)(param_1 + 0x24), 4); \ + *(s16 *)(param_1 + 0x28) = ((s16 (*)(s32, s32, s32))func_80012C6C)((s32)*(s16 *)(param_1 + 0x28), (s32)*(s16 *)(param_1 + 0x2e), 0x10); \ + *(s16 *)(param_1 + 0x2a) = ((s16 (*)(s32, s32, s32))func_80012C6C)((s32)*(s16 *)(param_1 + 0x2a), (s32)*(s16 *)(param_1 + 0x30), 0x10); \ + *(s16 *)(param_1 + 0x2c) = ((s16 (*)(s32, s32, s32))func_80012C6C)((s32)*(s16 *)(param_1 + 0x2c), (s32)*(s16 *)(param_1 + 0x32), 0x10); \ + *(s32 *)(param_1 + 0x48) = (s32)*(s16 *)(param_1 + 0x28) + (s32)*pv; \ + *(s32 *)(param_1 + 0x4c) = (s32)*(s16 *)(param_1 + 0x2a) + (s32)D_80126942; \ + *(s32 *)(param_1 + 0x50) = (s32)*(s16 *)(param_1 + 0x2c) + (s32)D_80126944; \ + func_80013F3C((s32)&mtx); \ + func_800123F0((s32)&mtx, (s32)*(s16 *)(param_1 + 0x1c)); \ + func_80012558((s32)&mtx, ((s32)*(s16 *)(param_1 + 0x1a) + (s32)(s16)param_2) & 0xFFF); \ + func_800126C4((s32)&mtx, (s32)*(s16 *)(param_1 + 0x18)); \ + mtx.t[0] = (s32)*(s16 *)(param_1 + 0x28) + (s32)*pv; \ + mtx.t[1] = (s32)*(s16 *)(param_1 + 0x2a) + (s32)D_80126942; \ + mtx.t[2] = (s32)*(s16 *)(param_1 + 0x2c) + (s32)D_80126944; \ + vec.vx = 0; \ + vec.vy = 0; \ + vec.vz = (s16)*(s32 *)(param_1 + 0x10); \ + func_8012F14C((s32)&mtx, (s32)&vec, (s32)&out); \ + *(s32 *)(param_1 + 0x3c) = (s32)out.vx; \ + *(s32 *)(param_1 + 0x40) = (s32)out.vy; \ + *(s32 *)(param_1 + 0x44) = (s32)out.vz; \ + } + #endif diff --git a/tools/dedup_propagate.py b/tools/dedup_propagate.py index 579ee9346..a7057c2e0 100644 --- a/tools/dedup_propagate.py +++ b/tools/dedup_propagate.py @@ -211,16 +211,27 @@ def find_site(text, ov, addr): # e.g. `extern u8 D_x[]; /* canonical TU type */` — a comment-blind `;\s*$` stopped the # scan there and dropped every EARLIER extern, failing compiles_standalone on the now- # undeclared callees/data; T6.4 fix for func_8014E048's pin/asm body). + # SESSION-18: the walk skipped BLANK lines but not STANDALONE COMMENT lines, so a + # full-line `/* ---- */` between two extern groups halted it and silently dropped every + # extern ABOVE the comment. That is the whole "CARRY-FIXABLE" class: the body then fails + # compiles_standalone on now-undeclared data/callees, and the caller filed it under + # "overlay-local TYPE (the real cap)" — a mislabel that wrote the class off for ~4 phases. + # (T6.4 had already fixed the TRAILING-comment case, `extern u8 D_x[]; /* note */`; this + # is the standalone-LINE case it did not reach.) Skip comment-only lines exactly like + # blanks, and drop them from the emitted body so make_macro never sees a `//`. + def _skippable(ln): + t = ln.strip() + return t == "" or t.startswith("//") or (t.startswith("/*") and t.endswith("*/")) start = i k = i - 1 - while k >= 0 and lines[k].strip() == "": + while k >= 0 and _skippable(lines[k]): k -= 1 while k >= 0 and re.match(r"^\s*extern\b.*;\s*(/\*.*\*/\s*)?$", lines[k]): start = k k -= 1 - while k >= 0 and lines[k].strip() == "": + while k >= 0 and _skippable(lines[k]): k -= 1 - body = [ln for ln in lines[start:end + 1] if ln.strip() != ""] + body = [ln for ln in lines[start:end + 1] if not _skippable(ln)] return ("def", start, end, body) return None