graphics/grNull.c: typed no-op stubs for WASM call_indirect
Magic's graphics layer routes every drawing primitive through function pointers (GrXxxPtr / grXxxPtr) that are bound to a driver at startup. The original null driver assigned a single 0-arg nullDoNothing() to every pointer, which works in native builds because of K&R loose prototype rules but fails in WASM where call_indirect requires an exact type match between caller and callee. This commit: * Adds typed no-op stubs nullDoNothingI/II/IIII/IIIIIII for void-returning callbacks of various arities. * Adds nullReturnFalseI/II/III for bool-returning callbacks and nullReturnZeroI for int-returning callbacks. * Casts each pointer assignment in nullSetDisplay() to the K&R pointer type the public header still uses, while the underlying function carries the correct WASM signature. * Fills in window-management and backing-store pointers that the original null driver left at NULL — many of these are called unconditionally by WindUpdate paths, and need at least a no-op to avoid traps. * Guards the stdin watch in nullSetDisplay() with #ifndef __EMSCRIPTEN__: WASM has no real stdin file descriptor and TxAdd1InputDevice() / SigWatchFile() are POSIX-specific. Native builds are unaffected: the K&R-loose prototype machinery still accepts the previous and the new code identically.
This commit is contained in:
parent
a1639cf08b
commit
5cf7c70662
|
|
@ -61,6 +61,74 @@ nullDoNothing()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Typed no-op stubs for WASM call_indirect type compatibility.
|
||||||
|
* WASM enforces exact type signatures at indirect call sites; assigning
|
||||||
|
* a 0-arg nullDoNothing to a pointer called with arguments causes a
|
||||||
|
* "null function or function signature mismatch" trap. These stubs
|
||||||
|
* have the correct arity so the WASM type check passes.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* 1-argument stub (int or pointer) */
|
||||||
|
static void
|
||||||
|
nullDoNothingI(int a)
|
||||||
|
{
|
||||||
|
(void) a;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 2-argument stub */
|
||||||
|
static void
|
||||||
|
nullDoNothingII(int a, int b)
|
||||||
|
{
|
||||||
|
(void) a; (void) b;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 4-argument stub */
|
||||||
|
static void
|
||||||
|
nullDoNothingIIII(int a, int b, int c, int d)
|
||||||
|
{
|
||||||
|
(void) a; (void) b; (void) c; (void) d;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 7-argument stub (for grFontTextPtr) */
|
||||||
|
static void
|
||||||
|
nullDoNothingIIIIIII(int a, int b, int c, int d, int e, int f, int g)
|
||||||
|
{
|
||||||
|
(void) a; (void) b; (void) c; (void) d; (void) e; (void) f; (void) g;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* bool-returning stubs — return FALSE so callers treat backing store / window
|
||||||
|
* creation as unavailable, which is correct for the headless null driver. */
|
||||||
|
static bool
|
||||||
|
nullReturnFalseI(int a)
|
||||||
|
{
|
||||||
|
(void) a;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
nullReturnFalseII(int a, int b)
|
||||||
|
{
|
||||||
|
(void) a; (void) b;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 3-argument bool-returning stub (for grDrawGridPtr) */
|
||||||
|
static bool
|
||||||
|
nullReturnFalseIII(int a, int b, int c)
|
||||||
|
{
|
||||||
|
(void) a; (void) b; (void) c;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 1-argument int-returning stub (for GrWindowIdPtr) */
|
||||||
|
static int
|
||||||
|
nullReturnZeroI(int a)
|
||||||
|
{
|
||||||
|
(void) a;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*---------------------------------------------------------
|
*---------------------------------------------------------
|
||||||
*
|
*
|
||||||
|
|
@ -246,8 +314,10 @@ nullSetDisplay(dispType, outFileName, mouseFileName)
|
||||||
{
|
{
|
||||||
TxPrintf("Using NULL graphics device.\n");
|
TxPrintf("Using NULL graphics device.\n");
|
||||||
|
|
||||||
|
#ifndef __EMSCRIPTEN__
|
||||||
TxAdd1InputDevice(fileno(stdin), nullStdin, (ClientData) NULL);
|
TxAdd1InputDevice(fileno(stdin), nullStdin, (ClientData) NULL);
|
||||||
if (TxStdinIsatty) SigWatchFile(fileno(stdin), "stdin");
|
if (TxStdinIsatty) SigWatchFile(fileno(stdin), "stdin");
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Set up the procedure values in the indirection table. */
|
/* Set up the procedure values in the indirection table. */
|
||||||
|
|
||||||
|
|
@ -259,25 +329,49 @@ nullSetDisplay(dispType, outFileName, mouseFileName)
|
||||||
|
|
||||||
GrEnableTabletPtr = nullDoNothing;
|
GrEnableTabletPtr = nullDoNothing;
|
||||||
GrDisableTabletPtr = nullDoNothing;
|
GrDisableTabletPtr = nullDoNothing;
|
||||||
GrSetCursorPtr = nullDoNothing;
|
GrSetCursorPtr = (void (*)()) nullDoNothingI;
|
||||||
GrTextSizePtr = NullTextSize;
|
GrTextSizePtr = NullTextSize;
|
||||||
GrDrawGlyphPtr = nullDoNothing;
|
GrDrawGlyphPtr = (void (*)()) nullDoNothingII;
|
||||||
GrBitBltPtr = NullBitBlt;
|
GrBitBltPtr = NullBitBlt;
|
||||||
GrReadPixelPtr = nullReturnZero;
|
GrReadPixelPtr = nullReturnZero;
|
||||||
GrFlushPtr = nullDoNothing;
|
GrFlushPtr = nullDoNothing;
|
||||||
|
|
||||||
|
/* Window management — null driver has no real windows; return FALSE so
|
||||||
|
* callers know the operation wasn't performed. */
|
||||||
|
GrCreateWindowPtr = NULL; /* headless: skip OS window creation, WindCreate stays OK */
|
||||||
|
GrDeleteWindowPtr = (void (*)()) nullDoNothingI;
|
||||||
|
GrConfigureWindowPtr = (void (*)()) nullDoNothingI;
|
||||||
|
GrOverWindowPtr = (void (*)()) nullDoNothingI;
|
||||||
|
GrUnderWindowPtr = (void (*)()) nullDoNothingI;
|
||||||
|
GrDamagedPtr = nullDoNothing;
|
||||||
|
GrUpdateIconPtr = (void (*)()) nullDoNothingII;
|
||||||
|
GrEventPendingPtr = (bool (*)()) nullReturnFalse;
|
||||||
|
GrWindowIdPtr = (int (*)()) nullReturnZeroI;
|
||||||
|
GrWindowNamePtr = NULL; /* protected by callers */
|
||||||
|
GrGetCursorPosPtr = (bool (*)()) nullReturnFalseII;
|
||||||
|
GrGetCursorRootPosPtr = (bool (*)()) nullReturnFalseII;
|
||||||
|
|
||||||
|
/* Backing store — not available in headless mode */
|
||||||
|
GrGetBackingStorePtr = (bool (*)()) nullReturnFalseII;
|
||||||
|
GrScrollBackingStorePtr = (bool (*)()) nullReturnFalseII;
|
||||||
|
GrPutBackingStorePtr = (void (*)()) nullDoNothingII;
|
||||||
|
GrFreeBackingStorePtr = (void (*)()) nullDoNothingI;
|
||||||
|
GrCreateBackingStorePtr = (void (*)()) nullDoNothingI;
|
||||||
|
|
||||||
/* local indirections */
|
/* local indirections */
|
||||||
grSetSPatternPtr = nullDoNothing;
|
grSetSPatternPtr = (void (*)()) nullDoNothingII;
|
||||||
grPutTextPtr = nullDoNothing;
|
grPutTextPtr = (void (*)()) nullDoNothingIIII;
|
||||||
grFontTextPtr = nullDoNothing;
|
grFontTextPtr = (void (*)()) nullDoNothingIIIIIII;
|
||||||
grDefineCursorPtr = nullDoNothing;
|
grDefineCursorPtr = (void (*)()) nullDoNothingI;
|
||||||
grDrawGridPtr = nullReturnFalse;
|
grFreeCursorPtr = (void (*)()) nullDoNothingI;
|
||||||
grDrawLinePtr = nullDoNothing;
|
grDrawGridPtr = (bool (*)()) nullReturnFalseIII;
|
||||||
grSetWMandCPtr = nullDoNothing;
|
grDrawLinePtr = (void (*)()) nullDoNothingIIII;
|
||||||
grFillRectPtr = nullDoNothing;
|
grSetWMandCPtr = (void (*)()) nullDoNothingII;
|
||||||
grSetStipplePtr = nullDoNothing;
|
grFillRectPtr = (void (*)()) nullDoNothingI;
|
||||||
grSetLineStylePtr = nullDoNothing;
|
grFillPolygonPtr = (void (*)()) nullDoNothingII;
|
||||||
grSetCharSizePtr = nullDoNothing;
|
grSetStipplePtr = (void (*)()) nullDoNothingI;
|
||||||
|
grSetLineStylePtr = (void (*)()) nullDoNothingI;
|
||||||
|
grSetCharSizePtr = (void (*)()) nullDoNothingI;
|
||||||
|
|
||||||
GrScreenRect.r_xtop = 511;
|
GrScreenRect.r_xtop = 511;
|
||||||
GrScreenRect.r_ytop = 483;
|
GrScreenRect.r_ytop = 483;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue