Skip to content

Qualify dScMgAmida_c::Virtual88's six calls into its base - #2118

Merged
andrewboudreau merged 1 commit into
mainfrom
cpp/minigame-methods-4
Sep 1, 2026
Merged

Qualify dScMgAmida_c::Virtual88's six calls into its base#2118
andrewboudreau merged 1 commit into
mainfrom
cpp/minigame-methods-4

Conversation

@andrewboudreau

Copy link
Copy Markdown
Collaborator

After #2116 the minigame family has no free-function definitions left. The last hand-written mangled name in it was a declaration, in the one file that calls up into its own base:

extern "C" {
extern void _ZN11dScMgBase_c9Virtual88Eiiii(Ctx* ctx, int cx, int cy,
                                            int colour, int size);
}
...
_ZN11dScMgBase_c9Virtual88Eiiii(ctx, y, x, arg3, 4);

Six call sites, all inside dScMgAmida_c::Virtual88. They become:

dScMgBase_c::Virtual88(y, x, arg3, 4);

Two things have to be true for that to be the same code, and neither is settled by the type system:

  • A qualified call must suppress virtual dispatch — otherwise this becomes a vtable load where the ROM has a direct bl.
  • this must need no adjustment — the old spelling passed ctx explicitly, which is (Ctx *)this unadjusted. That is only the same pointer if dScMgBase_c sits at offset 0 in dScMgAmida_c.

The bytes settle both:

build_pin.verify(_ZN12dScMgAmida_c9Virtual88Eiiii, 0x020d14c0, 0x498, ov006)
  -> (True, '2004/b56')

The local Ctx typedef stays — it is still how the body reads its fields, and replacing it with named inherited members is a separate change that needs its own byte proof.

Verified: rombuild.py -j 16 --no-rom → 11,088/11,088, 0 mismatching, 106/106 exact, 100.000000%. Nine static gates green.

Stacked on #2116. attribution-override.

The last hand-written mangled name in the minigame family was not a
definition but a declaration, in the one file that calls up into its own
base:

  extern "C" {
  extern void _ZN11dScMgBase_c9Virtual88Eiiii(Ctx* ctx, int cx, int cy,
                                              int colour, int size);
  }
  ...
  _ZN11dScMgBase_c9Virtual88Eiiii(ctx, y, x, arg3, 4);

Six call sites, all in dScMgAmida_c::Virtual88. They become

  dScMgBase_c::Virtual88(y, x, arg3, 4);

A qualified call suppresses virtual dispatch, so this is still the direct
`bl` the ROM has, not a vtable load -- and the implicit `this` needs no
adjustment because dScMgBase_c sits at offset 0 in dScMgAmida_c, which is
what makes passing `ctx` and passing `this` the same pointer. Both of those
are claims the bytes have to settle, not the type system:

  build_pin.verify(_ZN12dScMgAmida_c9Virtual88Eiiii, 0x020d14c0, 0x498, ov006)
    -> (True, '2004/b56')

The local `Ctx` typedef stays. It is still what the body reads its fields
through, and replacing it with named inherited members is a separate change
that needs its own byte proof.

VERIFIED: python tools/rombuild.py -j 16 --no-rom
  11,088 / 11,088 reproducing, 0 mismatching
  106/106 modules exact, 100.000000% of compared bytes
Nine static gates green.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QhhAeJwXBnfPp7B5DNjCwh
@andrewboudreau andrewboudreau added the attribution-override Maintainer accepts this PR's contributor-credit changes; validation reports them as warnings label Aug 31, 2026
@tangos-validator

tangos-validator Bot commented Aug 31, 2026

Copy link
Copy Markdown

✅ PR validation — Passed

Committed merge introduces no reconstruction or attribution regression.

Full merge validation

Check Result
Committed test merge yes
Byte-verified functions 10,781 / 11,347 (95.01%, +0)
Byte-verified code bytes 2,004,460 / 2,211,124 (90.65%, +0)
Claimed, not byte-verified 436 functions, 101,220 bytes (+0)
Perfect source moves 0 R100
Enrolled ranges (delinks complete) 11,059 functions, 2,053,148 bytes (92.86%, +0) -- differs from byte-verified by +278
Contributor credit 0 added, 0 changed, 0 lost
Relocation check 1 checked; 1 VERIFIED
Port reference check 405 checked; 0 stale
Module fidelity 106/106 exact; 100.000000% compared bytes
Code linked from verified source 11,088 functions, 2,067,148 bytes (93.49%)
Module bytes from source 2,067,148 / 3,049,600 (67.8%); 811,492 (26.6%) are data no delink entry reaches
ROM data reproduced from source 496 symbol(s) exact, 223 partial, 5 differ

Byte-verified means the range carries complete in a delinks.txt, so the ROM build compiled it and compared it to the cartridge. The 436 claimed functions have a src/ file named after the symbol with no NONMATCHING banner, and nothing compiles them -- dsd fills their addresses with the ROM's own bytes. Both together are the 11,217 this project calls matched.

Per-file link-check detail

All 1 changed file(s) compile to the ROM byte-for-byte with correct relocation targets.

File Symbol Result Slots checked
src/_ZN12dScMgAmida_c9Virtual88Eiiii.cpp _ZN12dScMgAmida_c9Virtual88Eiiii ✅ verified 1

The private worker commits a test merge, builds the stock ROM profile, compares every executable module, measures matched and source-built code, checks contributor lineage, and verifies affected relocations. The mod profile is opt-in and is not part of this merge gate.

Base automatically changed from cpp/minigame-methods-3 to main September 1, 2026 07:30
@andrewboudreau
andrewboudreau merged commit 673059d into main Sep 1, 2026
8 checks passed
@andrewboudreau
andrewboudreau deleted the cpp/minigame-methods-4 branch September 1, 2026 07:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

attribution-override Maintainer accepts this PR's contributor-credit changes; validation reports them as warnings

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant