diff options
author | Cheng Shao <astrohavoc@gmail.com> | 2022-10-21 13:47:58 +0000 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2022-11-11 00:26:55 -0500 |
commit | 07e92c92673c48db0325f101d07d73134ed79fe9 (patch) | |
tree | 26554fec5e7cc1c27108e76b3adbc6b3aefd73ff /rts/StgMiscClosures.cmm | |
parent | 32ae62e61e811bf99def141a388a3f0abc8b7107 (diff) | |
download | haskell-07e92c92673c48db0325f101d07d73134ed79fe9.tar.gz |
rts: workaround cmm's improper variadic ccall breaking wasm32 typechecking
Unlike other targets, wasm requires the function signature of the call
site and callee to strictly match. So in Cmm, when we call a C
function that actually returns a value, we need to add an _unused
local variable to receive it, otherwise type error awaits.
An even bigger problem is calling variadic functions like barf() and
such. Cmm doesn't support CAPI calling convention yet, so calls to
variadic functions just happen to work in some cases with some
target's ABI. But again, it doesn't work with wasm. Fortunately, the
wasm C ABI lowers varargs to a stack pointer argument, and it can be
passed NULL when no other arguments are expected to be passed. So we
also add the additional unused NULL arguments to those functions, so
to fix wasm, while not affecting behavior on other targets.
Diffstat (limited to 'rts/StgMiscClosures.cmm')
-rw-r--r-- | rts/StgMiscClosures.cmm | 6 |
1 files changed, 4 insertions, 2 deletions
diff --git a/rts/StgMiscClosures.cmm b/rts/StgMiscClosures.cmm index 20dc531a80..013db8731b 100644 --- a/rts/StgMiscClosures.cmm +++ b/rts/StgMiscClosures.cmm @@ -76,6 +76,8 @@ INFO_TABLE_RET (stg_stack_underflow_frame, UNDERFLOW_FRAME, INFO_TABLE_RET (stg_restore_cccs, RET_SMALL, W_ info_ptr, W_ cccs) { + W_ _unused; + unwind Sp = Sp + WDS(2); #if defined(PROFILING) CCCS = Sp(1); @@ -83,7 +85,7 @@ INFO_TABLE_RET (stg_restore_cccs, RET_SMALL, W_ info_ptr, W_ cccs) Sp_adj(2); IF_DEBUG(sanity, - ccall checkStackFrame(Sp "ptr")); + (_unused) = ccall checkStackFrame(Sp "ptr")); jump %ENTRY_CODE(Sp(0)) [*]; // NB. all registers live! } @@ -448,7 +450,7 @@ INFO_TABLE_RET( stg_dead_thread, RET_SMALL, W_ info_ptr, PROF_HDR_FIELDS(W_,p1,p2) P_ result ) -{ foreign "C" barf("stg_dead_thread entered!") never returns; } +{ foreign "C" barf("stg_dead_thread entered!", NULL) never returns; } /* ---------------------------------------------------------------------------- Entry code for a BCO |