From 232fcde308ae018764e5d54945a807d6a8097b0f Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Sun, 30 Apr 2017 22:59:37 -0700 Subject: ffi: support anonymous padding in structs. If the ffi struct type operator specifies nil as a slot name, then we treat the member as anonymous padding. When reading a struct from a buffer, we skip the padding. When writing out a struct to a buffer, we generate zeros in the size of the anonymous member. The type of the member is ignored, except for calculating the size. * ffi.c (ffi_struct_put): If the slot name is nil, don't recursively call put; just use memset to fill the target with zero bytes. (ffi_struct_get, ffi_struct_fill): If the slot name is nil, don't call get to fetch data. Just skip the area. --- ffi.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/ffi.c b/ffi.c index 272ea9d7..e9c95f48 100644 --- a/ffi.c +++ b/ffi.c @@ -963,11 +963,15 @@ static void ffi_struct_put(struct txr_ffi_type *tft, val strct, mem_t *dst, while (slots) { val slsym = pop(&slots); val type = pop(&types); - val slval = slot(strct, slsym); struct txr_ffi_type *mtft = ffi_type_struct(type); ucnum almask = mtft->align - 1; offs = (offs + almask) & ~almask; - mtft->put(mtft, slval, dst + offs, rtvec, self); + if (slsym) { + val slval = slot(strct, slsym); + mtft->put(mtft, slval, dst + offs, rtvec, self); + } else { + memset(dst + offs, 0, mtft->size); + } offs += mtft->size; } } @@ -985,10 +989,11 @@ static val ffi_struct_get(struct txr_ffi_type *tft, mem_t *src, val self) val type = pop(&types); struct txr_ffi_type *mtft = ffi_type_struct(type); ucnum almask = mtft->align - 1; - val slval; offs = (offs + almask) & ~almask; - slval = mtft->get(mtft, src + offs, self); - slotset(strct, slsym, slval); + if (slsym) { + val slval = mtft->get(mtft, src + offs, self); + slotset(strct, slsym, slval); + } offs += mtft->size; } @@ -1009,8 +1014,10 @@ static void ffi_struct_fill(struct txr_ffi_type *tft, mem_t *src, ucnum almask = mtft->align - 1; val slval; offs = (offs + almask) & ~almask; - slval = mtft->get(mtft, src + offs, self); - slotset(strct, slsym, slval); + if (slsym) { + slval = mtft->get(mtft, src + offs, self); + slotset(strct, slsym, slval); + } offs += mtft->size; } } -- cgit v1.2.3