mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-04-30 20:00:19 +02:00
FFI: Return the right alignment for structures.
* libguile/foreign.c (scm_alignof): Fix handling of structure alignment. Reported by Aidan Gauland <aidalgol@no8wireless.co.nz>. * test-suite/tests/foreign.test ("structs")["alignof { int8, double, int8 }", "int8, { int8, double, int8 }, int16"]: New tests.
This commit is contained in:
parent
dd36ce77cd
commit
d82f8518b9
2 changed files with 30 additions and 2 deletions
|
@ -402,8 +402,24 @@ SCM_DEFINE (scm_alignof, "alignof", 1, 0, 0, (SCM type),
|
||||||
/* a pointer */
|
/* a pointer */
|
||||||
return scm_from_size_t (alignof (void*));
|
return scm_from_size_t (alignof (void*));
|
||||||
else if (scm_is_pair (type))
|
else if (scm_is_pair (type))
|
||||||
/* a struct, yo */
|
{
|
||||||
return scm_alignof (scm_car (type));
|
/* TYPE is a structure. Section 3-3 of the i386, x86_64, PowerPC,
|
||||||
|
and SPARC P.S. of the System V ABI all say: "Aggregates
|
||||||
|
(structures and arrays) and unions assume the alignment of
|
||||||
|
their most strictly aligned component." */
|
||||||
|
size_t max;
|
||||||
|
|
||||||
|
for (max = 0; scm_is_pair (type); type = SCM_CDR (type))
|
||||||
|
{
|
||||||
|
size_t align;
|
||||||
|
|
||||||
|
align = scm_to_size_t (scm_alignof (SCM_CAR (type)));
|
||||||
|
if (align > max)
|
||||||
|
max = align;
|
||||||
|
}
|
||||||
|
|
||||||
|
return scm_from_size_t (max);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
scm_wrong_type_arg (FUNC_NAME, 1, type);
|
scm_wrong_type_arg (FUNC_NAME, 1, type);
|
||||||
}
|
}
|
||||||
|
|
|
@ -228,6 +228,11 @@
|
||||||
(>= (sizeof layout)
|
(>= (sizeof layout)
|
||||||
(reduce + 0.0 (map sizeof layout)))))
|
(reduce + 0.0 (map sizeof layout)))))
|
||||||
|
|
||||||
|
(pass-if "alignof { int8, double, int8 }"
|
||||||
|
;; alignment of the most strictly aligned component
|
||||||
|
(let ((layout (list int8 double int8)))
|
||||||
|
(= (alignof layout) (alignof double))))
|
||||||
|
|
||||||
(pass-if "parse-c-struct"
|
(pass-if "parse-c-struct"
|
||||||
(let ((layout (list int64 uint8))
|
(let ((layout (list int64 uint8))
|
||||||
(data (list -300 43)))
|
(data (list -300 43)))
|
||||||
|
@ -266,6 +271,13 @@
|
||||||
(pass-if "int8, pointer, short, double"
|
(pass-if "int8, pointer, short, double"
|
||||||
(let ((layout (list int8 '* short double))
|
(let ((layout (list int8 '* short double))
|
||||||
(data (list 77 %null-pointer -42 3.14)))
|
(data (list 77 %null-pointer -42 3.14)))
|
||||||
|
(equal? (parse-c-struct (make-c-struct layout data)
|
||||||
|
layout)
|
||||||
|
data)))
|
||||||
|
|
||||||
|
(pass-if "int8, { int8, double, int8 }, int16"
|
||||||
|
(let ((layout (list int8 (list int8 double int8) int16))
|
||||||
|
(data (list 77 (list 42 4.2 55) 88)))
|
||||||
(equal? (parse-c-struct (make-c-struct layout data)
|
(equal? (parse-c-struct (make-c-struct layout data)
|
||||||
layout)
|
layout)
|
||||||
data))))
|
data))))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue