Merge pull request #295 from mstan/fix/overlay-abi-v22-game-text-native-ok

overlay: ABI v22 game_text_native_ok shim (107 shards failed to link)
This commit is contained in:
Matt Stanley
2026-09-02 01:06:35 -07:00
committed by GitHub
3 changed files with 35 additions and 1 deletions
+19 -1
View File
@@ -45,6 +45,18 @@
* masked, aliased, read-only, precision-sensitive, flag/IR, and derived
* GTE regs; GTE-heavy overlays failed to LINK without shims (undefined
* gte_read_ctrl), silently blocking new coverage. */
/* v22: game_text_native_ok callback - the emitter emits a direct
* psx_game_text_native_ok() stale-static guard (code_generator.cpp, at
* block entry and before every direct jal). The function is DEFINED IN THE
* GENERATED DISPATCH SHARD, which lives in the executable, so an overlay
* DLL cannot see it: 107 of 109 shard failures on the 2026-09-02 Tomba 2
* framework bump were `undefined reference to psx_game_text_native_ok`.
* Exactly the rfe / gte_read_ctrl / gte_precision_store_word class again -
* an emitter gained a runtime call without the overlay ABI gaining the
* shim, and the only symptom is shards that silently fail to build so the
* code runs interpreted forever. NULL-guarded: a host predating v22 makes
* the shim return 0, which routes the guest through the dispatcher instead
* of native code - slower, never wrong. */
/* v11 batches per-instruction cycle charges inside overlay DLLs and flushes at
* block/device/store boundaries, removing a cross-DLL callback per instruction
* without changing the shared guest-cycle timeline. */
@@ -93,7 +105,7 @@
* host/DLL flavor mix — base-flavour DLLs and hosts are untouched, so
* the version stays. The emit-content change (PGXP_*() macros in all
* generated C) is covered by the codegen hash + CODEGEN_VER below. */
#define PSX_OVERLAY_ABI_VERSION 21
#define PSX_OVERLAY_ABI_VERSION 22
/* Process-lifetime overlay candidate capacity. Every accepted manifest F
* record consumes one slot, even when another DLL carries an identical
@@ -309,6 +321,12 @@ typedef struct {
/* Aspect-scaled terrain-frustum angle helper (ABI v21). */
uint32_t (*ws_angle_widen)(uint32_t vanilla);
/* Stale-static guard (ABI v22; see the version-history note above).
* Defined by the generated dispatch shard in the executable, so overlay
* DLLs must forward. Appended last; may be NULL on a host that predates
* it - the shim then returns 0 and the guest takes the dispatcher path. */
int (*game_text_native_ok)(uint32_t addr);
/* PGXP dataflow-shadowing hook table (pgxp_hooks.h). Only pgxp-flavour
* shards (PSX_OVERLAY_FLAVOR pgxp bit, compiled with -DPSX_PGXP=1) emit
* calls to psx_pgxp_*; their preamble forwards through this table. Base-
@@ -93,6 +93,16 @@ void psx_rfe_mark_escape(void) {
overlay_flush_cycles();
g_cbs.rfe_mark_escape();
}
/* Stale-static guard (ABI v22). The emitter emits this at block entry and
* before every direct jal, but it is DEFINED IN THE GENERATED DISPATCH SHARD
* (executable side), so an overlay DLL cannot resolve it without this shim.
* Its absence is what made 107 shards fail to link on the 2026-09-02 bump.
* NULL-guarded: returning 0 sends the guest down the dispatcher path, which is
* slower but never wrong -- the opposite choice (returning 1) would let an
* overlay run native code the guard was trying to reject. */
int psx_game_text_native_ok(uint32_t addr) {
return g_cbs.game_text_native_ok ? g_cbs.game_text_native_ok(addr) : 0;
}
/* Faithful-timing functions (ABI v9): overlay code built with PSX_ENABLE_BLOCK_CYCLES
* emits these; forward to the runtime's real impls so native overlays charge cycles on
* the SAME timeline as the interp/BIOS (a local copy would diverge). NULL-guarded so a
+6
View File
@@ -2260,6 +2260,12 @@ static void init_callbacks(void) {
s_callbacks.psx_restore_state_escape = psx_restore_state_escape;
/* Return-from-exception mark (ABI v12): overlay `rfe` ops forward here. */
s_callbacks.rfe_mark_escape = psx_rfe_mark_escape;
/* Stale-static guard (ABI v22): defined by the generated dispatch shard in
* this executable, so overlay DLLs forward here rather than link it. */
{
extern int psx_game_text_native_ok(uint32_t addr);
s_callbacks.game_text_native_ok = psx_game_text_native_ok;
}
/* Call-contract state (ABI v2): DLL code shares the runtime's bail
* flag and counters through these pointers. */
s_callbacks.call_bail_flag = &g_psx_call_bail;