summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2022-05-20 06:34:34 -0700
committerKaz Kylheku <kaz@kylheku.com>2022-05-20 06:34:34 -0700
commit1c70056c20ad0001b45daa7289c01d0eb3577211 (patch)
treee3a4467d31d5baa1f435da4859487af806b8a7c7
parent8a6c4b6749a94b3adae46e20de577918ca9d8c59 (diff)
downloadtxr-1c70056c20ad0001b45daa7289c01d0eb3577211.tar.gz
txr-1c70056c20ad0001b45daa7289c01d0eb3577211.tar.bz2
txr-1c70056c20ad0001b45daa7289c01d0eb3577211.zip
ffi: pack: implement documented align transformation.
* ffi.c (ffi_pack_members): Static function removed. (ffi_transform_pack): New static function. (ffi_type_compile): Rely on ffi_transform_pack to recognize and perform all necessary transformations. Cosmetic issue: when a struct is compiled, and the individual member types undergo transformation during member compilation, the syntax for the struct is nevertheless the original one with the untransformed members.
-rw-r--r--ffi.c51
1 files changed, 32 insertions, 19 deletions
diff --git a/ffi.c b/ffi.c
index 437713d7..e0276ec7 100644
--- a/ffi.c
+++ b/ffi.c
@@ -3923,26 +3923,41 @@ static val ffi_struct_init(val slot_init, val strct)
return nil;
}
-static val ffi_pack_members(val struct_syntax, val align)
+static val ffi_transform_pack(val syntax, val align)
{
- val op = pop(&struct_syntax);
- val name = pop(&struct_syntax);
- val iter;
- list_collect_decl (packed, ptail);
+ val op = pop(&syntax);
- for (iter = struct_syntax; iter; iter = cdr(iter)) {
- val slot_spec = car(iter);
- val slot = car(slot_spec);
- val type = cadr(slot_spec);
- val init = caddr(slot_spec);
- val packed_type = list(pack_s, align, type, nao);
+ if (op == struct_s || op == union_s)
+ {
+ val name = pop(&syntax);
+ val iter;
+ list_collect_decl (packed, ptail);
+
+ for (iter = syntax; iter; iter = cdr(iter)) {
+ val slot_spec = car(iter);
+ val slot = car(slot_spec);
+ val type = cadr(slot_spec);
+ val init = caddr(slot_spec);
+ val packed_type = list(pack_s, align, type, nao);
+
+ ptail = list_collect(ptail, if3(init,
+ list(slot, packed_type, init, nao),
+ list(slot, packed_type, nao)));
+ }
- ptail = list_collect(ptail, if3(init,
- list(slot, packed_type, init, nao),
- list(slot, packed_type, nao)));
+ return cons(op, cons(name, packed));
+ } else if (op == align_s) {
+ if (length(syntax) == one) {
+ val type = car(syntax);
+ return list(align_s, list(pack_s, align, type, nao), nao);
+ } else if (length(syntax) == two) {
+ val align = car(syntax);
+ val type = cadr(syntax);
+ return list(align_s, align, list(pack_s, align, type, nao), nao);
+ }
}
- return cons(op, cons(name, packed));
+ return syntax;
}
val ffi_type_compile(val syntax)
@@ -4334,10 +4349,8 @@ val ffi_type_compile(val syntax)
self, nao);
} else {
val alsyntax = if3(twoarg, cadr(syntax), caddr(syntax));
- val xalsyntax = if3(sym == pack_s && consp(alsyntax) &&
- (car(alsyntax) == struct_s ||
- car(alsyntax) == union_s),
- ffi_pack_members(alsyntax, align),
+ val xalsyntax = if3(sym == pack_s && consp(alsyntax),
+ ffi_transform_pack(alsyntax, align),
alsyntax);
val altype = ffi_type_compile(xalsyntax);
if (xalsyntax != alsyntax) {