summaryrefslogtreecommitdiffstats
path: root/txr.1
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2019-07-20 16:39:12 -0700
committerKaz Kylheku <kaz@kylheku.com>2019-07-20 16:39:12 -0700
commit54adf777ed9e1ce358848b4477a69dd59b5f0753 (patch)
tree688c0f29e4928b4c2b930ee1b2958801c2fa6a43 /txr.1
parenta07d183cf7215271fcc5ca60ec55273607419e3b (diff)
downloadtxr-54adf777ed9e1ce358848b4477a69dd59b5f0753.tar.gz
txr-54adf777ed9e1ce358848b4477a69dd59b5f0753.tar.bz2
txr-54adf777ed9e1ce358848b4477a69dd59b5f0753.zip
ffi: support flexible structures.
This commit adds support for working with foreign structures which use the C99 "flexible array member", or possibly the old "C struct hack". Some improvements are made in the FFI code the area of incomplete types and bitfields. * ffi.c (struct txr_ffi_type): New flag members incomplete and bitfield. (ffi_varray_dynsize): Check incomplete type flag rather than for zero size. (ffi_flex_dynsize, ffi_flex_alloc, ffi_flex_struct_in): New static functions. (ffi_struct_in): Call ffi_flex_struct_in when doing by-value semantics on a flexible structure, just before converting last member. This checks for the length method, calls it, and adjusts the last member object as documented. (ffi_struct_get): Likewise. (bitfield_syntax_p): Static function removed; there is a flag for this now in the type, so no need to parse its syntax. (make_ffi_type_pointer): Test bitfield flag rather than using bitfield_syntax_p. (make_ffi_type_struct): Take new argument indicating that the struct is flexible. Wire in appropriate virtual functions based on this flag, and set the type's incomplete flag accordingly. Check bitfield flag rather than using bitfield_syntax_p for detecting bitfield members. Calculate the size of flexible struct differently: it is the offset of the last member. (make_ffi_type_union): Test bitfield flag rather than using bitfield_syntax_p. (ffi_struct_compile): Renamed to ffi_membs_compile. (ffi_membs_compile): New pointer parameter for returning an indication whether the member list specifies a flexible struct. Test the incomplete flag of a member type rather than size being zero. (ffi_type_compile): Follow rename of ffi_struct_compile to ffi_membs_compile. Pass down the flag obtained from ffi_membs_compile into make_ffi_type_struct so that a flexible struct type is created when necessary. Disallow arrays of bitfields. Set bitfield flag on bitfield types. (ffi_init_types): Set incomplete flag on void type. (ffi_make_call_desc): Test for incomplete and bitfield types using new flags. (ffi_typedef, ffi_size, ffi_alignof): Test for bitfield type using new bitfield flag. (carray_elem_check): New static function. (carray_buf, carray_pun, carray_unum, carray_num): Use new carray_elem_check to check for bad array element type. This uses the incomplete flag rather than checking for zero size, and also disallows bitfields. * lib.h (length_s): Declared. * txr.1: Flexible structs documented in new section. Also section on incomplete types. Description of sizeof operator gives more detaild about incomplete types including flexible structs.
Diffstat (limited to 'txr.1')
-rw-r--r--txr.1100
1 files changed, 97 insertions, 3 deletions
diff --git a/txr.1 b/txr.1
index 02b47cc1..150ed5a2 100644
--- a/txr.1
+++ b/txr.1
@@ -62011,6 +62011,22 @@ and
.code bit
compound type operators.
+A structure member must not be an incomplete or zero sized array,
+unless it is the last member. If the last member of FFI structure is
+an incomplete array, then it is a flexible structure.
+
+A structure member must not be a flexible structure, unless it is the
+last member; the containing structure is then itself a flexible structure.
+
+Flexible structures correspond to the C concept of a "flexible array member":
+the idea that the last member of a structure may be an array of unknown size,
+which allows for variable-length data at the end of a structure, provided
+that the memory is suitably allocated.
+
+Flexible structures are subject to special restrictions and requirements. See
+the section Flexible Structures below. In particular, flexible structures
+may not be passed or returned by value.
+
See also: the
.code make-zstruct
function and the
@@ -63025,6 +63041,73 @@ members of structs and elements of arrays.
representation to the foreign representations exhibiting the specified
endianness.
+.SS* Incomplete Types
+
+In the \*(TL FFI type system, the following types are
+.IR incomplete :
+the type
+.codn void ,
+arrays of unspecified size, and any
+.code struct
+whose last element is of incomplete type.
+
+An incomplete type cannot used as a function parameter type, or a return
+value type. It may not be used as an array element or union member type.
+A struct member type may be incomplete only if it is the last member.
+
+An incomplete structure whose last member is an array is a
+.IR "flexible structure" .
+
+.SS* Flexible Structures
+
+If a FFI
+.code struct
+type is defined with an incomplete array (an array of unspecified size) as its
+last member, then it specifies an incomplete type known as a
+.IR "flexible structure" .
+That array is the
+.IR "terminating array" .
+The terminating array corresponds to a slot in the Lisp structure; that
+slot is the
+.IR "last slot" .
+
+A structure which has a flexible structure as its last member is also,
+effectively, a flexible structure.
+
+When a Lisp structure is being converted to the foreign representation
+under the control of a flexible structure FFI type, the number of elements
+in the terminating array is determined from the length of the object
+stored in the last slot of the Lisp structure. The length includes the
+terminating null element for
+.code zarray
+types. The conversion is consistent with the semantics of an incomplete
+arrays that is not a structure member.
+
+In the reverse direction, when a foreign representation is being converted
+to a Lisp structure under the control of a flexible structure FFI type,
+the size of the array that is accessed and extracted is determined from
+the length of the object stored in the last slot, or, if the array type
+is a
+.code zarray
+from detecting null-termination of the foreign array. The conversion of
+the array itself is consistent with the semantics of an incomplete
+arrays that is not a structure member.
+Before the conversion takes place, all of the members of the
+structure prior to the the terminating array, are extracted and converted to
+Lisp representations. The corresponding slots of the Lisp structure are
+updated. Then if the Lisp structure type has a
+.code length
+method, that method is invoked. The return value of the method is used
+to perform an adjustment on the object in the last slot.
+If the existing object in the last slot is a vector, its length is adjusted to
+the value returned by the method. If the existing
+object isn't a vector, then it is replaced by a new
+.codn nil -filled
+vector, whose length is given by the return value of
+.codn length .
+The conversion of the terminating array to Lisp representation the proceeds
+after this adjustment, using the adjusted last slot object.
+
.SS* Bitfield Allocation Rules
The \*(TL FFI type system follows rules for bitfield allocation which were
experimentally derived from the behavior of the GNU C compiler on several
@@ -64112,12 +64195,11 @@ expression is evaluated to an object value.
If
.code type-syntax
-denotes a variable length type, and the
+denotes an incomplete array or structure type, and the
.meta object-expr
argument is present, then a
.I "dynamic size" is computed: the actual number of bytes required to store
-that object value as a foreign representation of the specified variable length
-type.
+that object value as a foreign representation.
The
.code sizeof
@@ -64130,6 +64212,18 @@ is omitted, or if it is a constant expression according to the
.code constantp
function.
+For the type
+.codn void ,
+incomplete array types, and bitfield types, the one-argument form of
+.code sizeof
+reports zero.
+
+For incomplete structure types, the one-argument
+.code sizeof
+reports a size which is equivalent to the offset of the last member.
+The size of an incomplete structure does not include padding
+for the most strictly aligned member.
+
.coNP Macro @ alignof
.synb
.mets (alignof << type-syntax )