Resolves the method-id gaps surfaced by the dispatch axis, all real switch-shape edge cases rather than numbering bugs: - default holes: ids the runner doesn't implement route to the `JA default` block (tail-call to base CMC_Runner::run); capture that target and drop those cases (was emitting false Sound 5/6, Scene 10-15, Array 26-31) - sign-extension: high-base switches (CMC_NetPeer id 257+) encode the base as `LEA/ADD idx, 0xFFFFFEFF` (-257); _s32 sign-extends on both the scalar and the text path (Ghidra prints big displacements unsigned, small ones signed) - two-level (byte-indexed) switches: sparse runners (Image) use `MOVZX r,byte[i+byteTable]` (MSVC8) / `MOV rl,byte[i+byteTable]` (MSVC6) then `JMP [r*4+ptrTable]`; decode target = ptrTable[byteTable[i]], taking base/count from the byte-table's index register (differs from the JMP index reg on MSVC6) - _executable() guard + id clamp: never emit a non-code "case" Result: Piklib 500 rows / BlooMoo 561, garbage 0, dispatch<->methods consistent. The lone genuinely-nameless method is CMC_Animo id 14 (a bool getter prepareMthHashSet doesn't register) - a real engine property, correctly absent from the methods axis. FUN_ ctor names are not recoverable (no symbols/mangled strings/RTTI in the binary for FILTER/MOVIE/VECTOR/PATH/FIFO/LIFO/STATICFILTER); cpp_class=None stays. Snapshots regenerated; 34/34 tests pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
35 KiB
35 KiB