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
|
CALLBACK(3) Library Functions Manual CALLBACK(3)
[1mNAME[0m
callback - closures with variable arguments as first-class C functions
[1mSYNOPSIS[0m
[1m#include <callback.h>[0m
[1mvoid [4m[22mfunction[24m [1m(void* [4m[22mdata[24m[1m, va_alist [4m[22malist[24m[1m)[0m
[1m{[0m
[1mva_start_[4m[22mtype[24m[1m([4m[22malist[24m[1m[, [4m[22mreturn_type[24m[1m]);[0m
[4marg[24m [1m= va_arg_[4m[22mtype[24m[1m([4m[22malist[24m[1m[, [4m[22marg_type[24m[1m]);[0m
[1mva_return_[4m[22mtype[24m[1m([4m[22malist[24m[1m[[, [4m[22mreturn_type[24m[1m], [4m[22mreturn_value[24m[1m]);[0m
[1m}[0m
[4mcallback[24m [1m= alloc_callback([4m[22m&function[24m[1m, [4m[22mdata[24m[1m);[0m
[1mfree_callback([4m[22mcallback[24m[1m);[0m
[1mis_callback([4m[22mcallback[24m[1m)[0m
[1mcallback_address([4m[22mcallback[24m[1m)[0m
[1mcallback_data([4m[22mcallback[24m[1m)[0m
[1mDESCRIPTION[0m
These functions implement [4mclosures[24m with variable arguments as first-
class C functions.
Closures as [4mfirst-class[24m [4mC[24m [4mfunctions[24m means that they fit into a function
pointer and can be called exactly like any other C function. Moreover,
they can be called with variable arguments and can return variable
return values.
[4mcallback[24m [1m= alloc_callback([4m[22m&function[24m[1m, [4m[22mdata[24m[1m) [22mallocates a callback. When
[4mcallback[24m gets called, it arranges to call [4mfunction[24m, passing [4mdata[24m as
first argument and, as second argument, the entire sequence of argu‐
ments passed to [4mcallback[24m.
Function calling conventions differ considerably on different machines,
therefore the arguments are accessed and the result value is stored
through the same macros as used by the [4mvacall[24m package, see below.
The callbacks are functions with indefinite extent: [4mcallback[24m is only
deallocated when [1mfree_callback([4m[22mcallback[24m[1m) [22mis called.
[1mis_callback([4m[22mcallback[24m[1m) [22mchecks whether the C function [4mcallback[24m was pro‐
duced by a call to [4malloc_callback[24m. If this returns true, the arguments
given to [4malloc_callback[24m can be retrieved:
[1mcallback_address([4m[22mcallback[24m[1m) [22mreturns [4m&function[24m,
[1mcallback_data([4m[22mcallback[24m[1m) [22mreturns [4mdata[24m.
[1mVACALL MACROS[0m
Within [4mfunction[24m, the following macros can be used to walk through the
argument list and specify a return value:
[1mva_start_[4m[22mtype[24m[1m([4m[22malist[24m[1m[, [4m[22mreturn_type[24m[1m]);[0m
starts the walk through the argument list and specifies the
return type.
[4marg[24m [1m= va_arg_[4m[22mtype[24m[1m([4m[22malist[24m[1m[, [4m[22marg_type[24m[1m]);[0m
fetches the next argument from the argument list.
[1mva_return_[4m[22mtype[24m[1m([4m[22malist[24m[1m[[, [4m[22mreturn_type[24m[1m], [4m[22mreturn_value[24m[1m]);[0m
ends the walk through the argument list and specifies the return
value.
The [4mtype[24m in [1mva_start_[4m[22mtype[24m and [1mva_return_[4m[22mtype[24m shall be one of [1mvoid[22m, [1mint[22m,
[1muint[22m, [1mlong[22m, [1mulong[22m, [1mlonglong[22m, [1mulonglong[22m, [1mdouble[22m, [1mstruct[22m, [1mptr [22mor (for
ANSI C calling conventions only) [1mchar[22m, [1mschar[22m, [1muchar[22m, [1mshort[22m, [1mushort[22m,
[1mfloat[22m, depending on the class of [4mreturn_type[24m.
The [4mtype[24m specifiers in [1mva_start_[4m[22mtype[24m and [1mva_return_[4m[22mtype[24m must be the
same. The [4mreturn_type[24m specifiers passed to [1mva_start_[4m[22mtype[24m and
[1mva_return_[4m[22mtype[24m must be the same.
The [4mtype[24m in [1mva_arg_[4m[22mtype[24m shall be one of [1mint[22m, [1muint[22m, [1mlong[22m, [1mulong[22m, [1mlong‐[0m
[1mlong[22m, [1mulonglong[22m, [1mdouble[22m, [1mstruct[22m, [1mptr [22mor (for ANSI C calling conventions
only) [1mchar[22m, [1mschar[22m, [1muchar[22m, [1mshort[22m, [1mushort[22m, [1mfloat[22m, depending on the class
of [4marg_type[24m.
In [1mva_start_struct([4m[22malist[24m[1m, [4m[22mreturn_type[24m[1m, [4m[22msplittable[24m[1m); [22mthe [4msplittable[24m flag
specifies whether the struct [4mreturn_type[24m can be returned in registers
such that every struct field fits entirely in a single register. This
needs to be specified for structs of size 2*sizeof(long). For structs
of size <= sizeof(long), [4msplittable[24m is ignored and assumed to be 1. For
structs of size > 2*sizeof(long), [4msplittable[24m is ignored and assumed to
be 0. There are some handy macros for this:
[1mva_word_splittable_1 ([4m[22mtype1[24m[1m)[0m
[1mva_word_splittable_2 ([4m[22mtype1[24m[1m, [4m[22mtype2[24m[1m)[0m
[1mva_word_splittable_3 ([4m[22mtype1[24m[1m, [4m[22mtype2[24m[1m, [4m[22mtype3[24m[1m)[0m
[1mva_word_splittable_4 ([4m[22mtype1[24m[1m, [4m[22mtype2[24m[1m, [4m[22mtype3[24m[1m, [4m[22mtype4[24m[1m)[0m
For a struct with three slots
[1mstruct { [4m[22mtype1[24m [4mid1[24m[1m; [4m[22mtype2[24m [4mid2[24m[1m; [4m[22mtype3[24m [4mid3[24m[1m; }[0m
you can specify [4msplittable[24m as [1mva_word_splittable_3 ([4m[22mtype1[24m[1m, [4m[22mtype2[24m[1m,[0m
[4mtype3[24m[1m) [22m.
[1mNOTES[0m
Functions which want to emulate Kernighan & Ritchie style functions
(i.e., in ANSI C, functions without a typed argument list) cannot use
the [4mtype[24m values [1mchar[22m, [1mschar[22m, [1muchar[22m, [1mshort[22m, [1mushort[22m, [1mfloat[22m. As pre‐
scribed by the default K&R C expression promotions, they have to use
[1mint [22minstead of [1mchar[22m, [1mschar[22m, [1muchar[22m, [1mshort[22m, [1mushort [22mand [1mdouble [22minstead of
[1mfloat[22m.
The macros [1mva_start_longlong()[22m, [1mva_start_ulonglong()[22m, [1mva_return_long‐[0m
[1mlong()[22m, [1mva_return_ulonglong()[22m, [1mva_arg_longlong() [22mand [1mva_arg_ulonglong()[0m
work only if the C compiler has a working [1mlong long [22m64-bit integer
type.
The struct types used in [1mva_start_struct() [22mand [1mva_struct() [22mmust only
contain (signed or unsigned) int, long, long long or pointer fields.
Struct types containing (signed or unsigned) char, short, float, double
or other structs are not supported.
[1mSEE ALSO[0m
[1mvacall[22m(3), [1mtrampoline[22m(3).
[1mBUGS[0m
The current implementations have been tested on a selection of common
cases but there are probably still many bugs.
There are typically built-in limits on the size of the argument-list,
which may also include the size of any structure arguments.
The decision whether a struct is to be returned in registers or in mem‐
ory considers only the struct's size and alignment. This is inaccurate:
for example, gcc on m68k-next returns [1mstruct { char a,b,c; } [22min regis‐
ters and [1mstruct { char a[3]; } [22min memory, although both types have the
same size and the same alignment.
The argument list can only be walked once.
[1mNON-BUGS[0m
All information is passed in CPU registers and the stack. The [1mcallback[0m
package is therefore multithread-safe.
[1mPORTING[0m
Porting [1mcallback [22mconsists in first porting the [1mvacall [22mand [1mtrampoline[0m
packages, then choosing a CPU register for passing the closure from
[1mtrampoline [22mto [1mvacall[22m. This register is normally the register desig‐
nated by STATIC_CHAIN_REGNUM in the gcc source, file gcc-2.7.2/con‐
fig/[4mcpu[24m/[4mcpu[24m.h.
[1mAUTHOR[0m
Bruno Haible <bruno@clisp.org>
[1mACKNOWLEDGEMENTS[0m
Many ideas were cribbed from the gcc source.
1 January 2017 CALLBACK(3)
|