Harden dispatch switch parsing (id-gap drobiazgi)

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>
This commit is contained in:
Patryk Gensch
2026-05-31 16:56:24 +02:00
parent b0d3d22445
commit be733cf8b7
3 changed files with 773 additions and 728 deletions

View File

@@ -3229,60 +3229,6 @@
"owner": "CMC_Array",
"runner": "CMC_Array_Runner"
},
{
"calls": [],
"case_addr": "0x100471fb",
"id": 26,
"impl": "CMC_Runner::run",
"impl_addr": "0x10095e40",
"owner": "CMC_Array",
"runner": "CMC_Array_Runner"
},
{
"calls": [],
"case_addr": "0x100471fb",
"id": 27,
"impl": "CMC_Runner::run",
"impl_addr": "0x10095e40",
"owner": "CMC_Array",
"runner": "CMC_Array_Runner"
},
{
"calls": [],
"case_addr": "0x100471fb",
"id": 28,
"impl": "CMC_Runner::run",
"impl_addr": "0x10095e40",
"owner": "CMC_Array",
"runner": "CMC_Array_Runner"
},
{
"calls": [],
"case_addr": "0x100471fb",
"id": 29,
"impl": "CMC_Runner::run",
"impl_addr": "0x10095e40",
"owner": "CMC_Array",
"runner": "CMC_Array_Runner"
},
{
"calls": [],
"case_addr": "0x100471fb",
"id": 30,
"impl": "CMC_Runner::run",
"impl_addr": "0x10095e40",
"owner": "CMC_Array",
"runner": "CMC_Array_Runner"
},
{
"calls": [],
"case_addr": "0x100471fb",
"id": 31,
"impl": "CMC_Runner::run",
"impl_addr": "0x10095e40",
"owner": "CMC_Array",
"runner": "CMC_Array_Runner"
},
{
"calls": [
"vtbl+0x40",
@@ -5087,6 +5033,663 @@
"owner": "CMC_Groupped",
"runner": "CMC_Groupped_Runner"
},
{
"calls": [
"CMC_Image::getImage",
"vtbl+0x7c"
],
"case_addr": "0x100760e8",
"id": 1,
"impl": null,
"impl_addr": "0x100760e8",
"owner": "CMC_Image",
"runner": "CMC_Image_Runner"
},
{
"calls": [
"CMC_Image::getImage",
"vtbl+0x7c"
],
"case_addr": "0x10076106",
"id": 2,
"impl": null,
"impl_addr": "0x10076106",
"owner": "CMC_Image",
"runner": "CMC_Image_Runner"
},
{
"calls": [
"CMC_Image::getImage",
"vtbl+0x3c",
"vtbl+0x3c",
"vtbl+0x104",
"CMC_EditBox::getEditBox",
"CMC_EditBox::getEditBox",
"vtbl+0x64",
"vtbl+0x104"
],
"case_addr": "0x10076124",
"id": 5,
"impl": null,
"impl_addr": "0x10076124",
"owner": "CMC_Image",
"runner": "CMC_Image_Runner"
},
{
"calls": [
"CMC_Image::getImage",
"vtbl+0x3c",
"vtbl+0x3c",
"CMC_EditBox::getEditBox",
"CMC_EditBox::getEditBox",
"vtbl+0x6c",
"CMC_Object::flush",
"CMC_Object::flush"
],
"case_addr": "0x100761f2",
"id": 6,
"impl": null,
"impl_addr": "0x100761f2",
"owner": "CMC_Image",
"runner": "CMC_Image_Runner"
},
{
"calls": [
"vtbl+0x40",
"CMC_Keyboard::getLatestKey",
"vtbl+0x94",
"CMC_Object::flush"
],
"case_addr": "0x1007624f",
"id": 7,
"impl": "CMC_Image_Runner::load",
"impl_addr": "0x10076b30",
"owner": "CMC_Image",
"runner": "CMC_Image_Runner"
},
{
"calls": [
"CMC_Image::getImage",
"CGraphicsObject::SetClippingRect"
],
"case_addr": "0x1007626f",
"id": 8,
"impl": null,
"impl_addr": "0x1007626f",
"owner": "CMC_Image",
"runner": "CMC_Image_Runner"
},
{
"calls": [
"CMC_Image::getImage",
"vtbl+0x40",
"CMC_Keyboard::getLatestKey",
"CMC_ObjectsContainer::getGraphicsObject",
"vtbl+0xe8",
"CXRect::operator=",
"CMC_Object::flush"
],
"case_addr": "0x10076293",
"id": 9,
"impl": "CMC_Image_Runner::setClipping",
"impl_addr": "0x10076be0",
"owner": "CMC_Image",
"runner": "CMC_Image_Runner"
},
{
"calls": [
"CMC_Image::getImage",
"CMC_VariableFactory::allocInteger",
"vtbl+0xd8",
"CMC_Integer::setValue"
],
"case_addr": "0x100762b3",
"id": 15,
"impl": null,
"impl_addr": "0x100762b3",
"owner": "CMC_Image",
"runner": "CMC_Image_Runner"
},
{
"calls": [
"CMC_Image::getImage",
"CMC_VariableFactory::allocInteger",
"vtbl+0xd8",
"CMC_Integer::setValue"
],
"case_addr": "0x100762ea",
"id": 16,
"impl": null,
"impl_addr": "0x100762ea",
"owner": "CMC_Image",
"runner": "CMC_Image_Runner"
},
{
"calls": [
"CMC_Image::getImage",
"CMC_VariableFactory::allocInteger",
"vtbl+0xc4",
"CMC_Integer::setValue"
],
"case_addr": "0x10076322",
"id": 17,
"impl": null,
"impl_addr": "0x10076322",
"owner": "CMC_Image",
"runner": "CMC_Image_Runner"
},
{
"calls": [
"CMC_Image::getImage",
"CMC_VariableFactory::allocInteger",
"vtbl+0xc8",
"CMC_Integer::setValue"
],
"case_addr": "0x10076352",
"id": 18,
"impl": null,
"impl_addr": "0x10076352",
"owner": "CMC_Image",
"runner": "CMC_Image_Runner"
},
{
"calls": [
"CMC_VariableFactory::allocBool",
"CMC_Image::getImage",
"vtbl+0x40",
"CMC_Keyboard::getLatestKey",
"CMC_ObjectsContainer::getGraphicsObject",
"vtbl+0x3c",
"CMC_EditBox::getEditBox",
"vtbl+0xf4",
"CMC_Bool::setValue",
"CMC_Object::flush",
"CMC_Object::flush"
],
"case_addr": "0x10076382",
"id": 23,
"impl": "CMC_Image_Runner::isNear",
"impl_addr": "0x10076e40",
"owner": "CMC_Image",
"runner": "CMC_Image_Runner"
},
{
"calls": [
"CMC_VariableFactory::allocBool",
"CMC_Image::getImage",
"vtbl+0x3c",
"vtbl+0x3c",
"vtbl+0x34",
"CMC_Bool::getValue",
"CMC_EditBox::getEditBox",
"CMC_EditBox::getEditBox",
"CGraphicsObject::isInside",
"CMC_Bool::setValue",
"CMC_Object::flush",
"CMC_Object::flush",
"CMC_Object::flush"
],
"case_addr": "0x100763a2",
"id": 24,
"impl": "CMC_Image_Runner::isInside",
"impl_addr": "0x10077010",
"owner": "CMC_Image",
"runner": "CMC_Image_Runner"
},
{
"calls": [
"vtbl+0x34",
"CMC_Image::getImage",
"vtbl+0x38"
],
"case_addr": "0x100763c2",
"id": 26,
"impl": null,
"impl_addr": "0x100763c2",
"owner": "CMC_Image",
"runner": "CMC_Image_Runner"
},
{
"calls": [
"CMC_Image::getImage",
"vtbl+0x90",
"vtbl+0x34"
],
"case_addr": "0x10076429",
"id": 27,
"impl": null,
"impl_addr": "0x10076429",
"owner": "CMC_Image",
"runner": "CMC_Image_Runner"
},
{
"calls": [
"vtbl+0x3c",
"CMC_Image::getImage",
"CMC_EditBox::getEditBox",
"CRefreshScreen::SetPriority",
"CMC_Object::flush"
],
"case_addr": "0x10076455",
"id": 32,
"impl": null,
"impl_addr": "0x10076455",
"owner": "CMC_Image",
"runner": "CMC_Image_Runner"
},
{
"calls": [
"vtbl+0x3c",
"vtbl+0x3c",
"CMC_Image::getImage",
"CMC_VariableFactory::allocInteger",
"CMC_Integer::setValue",
"vtbl+0xd8",
"CMC_EditBox::getEditBox",
"vtbl+0xd8",
"vtbl+0xc4",
"CMC_EditBox::getEditBox",
"vtbl+0xd8",
"CMC_EditBox::getEditBox",
"vtbl+0xd8",
"vtbl+0xc8",
"CMC_EditBox::getEditBox"
],
"case_addr": "0x100764a1",
"id": 33,
"impl": "CMC_Image_Runner::getAlpha",
"impl_addr": "0x100771a0",
"owner": "CMC_Image",
"runner": "CMC_Image_Runner"
},
{
"calls": [
"vtbl+0x3c",
"vtbl+0x3c",
"CMC_Image::getImage",
"vtbl+0x4c",
"CMC_VariableFactory::allocInteger",
"CMC_Integer::setValue",
"vtbl+0xd8",
"CMC_EditBox::getEditBox",
"vtbl+0xd8",
"vtbl+0xc4",
"CMC_EditBox::getEditBox",
"vtbl+0xd8",
"CMC_EditBox::getEditBox",
"vtbl+0xd8",
"vtbl+0xc8"
],
"case_addr": "0x100764c1",
"id": 34,
"impl": "CMC_Image_Runner::getPixel",
"impl_addr": "0x100772e0",
"owner": "CMC_Image",
"runner": "CMC_Image_Runner"
},
{
"calls": [
"vtbl+0x3c",
"vtbl+0x3c",
"vtbl+0x40",
"CMC_Keyboard::getLatestKey",
"CMC_ObjectsContainer::getGraphicsObject",
"CMC_Image::getImage",
"CMC_EditBox::getEditBox",
"CMC_EditBox::getEditBox",
"CXPoint::CXPoint",
"CGraphicsObject::mergeAlpha",
"CMC_Object::flush",
"CMC_Object::flush",
"CMC_Object::flush"
],
"case_addr": "0x100764e1",
"id": 36,
"impl": "CMC_Image_Runner::mergeAlpha",
"impl_addr": "0x10077430",
"owner": "CMC_Image",
"runner": "CMC_Image_Runner"
},
{
"calls": [
"CMC_Image::getImage",
"vtbl+0x104"
],
"case_addr": "0x10076501",
"id": 37,
"impl": null,
"impl_addr": "0x10076501",
"owner": "CMC_Image",
"runner": "CMC_Image_Runner"
},
{
"calls": [
"CMC_Image::getImage",
"vtbl+0xd8",
"vtbl+0xcc",
"CMC_VariableFactory::allocInteger"
],
"case_addr": "0x10076520",
"id": 40,
"impl": null,
"impl_addr": "0x10076520",
"owner": "CMC_Image",
"runner": "CMC_Image_Runner"
},
{
"calls": [
"CMC_Image::getImage",
"vtbl+0xd8",
"vtbl+0xcc",
"CMC_VariableFactory::allocInteger",
"CMC_Integer::setValue"
],
"case_addr": "0x1007655a",
"id": 41,
"impl": null,
"impl_addr": "0x1007655a",
"owner": "CMC_Image",
"runner": "CMC_Image_Runner"
},
{
"calls": [
"CMC_Image::getImage",
"CMC_VariableFactory::allocBool",
"CMC_Bool::setValue"
],
"case_addr": "0x100765ae",
"id": 48,
"impl": null,
"impl_addr": "0x100765ae",
"owner": "CMC_Image",
"runner": "CMC_Image_Runner"
},
{
"calls": [
"CMC_Image::getImage",
"vtbl+0x40",
"CMC_Keyboard::getLatestKey",
"CMC_ObjectsContainer::getObject",
"MSVCRT.DLL::free",
"CMC_Image::getImage",
"vtbl+0xd8",
"vtbl+0x60",
"vtbl+0xcc",
"vtbl+0xd0",
"vtbl+0x4c",
"CGraphicsObject::AlphaChannel",
"vtbl+0x104"
],
"case_addr": "0x100765da",
"id": 49,
"impl": "CMC_Image_Runner::link",
"impl_addr": "0x100775f0",
"owner": "CMC_Image",
"runner": "CMC_Image_Runner"
},
{
"calls": [
"vtbl+0x34",
"CMC_Bool::getValue",
"vtbl+0x34",
"CMC_Bool::getValue"
],
"case_addr": "0x100765fa",
"id": 50,
"impl": null,
"impl_addr": "0x100765fa",
"owner": "CMC_Image",
"runner": "CMC_Image_Runner"
},
{
"calls": [
"vtbl+0x3c",
"CMC_Image::getImage",
"CMC_EditBox::getEditBox",
"vtbl+0x3c"
],
"case_addr": "0x10076639",
"id": 51,
"impl": null,
"impl_addr": "0x10076639",
"owner": "CMC_Image",
"runner": "CMC_Image_Runner"
},
{
"calls": [
"CMC_Image::getImage",
"vtbl+0x40",
"CMC_Keyboard::getLatestKey",
"vtbl+0xbc",
"CMC_Object::flush"
],
"case_addr": "0x100766a7",
"id": 52,
"impl": "CMC_Image_Runner::save",
"impl_addr": "0x10076b70",
"owner": "CMC_Image",
"runner": "CMC_Image_Runner"
},
{
"calls": [
"CMC_Image::getImage",
"vtbl+0xd8",
"vtbl+0xcc",
"vtbl+0x40",
"MSVCRT.DLL::malloc"
],
"case_addr": "0x100766c7",
"id": 53,
"impl": "CMC_Image_Runner::setAnchor",
"impl_addr": "0x100777b0",
"owner": "CMC_Image",
"runner": "CMC_Image_Runner"
},
{
"calls": [
"CMC_Image::getImage",
"vtbl+0x94",
"vtbl+0x104"
],
"case_addr": "0x100766e7",
"id": 54,
"impl": null,
"impl_addr": "0x100766e7",
"owner": "CMC_Image",
"runner": "CMC_Image_Runner"
},
{
"calls": [
"CMC_Image::getImage",
"vtbl+0x98",
"vtbl+0x104"
],
"case_addr": "0x10076712",
"id": 55,
"impl": null,
"impl_addr": "0x10076712",
"owner": "CMC_Image",
"runner": "CMC_Image_Runner"
},
{
"calls": [
"CMC_Image::getImage",
"vtbl+0x9c",
"vtbl+0x104"
],
"case_addr": "0x1007673d",
"id": 56,
"impl": null,
"impl_addr": "0x1007673d",
"owner": "CMC_Image",
"runner": "CMC_Image_Runner"
},
{
"calls": [
"CMC_Image::getImage",
"vtbl+0x40",
"CMC_Keyboard::getLatestKey",
"CMC_ObjectsContainer::getGraphicsObject",
"vtbl+0x3c",
"CMC_EditBox::getEditBox",
"CGraphicsObject::addObject"
],
"case_addr": "0x10076768",
"id": 57,
"impl": "CMC_Image_Runner::drawOnto",
"impl_addr": "0x10077da0",
"owner": "CMC_Image",
"runner": "CMC_Image_Runner"
},
{
"calls": [
"CMC_Image::getImage",
"vtbl+0x104",
"vtbl+0x64",
"vtbl+0x104"
],
"case_addr": "0x100761b6",
"id": 58,
"impl": null,
"impl_addr": "0x100761b6",
"owner": "CMC_Image",
"runner": "CMC_Image_Runner"
},
{
"calls": [
"vtbl+0x3c",
"vtbl+0x3c",
"CMC_EditBox::getEditBox",
"CMC_EditBox::getEditBox"
],
"case_addr": "0x1007617b",
"id": 59,
"impl": null,
"impl_addr": "0x1007617b",
"owner": "CMC_Image",
"runner": "CMC_Image_Runner"
},
{
"calls": [
"CMC_Image::getImage",
"vtbl+0x3c",
"vtbl+0x3c",
"vtbl+0x34",
"CMC_VariableFactory::allocBool",
"CMC_Bool::getValue",
"CMC_EditBox::getEditBox",
"CMC_EditBox::getEditBox",
"CXPoint::CXPoint",
"CGraphicsObject::isAt",
"CMC_Bool::setValue"
],
"case_addr": "0x10076788",
"id": 63,
"impl": "CMC_Image_Runner::isAt",
"impl_addr": "0x10077e10",
"owner": "CMC_Image",
"runner": "CMC_Image_Runner"
},
{
"calls": [
"CMC_VariableFactory::allocInteger",
"CMC_Image::getImage",
"CMC_Integer::setValue"
],
"case_addr": "0x1007666f",
"id": 64,
"impl": null,
"impl_addr": "0x1007666f",
"owner": "CMC_Image",
"runner": "CMC_Image_Runner"
},
{
"calls": [
"CMC_Image::getImage",
"vtbl+0x38",
"CMC_Double::getValue",
"vtbl+0x38",
"CMC_Double::getValue",
"vtbl+0x3c",
"CMC_EditBox::getEditBox",
"vtbl+0x3c",
"CMC_EditBox::getEditBox",
"vtbl+0x40",
"CMC_Keyboard::getLatestKey",
"CMC_ObjectsContainer::getObject"
],
"case_addr": "0x100767a8",
"id": 65,
"impl": "CMC_Image_Runner::getSlideComps",
"impl_addr": "0x10077e90",
"owner": "CMC_Image",
"runner": "CMC_Image_Runner"
},
{
"calls": [
"vtbl+0x3c",
"CMC_EditBox::getEditBox",
"vtbl+0x3c",
"CMC_EditBox::getEditBox",
"vtbl+0x40",
"CMC_Keyboard::getLatestKey",
"CMC_ObjectsContainer::getObject",
"MSVCRT.DLL::free",
"MSVCRT.DLL::operator_new",
"MSVCRT.DLL::malloc"
],
"case_addr": "0x100767c8",
"id": 66,
"impl": "CMC_Image_Runner::getColorAt",
"impl_addr": "0x10078230",
"owner": "CMC_Image",
"runner": "CMC_Image_Runner"
},
{
"calls": [
"vtbl+0x3c",
"CMC_EditBox::getEditBox",
"vtbl+0x3c",
"CMC_EditBox::getEditBox",
"CMC_VariableFactory::allocInteger"
],
"case_addr": "0x100767e8",
"id": 67,
"impl": null,
"impl_addr": "0x100767e8",
"owner": "CMC_Image",
"runner": "CMC_Image_Runner"
},
{
"calls": [
"vtbl+0x3c",
"CMC_EditBox::getEditBox",
"vtbl+0x3c",
"CMC_EditBox::getEditBox",
"CMC_VariableFactory::allocInteger"
],
"case_addr": "0x1007681d",
"id": 68,
"impl": "CMC_Image_Runner::getColorBAt",
"impl_addr": "0x100783e0",
"owner": "CMC_Image",
"runner": "CMC_Image_Runner"
},
{
"calls": [
"vtbl+0x3c",
"CMC_EditBox::getEditBox",
"vtbl+0x3c",
"CMC_EditBox::getEditBox",
"CMC_VariableFactory::allocInteger"
],
"case_addr": "0x1007683d",
"id": 69,
"impl": "CMC_Image_Runner::getColorBAt",
"impl_addr": "0x100783e0",
"owner": "CMC_Image",
"runner": "CMC_Image_Runner"
},
{
"calls": [
"vtbl+0x3c",
@@ -5190,15 +5793,6 @@
"owner": "CMC_Keyboard",
"runner": "CMC_Keyboard_Runner"
},
{
"calls": [],
"case_addr": "0x1007ecf2",
"id": 5,
"impl": "CMC_Runner::run",
"impl_addr": "0x10095e40",
"owner": "CMC_Keyboard",
"runner": "CMC_Keyboard_Runner"
},
{
"calls": [
"CMC_VariableFactory::allocString",
@@ -6219,60 +6813,6 @@
"owner": "CMC_Scene",
"runner": "CMC_Scene_Runner"
},
{
"calls": [],
"case_addr": "0x1009d2fb",
"id": 10,
"impl": "CMC_Runner::run",
"impl_addr": "0x10095e40",
"owner": "CMC_Scene",
"runner": "CMC_Scene_Runner"
},
{
"calls": [],
"case_addr": "0x1009d2fb",
"id": 11,
"impl": "CMC_Runner::run",
"impl_addr": "0x10095e40",
"owner": "CMC_Scene",
"runner": "CMC_Scene_Runner"
},
{
"calls": [],
"case_addr": "0x1009d2fb",
"id": 12,
"impl": "CMC_Runner::run",
"impl_addr": "0x10095e40",
"owner": "CMC_Scene",
"runner": "CMC_Scene_Runner"
},
{
"calls": [],
"case_addr": "0x1009d2fb",
"id": 13,
"impl": "CMC_Runner::run",
"impl_addr": "0x10095e40",
"owner": "CMC_Scene",
"runner": "CMC_Scene_Runner"
},
{
"calls": [],
"case_addr": "0x1009d2fb",
"id": 14,
"impl": "CMC_Runner::run",
"impl_addr": "0x10095e40",
"owner": "CMC_Scene",
"runner": "CMC_Scene_Runner"
},
{
"calls": [],
"case_addr": "0x1009d2fb",
"id": 15,
"impl": "CMC_Runner::run",
"impl_addr": "0x10095e40",
"owner": "CMC_Scene",
"runner": "CMC_Scene_Runner"
},
{
"calls": [
"vtbl+0x3c",
@@ -6850,24 +7390,6 @@
"owner": "CMC_Sound",
"runner": "CMC_Sound_Runner"
},
{
"calls": [],
"case_addr": "0x100a3a92",
"id": 5,
"impl": "CMC_Runner::run",
"impl_addr": "0x10095e40",
"owner": "CMC_Sound",
"runner": "CMC_Sound_Runner"
},
{
"calls": [],
"case_addr": "0x100a3a92",
"id": 6,
"impl": "CMC_Runner::run",
"impl_addr": "0x10095e40",
"owner": "CMC_Sound",
"runner": "CMC_Sound_Runner"
},
{
"calls": [
"CMC_Button::getButton",
@@ -7818,15 +8340,6 @@
"owner": "CMC_Variable",
"runner": "CMC_Variable_Runner"
},
{
"calls": [],
"case_addr": "0x100b8162",
"id": 19,
"impl": "CMC_Runner::run",
"impl_addr": "0x10095e40",
"owner": "CMC_Variable",
"runner": "CMC_Variable_Runner"
},
{
"calls": [
"CMC_VariableFactory::allocDouble",