summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2017-05-25 19:06:25 -0700
committerKaz Kylheku <kaz@kylheku.com>2017-05-25 19:06:25 -0700
commit860d69fc371cdddce1b4db1409201ecd67c88be6 (patch)
treeae4b87229be6da86174a5f8ea6264decdad52edb
parentbd7f295779e95d92ea702851c70b06f332c5a20f (diff)
downloadtxr-860d69fc371cdddce1b4db1409201ecd67c88be6.tar.gz
txr-860d69fc371cdddce1b4db1409201ecd67c88be6.tar.bz2
txr-860d69fc371cdddce1b4db1409201ecd67c88be6.zip
ffi: bugfix: gc-correct handling of memb array.
* ffi.c (make_ffi_type_struct): Use calloc for allocating memb, so all the Lisp objects in it are initially nil. Then install it into the structure upfront. Afterward, as we iterate over the slots and types and install them into the array, we lose references to them. But now since the array is now wired into the FFI struct type structure, these objects are now visible to GC.
-rw-r--r--ffi.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/ffi.c b/ffi.c
index 6e71e743..79f71538 100644
--- a/ffi.c
+++ b/ffi.c
@@ -1514,7 +1514,7 @@ static val make_ffi_type_struct(val syntax, val lisp_type,
ffi_type **elements = coerce(ffi_type **,
chk_malloc(sizeof *elements * (nmemb + 1)));
struct smemb *memb = coerce(struct smemb *,
- chk_malloc(sizeof *memb * nmemb));
+ chk_calloc(nmemb, sizeof *memb));
val obj = cobj(coerce(mem_t *, tft), ffi_type_s, &ffi_type_struct_ops);
ucnum offs = 0;
ucnum most_align = 0;
@@ -1533,6 +1533,7 @@ static val make_ffi_type_struct(val syntax, val lisp_type,
tft->release = ffi_struct_release;
tft->alloc = ffi_fixed_alloc;
tft->free = free;
+ tft->memb = memb;
for (i = 0; i < nmemb; i++) {
val type = pop(&types);
@@ -1567,7 +1568,6 @@ static val make_ffi_type_struct(val syntax, val lisp_type,
tft->size = (offs + most_align - 1) & ~(most_align - 1);
tft->align = most_align;
- tft->memb = memb;
return obj;
}