From 581d95e976938d62e79a54af2dd1c23955201b11 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Sun, 7 May 2017 08:56:03 -0700 Subject: ffi: bugfix: all out calls must fall back on put. * ffi.c (ffi_struct_out, ffi_array_out): For any element which has no out function, do a put if the copy flag is true. Otherwise callbacks cannot update members in aggregates passed by pointer. --- ffi.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/ffi.c b/ffi.c index 6c366738..1a9ebb01 100644 --- a/ffi.c +++ b/ffi.c @@ -909,13 +909,16 @@ static void ffi_struct_out(struct txr_ffi_type *tft, int copy, val strct, struct txr_ffi_type *mtft = ffi_type_struct(type); ucnum almask = mtft->align - 1; offs = (offs + almask) & ~almask; - if (mtft->out != 0) { - if (slsym) { + if (slsym) { + if (mtft->out != 0) { val slval = slot(strct, slsym); mtft->out(mtft, copy, slval, dst + offs, self); - } else { - memset(dst + offs, 0, mtft->size); + } else if (copy) { + val slval = slot(strct, slsym); + mtft->put(mtft, slval, dst + offs, self); } + } else if (copy) { + memset(dst + offs, 0, mtft->size); } offs += mtft->size; } @@ -1061,6 +1064,9 @@ static void ffi_array_out(struct txr_ffi_type *tft, int copy, val vec, if (etft->out != 0) { val elval = ref(vec, num_fast(i)); etft->out(etft, copy, elval, dst + offs, self); + } else if (copy) { + val elval = ref(vec, num_fast(i)); + etft->put(etft, elval, dst + offs, self); } offs += elsize; } -- cgit v1.2.3