summaryrefslogtreecommitdiffstats
path: root/ffi.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2017-06-21 22:26:47 -0700
committerKaz Kylheku <kaz@kylheku.com>2017-06-21 22:26:47 -0700
commit6faa3362efe19984e428f15e92c6631654e1dd40 (patch)
tree4c93279bd8ccb6aaf127e50c713d06443454042c /ffi.c
parent2619181c7f4139af56f2fce340d2b0046b12d552 (diff)
downloadtxr-6faa3362efe19984e428f15e92c6631654e1dd40.tar.gz
txr-6faa3362efe19984e428f15e92c6631654e1dd40.tar.bz2
txr-6faa3362efe19984e428f15e92c6631654e1dd40.zip
ffi: override libffi size/alignment calculations.
Don't bother creating and filling the ffi_type elements[] array for a structs or array. Let's punch in the size and alignment fields with the values we calculate ourselves already, and set up a dummy elements[] array that contains only a null terminator. * ffi.c (struct txr_ffi_type): New member, elements: one element dummy array that holds a null pointer. (ffi_type_struct_destroy_op): Do not free ft->elements, since it isn't dynamically allocated any more. (ffi_struct_clone, ffi_array_clone): Don't copy the elements array; just set up a dummy elements array in the copied type. (make_ffi_type_struct, make_ffi_type_array): Eliminate the dynamic allocation of the elements array. Point ft->elements to the dummy array. Set up the ft->size and ft->alignment.
Diffstat (limited to 'ffi.c')
-rw-r--r--ffi.c67
1 files changed, 16 insertions, 51 deletions
diff --git a/ffi.c b/ffi.c
index de71d9a8..1b8aaf7b 100644
--- a/ffi.c
+++ b/ffi.c
@@ -159,6 +159,7 @@ struct smemb {
struct txr_ffi_type {
ffi_type *ft;
+ ffi_type *elements[1];
val lt;
val syntax;
val eltype;
@@ -225,7 +226,6 @@ static void ffi_type_struct_destroy_op(val obj)
#endif
#if HAVE_LIBFFI
- free(ft->elements);
ft->elements = 0;
free(ft);
tft->ft = 0;
@@ -2725,18 +2725,13 @@ static struct txr_ffi_type *ffi_struct_clone(struct txr_ffi_type *orig)
{
cnum nmemb = orig->nelem;
struct txr_ffi_type *copy = ffi_simple_clone(orig);
-#if HAVE_LIBFFI
- size_t elements_size = sizeof *orig->ft->elements * (nmemb + 1);
-#endif
size_t memb_size = sizeof *orig->memb * nmemb;
ffi_type *ft = coerce(ffi_type *, chk_copy_obj(coerce(mem_t *, orig->ft),
sizeof *orig->ft));
copy->ft = ft;
#if HAVE_LIBFFI
- ft->elements = coerce(ffi_type **, chk_copy_obj(coerce(mem_t *,
- ft->elements),
- elements_size));
+ ft->elements = copy->elements;
#endif
copy->memb = coerce(struct smemb *, chk_copy_obj(coerce(mem_t *,
orig->memb),
@@ -2748,16 +2743,11 @@ static struct txr_ffi_type *ffi_struct_clone(struct txr_ffi_type *orig)
static val make_ffi_type_struct(val syntax, val lisp_type,
val slots, val types)
{
- val self = lit("ffi-type-compile");
struct txr_ffi_type *tft = coerce(struct txr_ffi_type *,
chk_calloc(1, sizeof *tft));
ffi_type *ft = coerce(ffi_type *, chk_calloc(1, sizeof *ft));
cnum nmemb = c_num(length(types)), i;
-#if HAVE_LIBFFI
- ffi_type **elements = coerce(ffi_type **,
- chk_xalloc(sizeof *elements, (nmemb + 1), self));
-#endif
struct smemb *memb = coerce(struct smemb *,
chk_calloc(nmemb, sizeof *memb));
val obj = cobj(coerce(mem_t *, tft), ffi_type_s, &ffi_type_struct_ops);
@@ -2767,9 +2757,6 @@ static val make_ffi_type_struct(val syntax, val lisp_type,
int bit_offs = 0;
const unsigned bits_int = 8 * sizeof(int);
- ft->type = FFI_TYPE_STRUCT;
- ft->size = 0;
-
tft->ft = ft;
tft->syntax = syntax;
tft->lt = lisp_type;
@@ -2789,10 +2776,6 @@ static val make_ffi_type_struct(val syntax, val lisp_type,
struct txr_ffi_type *mtft = ffi_type_struct(type);
cnum size = mtft->size;
-#if HAVE_LIBFFI
- elements[i] = mtft->ft;
-#endif
-
memb[i].mtype = type;
memb[i].mname = slot;
memb[i].mtft = mtft;
@@ -2867,38 +2850,31 @@ static val make_ffi_type_struct(val syntax, val lisp_type,
tft->nelem = i;
-#if HAVE_LIBFFI
- elements[i] = 0;
-#endif
-
if (need_out_handler)
tft->out = ffi_struct_out;
-#if HAVE_LIBFFI
- ft->elements = elements;
-#endif
-
tft->size = (offs + most_align - 1) & ~(most_align - 1);
tft->align = most_align;
+#if HAVE_LIBFFI
+ ft->type = FFI_TYPE_STRUCT;
+ ft->size = tft->size;
+ ft->alignment = tft->align;
+ ft->elements = tft->elements;
+#endif
+
return obj;
}
static struct txr_ffi_type *ffi_array_clone(struct txr_ffi_type *orig)
{
struct txr_ffi_type *copy = ffi_simple_clone(orig);
-#if HAVE_LIBFFI
- cnum nmemb = orig->nelem;
- size_t elements_size = sizeof *orig->ft->elements * (nmemb + 1);
-#endif
ffi_type *ft = coerce(ffi_type *, chk_copy_obj(coerce(mem_t *, orig->ft),
sizeof *orig->ft));
copy->ft = ft;
#if HAVE_LIBFFI
- ft->elements = coerce(ffi_type **, chk_copy_obj(coerce(mem_t *,
- ft->elements),
- elements_size));
+ ft->elements = copy->elements;
#endif
return copy;
}
@@ -2909,20 +2885,11 @@ static val make_ffi_type_array(val syntax, val lisp_type,
struct txr_ffi_type *tft = coerce(struct txr_ffi_type *,
chk_calloc(1, sizeof *tft));
ffi_type *ft = coerce(ffi_type *, chk_calloc(1, sizeof *ft));
-
cnum nelem = c_num(dim), i;
-#if HAVE_LIBFFI
- ffi_type **elements = coerce(ffi_type **, chk_xalloc((nelem + 1),
- sizeof *elements,
- self));
-#endif
val obj = cobj(coerce(mem_t *, tft), ffi_type_s, &ffi_type_struct_ops);
struct txr_ffi_type *etft = ffi_type_struct(eltype);
- ft->type = FFI_TYPE_STRUCT;
- ft->size = 0;
-
tft->ft = ft;
tft->syntax = syntax;
tft->lt = lisp_type;
@@ -2936,9 +2903,6 @@ static val make_ffi_type_array(val syntax, val lisp_type,
tft->free = free;
for (i = 0; i < nelem; i++) {
-#if HAVE_LIBFFI
- elements[i] = etft->ft;
-#endif
if (i == 0) {
tft->size = etft->size * nelem;
tft->align = etft->align;
@@ -2947,14 +2911,15 @@ static val make_ffi_type_array(val syntax, val lisp_type,
}
}
-#if HAVE_LIBFFI
- elements[i] = 0;
+ tft->nelem = nelem;
- ft->elements = elements;
+#if HAVE_LIBFFI
+ ft->type = FFI_TYPE_STRUCT;
+ ft->size = etft->size * nelem;
+ ft->alignment = etft->align;
+ ft->elements = tft->elements;
#endif
- tft->nelem = nelem;
-
return obj;
}