diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2017-04-30 22:59:37 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2017-04-30 22:59:37 -0700 |
commit | 00bcc66f6e651f9f2a4b3b0caea2cad4e79e5f11 (patch) | |
tree | c6b9a53c74160f22dc049f9234d91e55dd10164a | |
parent | 32c85433deff6bbc19edba5e7903b162d8a27a47 (diff) | |
download | txr-00bcc66f6e651f9f2a4b3b0caea2cad4e79e5f11.tar.gz txr-00bcc66f6e651f9f2a4b3b0caea2cad4e79e5f11.tar.bz2 txr-00bcc66f6e651f9f2a4b3b0caea2cad4e79e5f11.zip |
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.
-rw-r--r-- | ffi.c | 21 |
1 files changed, 14 insertions, 7 deletions
@@ -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; } } |