summaryrefslogtreecommitdiffstats
path: root/ffi.c
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 /ffi.c
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.
Diffstat (limited to 'ffi.c')
-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) {