documentation fixes Fixes #78. Documentation for #33 and #35, but no fix.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280
diff --git a/doc/libffi.texi b/doc/libffi.texi
index ff72e58..125d33d 100644
--- a/doc/libffi.texi
+++ b/doc/libffi.texi
@@ -107,6 +107,7 @@ values passed between the two languages.
* Multiple ABIs:: Different passing styles on one platform.
* The Closure API:: Writing a generic function.
* Closure Example:: A closure example.
+* Thread Safety:: Thread safety.
@end menu
@@ -172,6 +173,10 @@ Also note that a call to @code{ffi_prep_cif_var} with
@end defun
+Note that the resulting @code{ffi_cif} holds pointers to all the
+@code{ffi_type} objects that were used durin initialization. You must
+ensure that these type objects have a lifetime at least as long as
+that of the @code{ffi_cif}.
To call a function using an initialized @code{ffi_cif}, use the
@code{ffi_call} function:
@@ -190,12 +195,29 @@ to ensure this. If @var{cif} declares that the function returns
@code{void} (using @code{ffi_type_void}), then @var{rvalue} is
ignored.
+In most situations, @samp{libffi} will handle promotion according to
+the ABI. However, for historical reasons, there is a special case
+with return values that must be handled by your code. In particular,
+for integral (not @code{struct}) types that are narrower than the
+system register size, the return value will be widened by
+@samp{libffi}. @samp{libffi} provides a type, @code{ffi_arg}, that
+can be used as the return type. For example, if the CIF was defined
+with a return type of @code{char}, @samp{libffi} will try to store a
+full @code{ffi_arg} into the return value.
+
@var{avalues} is a vector of @code{void *} pointers that point to the
memory locations holding the argument values for a call. If @var{cif}
declares that the function has no arguments (i.e., @var{nargs} was 0),
then @var{avalues} is ignored. Note that argument values may be
modified by the callee (for instance, structs passed by value); the
burden of copying pass-by-value arguments is placed on the caller.
+
+Note that while the return value must be register-sized, arguments
+should exactly match their declared type. For example, if an argument
+is a @code{short}, then the entry is @var{avalues} should point to an
+object declared as @code{short}; but if the return type is
+@code{short}, then @var{rvalue} should point to an object declared as
+a larger type -- usually @code{ffi_arg}.
@end defun
@@ -246,6 +268,8 @@ int main()
@menu
* Primitive Types:: Built-in types.
* Structures:: Structure types.
+* Size and Alignment:: Size and alignment of types.
+* Arrays and Unions:: Arrays and unions.
* Type Example:: Structure type example.
* Complex:: Complex types.
* Complex Type Example:: Complex type example.
@@ -370,8 +394,7 @@ when passing to @code{ffi_prep_cif}.
@node Structures
@subsection Structures
-Although @samp{libffi} has no special support for unions or
-bit-fields, it is perfectly happy passing structures back and forth.
+@samp{libffi} is perfectly happy passing structures back and forth.
You must first describe the structure to @samp{libffi} by creating a
new @code{ffi_type} object for it.
@@ -391,9 +414,132 @@ For a structure, this should be set to @code{FFI_TYPE_STRUCT}.
@item ffi_type **elements
This is a @samp{NULL}-terminated array of pointers to @code{ffi_type}
objects. There is one element per field of the struct.
+
+Note that @samp{libffi} has no special support for bit-fields. You
+must manage these manually.
@end table
@end deftp
+The @code{size} and @code{alignment} fields will be filled in by
+@code{ffi_prep_cif} or @code{ffi_prep_cif_var}, as needed.
+
+@node Size and Alignment
+@subsection Size and Alignment
+
+@code{libffi} will set the @code{size} and @code{alignment} fields of
+an @code{ffi_type} object for you. It does so using its knowledge of
+the ABI.
+
+You might expect that you can simply read these fields for a type that
+has been laid out by @code{libffi}. However, there are some caveats.
+
+@itemize @bullet
+@item
+The size or alignment of some of the built-in types may vary depending
+on the chosen ABI.
+
+@item
+The size and alignment of a new structure type will not be set by
+@code{libffi} until it has been passed to @code{ffi_prep_cif}.
+
+@item
+A structure type cannot be shared across ABIs. Instead each ABI needs
+its own copy of the structure type.
+@end itemize
+
+So, before examining these fields, it is safest to pass the
+@code{ffi_type} object to @code{ffi_prep_cif} first. This function
+will do all the needed setup.
+
+@example
+ffi_type *desired_type;
+ffi_abi desired_abi;
+@dots{}
+ffi_cif cif;
+if (ffi_prep_cif (&cif, desired_abi, 0, desired_type, NULL) == FFI_OK)
+ @{
+ size_t size = desired_type->size;
+ unsigned short alignment = desired_type->alignment;
+ @}
+@end example
+
+@node Arrays and Unions
+@subsection Arrays and Unions
+
+@subsubsection Arrays
+
+@samp{libffi} does not have direct support for arrays or unions.
+However, they can be emulated using structures.
+
+To emulate an array, simply create an @code{ffi_type} using
+@code{FFI_TYPE_STRUCT} with as many members as there are elements in
+the array.
+
+@example
+ffi_type array_type;
+ffi_type **elements
+int i;
+
+elements = malloc ((n + 1) * sizeof (ffi_type *));
+for (i = 0; i < n; ++i)
+ elements[i] = array_element_type;
+elements[n] = NULL;
+
+array_type.size = array_type.alignment = 0;
+array_type.type = FFI_TYPE_STRUCT;
+array_type.elements = elements;
+@end example
+
+Note that arrays cannot be passed or returned by value in C --
+structure types created like this should only be used to refer to
+members of real @code{FFI_TYPE_STRUCT} objects.
+
+However, a phony array type like this will not cause any errors from
+@samp{libffi} if you use it as an argument or return type. This may
+be confusing.
+
+@subsubsection Unions
+
+A union can also be emulated using @code{FFI_TYPE_STRUCT}. In this
+case, however, you must make sure that the size and alignment match
+the real requirements of the union.
+
+One simple way to do this is to ensue that each element type is laid
+out. Then, give the new structure type a single element; the size of
+the largest element; and the largest alignment seen as well.
+
+This example uses the @code{ffi_prep_cif} trick to ensure that each
+element type is laid out.
+
+@example
+ffi_abi desired_abi;
+ffi_type union_type;
+ffi_type **union_elements;
+
+int i;
+ffi_type element_types[2];
+
+element_types[1] = NULL;
+
+union_type.size = union_type.alignment = 0;
+union_type.type = FFI_TYPE_STRUCT;
+union_type.elements = element_types;
+
+for (i = 0; union_elements[i]; ++i)
+ @{
+ ffi_cif cif;
+ if (ffi_prep_cif (&cif, desired_abi, 0, union_elements[i], NULL) == FFI_OK)
+ @{
+ if (union_elements[i]->size > union_type.size)
+ @{
+ union_type.size = union_elements[i];
+ size = union_elements[i]->size;
+ @}
+ if (union_elements[i]->alignment > union_type.alignment)
+ union_type.alignment = union_elements[i]->alignment;
+ @}
+ @}
+@end example
@node Type Example
@subsection Type Example
@@ -636,6 +782,8 @@ Prepare a closure function.
the writable address returned by @code{ffi_closure_alloc}.
@var{cif} is the @code{ffi_cif} describing the function parameters.
+Note that this object, and the types to which it refers, must be kept
+alive until the closure itself is freed.
@var{user_data} is an arbitrary datum that is passed, uninterpreted,
to your closure function.
@@ -652,8 +800,12 @@ The @code{ffi_cif} passed to @code{ffi_prep_closure_loc}.
@item ret
A pointer to the memory used for the function's return value.
@var{fun} must fill this, unless the function is declared as returning
-@code{void}.
+@code{void}. Note that this points to memory that is exactly the size
+of the type given as the return type when initializing the CIF. In
+particular, closures do not have the special promotion behavior of
+@code{ffi_call}.
@c FIXME: is this NULL for void-returning functions?
+@c (experimentally it is not, but it seems like a good idea)
@item args
A vector of pointers to memory holding the arguments to the function.
@@ -664,8 +816,7 @@ The same @var{user_data} that was passed to
@end table
@code{ffi_prep_closure_loc} will return @code{FFI_OK} if everything
-went ok, and something else on error.
-@c FIXME: what?
+went ok, and one of the other @code{ffi_status} values on error.
After calling @code{ffi_prep_closure_loc}, you can cast @var{codeloc}
to the appropriate pointer-to-function type.
@@ -733,6 +884,28 @@ int main()
@end example
+@node Thread Safety
+@section Thread Safety
+
+@code{libffi} is not completely thread-safe. However, many parts are,
+and if you follow some simple rules, you can use it safely in a
+multi-threaded program.
+
+@itemize @bullet
+@item
+@code{ffi_prep_cif} may modify the @code{ffi_type} objects passed to
+it. It is best to ensure that only a single thread prepares a given
+@code{ffi_cif} at a time.
+
+@item
+On some platforms, @code{ffi_prep_cif} may modify the size and
+alignment of some types, depending on the chosen ABI. On these
+platforms, if you switch between ABIs, you must ensure that there is
+only one call to @code{ffi_prep_cif} at a time.
+
+Currently the only affected platform is PowerPC and the only affected
+type is @code{long double}.
+@end itemize
@node Missing Features
@chapter Missing Features
@@ -749,9 +922,10 @@ There is no support for bit fields in structures.
@item
The ``raw'' API is undocumented.
-@c argument promotion?
-@c unions?
@c anything else?
+
+@item
+The Go API is undocumented.
@end itemize
Note that variadic support is very new and tested on a relatively