summaryrefslogtreecommitdiffstats
path: root/ffi.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2017-06-27 06:04:24 -0700
committerKaz Kylheku <kaz@kylheku.com>2017-06-27 06:04:24 -0700
commit7e915426a84cc4dd87743d0c1aa19e462895cc94 (patch)
treede31371581acf07550d8f2c011372bfae30a44aa /ffi.c
parent39a889bb8b7794cda6b967acbd4222486f318104 (diff)
downloadtxr-7e915426a84cc4dd87743d0c1aa19e462895cc94.tar.gz
txr-7e915426a84cc4dd87743d0c1aa19e462895cc94.tar.bz2
txr-7e915426a84cc4dd87743d0c1aa19e462895cc94.zip
ffi: add missing rput/rget ops for big endian.
We either mishandle return values, or crash due to a null rput/rget function pointers on aggregate types and bools. * ffi.c (ffi_bool_rput, ffi_bool_rget): New static functions. (make_ffi_type_pointer, make_ffi_type_struct, make_ffi_type_union, make_ffi_type_array): Fill in rput and rget. (ffi_type_compile): Fill in rget and rput for bool with new functions.
Diffstat (limited to 'ffi.c')
-rw-r--r--ffi.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/ffi.c b/ffi.c
index 0d531724..a555168b 100644
--- a/ffi.c
+++ b/ffi.c
@@ -1751,6 +1751,21 @@ static val ffi_le_u32_rget(struct txr_ffi_type *tft, mem_t *src, val self)
return ffi_le_u32_get(tft, src + 4, self);
}
+static void ffi_bool_rput(struct txr_ffi_type *tft, val truth,
+ mem_t *dst, val self)
+{
+ val n = truth ? one : zero;
+ struct txr_ffi_type *tgtft = ffi_type_struct(tft->eltype);
+ tgtft->rput(tft, n, dst, self); /* tft deliberate */
+}
+
+static val ffi_bool_rget(struct txr_ffi_type *tft, mem_t *src, val self)
+{
+ struct txr_ffi_type *tgtft = ffi_type_struct(tft->eltype);
+ val n = tgtft->rget(tft, src, self); /* tft deliberate */
+ return null(zerop(n));
+}
+
#endif
static void ffi_cptr_put(struct txr_ffi_type *tft, val n, mem_t *dst,
@@ -2772,6 +2787,10 @@ static val make_ffi_type_pointer(val syntax, val lisp_type,
tft->clone = ffi_simple_clone;
tft->put = put;
tft->get = get;
+#if !HAVE_LITTLE_ENDIAN
+ tft->rput = put;
+ tft->rget = get;
+#endif
tft->eltype = tgtype;
tft->in = in;
tft->out = out;
@@ -2828,6 +2847,10 @@ static val make_ffi_type_struct(val syntax, val lisp_type,
tft->clone = ffi_struct_clone;
tft->put = ffi_struct_put;
tft->get = ffi_struct_get;
+#if !HAVE_LITTLE_ENDIAN
+ tft->rput = ffi_struct_put;
+ tft->rget = ffi_struct_get;
+#endif
tft->in = ffi_struct_in;
tft->release = ffi_struct_release;
tft->alloc = ffi_fixed_alloc;
@@ -2956,6 +2979,10 @@ static val make_ffi_type_union(val syntax, val lisp_type,
tft->clone = ffi_struct_clone;
tft->put = ffi_union_put;
tft->get = ffi_union_get;
+#if !HAVE_LITTLE_ENDIAN
+ tft->rput = ffi_union_put;
+ tft->rget = ffi_union_get;
+#endif
tft->in = ffi_union_in;
tft->alloc = ffi_fixed_alloc;
tft->free = free;
@@ -3045,6 +3072,10 @@ static val make_ffi_type_array(val syntax, val lisp_type,
tft->clone = ffi_array_clone;
tft->put = ffi_array_put;
tft->get = ffi_array_get;
+#if !HAVE_LITTLE_ENDIAN
+ tft->rput = ffi_array_put;
+ tft->rget = ffi_array_get;
+#endif
tft->in = ffi_array_in;
tft->release = ffi_array_release;
tft->alloc = ffi_fixed_alloc;
@@ -3469,6 +3500,10 @@ val ffi_type_compile(val syntax)
tft->eltype = type;
tft->get = ffi_bool_get;
tft->put = ffi_bool_put;
+#if !HAVE_LITTLE_ENDIAN
+ tft->rget = ffi_bool_rget;
+ tft->rput = ffi_bool_rput;
+#endif
return type_copy;
}