summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCheng Shao <astrohavoc@gmail.com>2022-10-23 16:11:17 +0000
committerMarge Bot <ben+marge-bot@smart-cactus.org>2022-11-11 00:26:55 -0500
commit88bbdb3186f39c878677f03dbb5fd91a03632be7 (patch)
tree2052476c46554e33651189a7414b1babb3e81fb0
parent0e33f66792bda2a1ced88db3ebf4689d8cfead31 (diff)
downloadhaskell-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.c34
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;
}