diff options
author | Cheng Shao <astrohavoc@gmail.com> | 2022-10-23 16:11:17 +0000 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2022-11-11 00:26:55 -0500 |
commit | 88bbdb3186f39c878677f03dbb5fd91a03632be7 (patch) | |
tree | 2052476c46554e33651189a7414b1babb3e81fb0 | |
parent | 0e33f66792bda2a1ced88db3ebf4689d8cfead31 (diff) | |
download | haskell-88bbdb3186f39c878677f03dbb5fd91a03632be7.tar.gz |
rts: LibffiAdjustor: adapt to ffi_alloc_prep_closure interface for wasm32
libffi-wasm32 only supports non-standard libffi closure api via
ffi_alloc_prep_closure(). This patch implements
ffi_alloc_prep_closure() via standard libffi closure api on other
targets, and uses it to implement adjustor functionality.
-rw-r--r-- | rts/adjustor/LibffiAdjustor.c | 34 |
1 files changed, 24 insertions, 10 deletions
diff --git a/rts/adjustor/LibffiAdjustor.c b/rts/adjustor/LibffiAdjustor.c index e24a4a12f7..292c5c7496 100644 --- a/rts/adjustor/LibffiAdjustor.c +++ b/rts/adjustor/LibffiAdjustor.c @@ -14,6 +14,20 @@ #include "ffi.h" #include <string.h> +// Note that ffi_alloc_prep_closure is a non-standard libffi closure +// API that is only provided by libffi-wasm32, not upstream libffi. +#if !defined(wasm32_HOST_ARCH) + +static ffi_status ffi_alloc_prep_closure(ffi_closure **pclosure, ffi_cif *cif, + void (*fun)(ffi_cif *cif, void *ret, + void **args, void *user_data), + void *user_data, void **code) { + *pclosure = ffi_closure_alloc(sizeof(ffi_closure), code); + return ffi_prep_closure_loc(*pclosure, cif, fun, user_data, *code); +} + +#endif + /* Maps AdjustorExecutable* to AdjustorWritable*. */ static HashTable* allocatedExecs; @@ -21,17 +35,20 @@ void initAdjustors() { allocatedExecs = allocHashTable(); } -static AdjustorWritable allocate_adjustor(AdjustorExecutable *exec_ret) +static AdjustorWritable allocate_adjustor(AdjustorExecutable *exec_ret, ffi_cif *cif, void *wptr, void *hptr) { AdjustorWritable writ; - ffi_closure* cl; - ACQUIRE_SM_LOCK; - cl = writ = ffi_closure_alloc(sizeof(ffi_closure), exec_ret); - if (cl != NULL) { + ffi_status r = ffi_alloc_prep_closure(&writ, cif, wptr, hptr, exec_ret); + if (r != FFI_OK) + barf("ffi_alloc_prep_closure failed: %d", r); + + if (*exec_ret != NULL) { + ACQUIRE_SM_LOCK; insertHashTable(allocatedExecs, (StgWord)*exec_ret, writ); + RELEASE_SM_LOCK; } - RELEASE_SM_LOCK; + return writ; } @@ -165,13 +182,10 @@ createAdjustor (int cconv, r = ffi_prep_cif(cif, abi, n_args, result_type, arg_types); if (r != FFI_OK) barf("ffi_prep_cif failed: %d", r); - cl = allocate_adjustor(&code); + cl = allocate_adjustor(&code, cif, wptr, hptr); if (cl == NULL) { barf("createAdjustor: failed to allocate memory"); } - r = ffi_prep_closure_loc(cl, cif, (void*)wptr, hptr/*userdata*/, code); - if (r != FFI_OK) barf("ffi_prep_closure_loc failed: %d", r); - return (void*)code; } |