summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2017-04-30 22:59:37 -0700
committerKaz Kylheku <kaz@kylheku.com>2017-04-30 22:59:37 -0700
commit00bcc66f6e651f9f2a4b3b0caea2cad4e79e5f11 (patch)
treec6b9a53c74160f22dc049f9234d91e55dd10164a
parent32c85433deff6bbc19edba5e7903b162d8a27a47 (diff)
downloadtxr-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.c21
1 files 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;
}
}