1CALLBACK(3)                Library Functions Manual                CALLBACK(3)
2
3
4

NAME

6       callback - closures with variable arguments as first-class C functions
7

SYNOPSIS

9       #include <callback.h>
10
11       void function (void* data, va_alist alist)
12       {
13         va_start_type(alist[, return_type]);
14         arg = va_arg_type(alist[, arg_type]);
15         va_return_type(alist[[, return_type], return_value]);
16       }
17
18       callback = alloc_callback(&function, data);
19
20       free_callback(callback);
21
22       is_callback(callback)
23       callback_address(callback)
24       callback_data(callback)
25

DESCRIPTION

27       These  functions  implement  closures with variable arguments as first-
28       class C functions.
29
30       Closures as first-class C functions means that they fit into a function
31       pointer  and can be called exactly like any other C function. Moreover,
32       they can be called with variable  arguments  and  can  return  variable
33       return values.
34
35       callback  =  alloc_callback(&function, data) allocates a callback. When
36       callback gets called, it arranges to call  function,  passing  data  as
37       first  argument  and,  as second argument, the entire sequence of argu‐
38       ments passed to callback.
39
40       Function calling conventions differ considerably on different machines,
41       therefore  the  arguments  are  accessed and the result value is stored
42       through the same macros as used by the vacall package, see below.
43
44       The callbacks are functions with indefinite extent:  callback  is  only
45       deallocated when free_callback(callback) is called.
46
47       is_callback(callback)  checks  whether the C function callback was pro‐
48       duced by a call to alloc_callback.  If this returns true, the arguments
49       given to alloc_callback can be retrieved:
50
51           callback_address(callback) returns &function,
52
53           callback_data(callback) returns data.
54
55

VACALL MACROS

57       Within  function,  the following macros can be used to walk through the
58       argument list and specify a return value:
59
60       va_start_type(alist[, return_type]);
61              starts the walk through the  argument  list  and  specifies  the
62              return type.
63
64       arg = va_arg_type(alist[, arg_type]);
65              fetches the next argument from the argument list.
66
67       va_return_type(alist[[, return_type], return_value]);
68              ends the walk through the argument list and specifies the return
69              value.
70
71       The type in va_start_type and va_return_type shall be one of void, int,
72       uint,  long,  ulong,  longlong,  ulonglong, double, struct, ptr or (for
73       ANSI C calling conventions only) char,  schar,  uchar,  short,  ushort,
74       float, depending on the class of return_type.
75
76       The  type  specifiers  in  va_start_type and va_return_type must be the
77       same.   The  return_type  specifiers  passed   to   va_start_type   and
78       va_return_type must be the same.
79
80       The  type  in va_arg_type shall be one of int, uint, long, ulong, long‐
81       long, ulonglong, double, struct, ptr or (for ANSI C calling conventions
82       only)  char, schar, uchar, short, ushort, float, depending on the class
83       of arg_type.
84
85       In va_start_struct(alist, return_type, splittable); the splittable flag
86       specifies  whether  the struct return_type can be returned in registers
87       such that every struct field fits entirely in a single  register.  This
88       needs  to  be specified for structs of size 2*sizeof(long). For structs
89       of size <= sizeof(long), splittable is ignored and assumed to be 1. For
90       structs  of size > 2*sizeof(long), splittable is ignored and assumed to
91       be 0. There are some handy macros for this:
92       va_word_splittable_1 (type1)
93       va_word_splittable_2 (type1, type2)
94       va_word_splittable_3 (type1, type2, type3)
95       va_word_splittable_4 (type1, type2, type3, type4)
96       For a struct with three slots
97       struct { type1 id1; type2 id2; type3 id3; }
98       you can  specify  splittable  as  va_word_splittable_3  (type1,  type2,
99       type3) .
100
101

NOTES

103       Functions  which  want  to  emulate Kernighan & Ritchie style functions
104       (i.e., in ANSI C, functions without a typed argument list)  cannot  use
105       the  type  values  char,  schar,  uchar, short, ushort, float.  As pre‐
106       scribed by the default K&R C expression promotions, they  have  to  use
107       int  instead of char, schar, uchar, short, ushort and double instead of
108       float.
109
110       The macros va_start_longlong(),  va_start_ulonglong(),  va_return_long‐
111       long(), va_return_ulonglong(), va_arg_longlong() and va_arg_ulonglong()
112       work only if the C compiler has a  working  long  long  64-bit  integer
113       type.
114
115       The  struct  types  used in va_start_struct() and va_struct() must only
116       contain (signed or unsigned) int, long, long long  or  pointer  fields.
117       Struct types containing (signed or unsigned) char, short, float, double
118       or other structs are not supported.
119
120

SEE ALSO

122       vacall(3), trampoline(3).
123
124

BUGS

126       The current implementations have been tested on a selection  of  common
127       cases but there are probably still many bugs.
128
129       There  are  typically built-in limits on the size of the argument-list,
130       which may also include the size of any structure arguments.
131
132       The decision whether a struct is to be returned in registers or in mem‐
133       ory considers only the struct's size and alignment. This is inaccurate:
134       for example, gcc on m68k-next returns struct { char a,b,c; } in  regis‐
135       ters  and struct { char a[3]; } in memory, although both types have the
136       same size and the same alignment.
137
138       The argument list can only be walked once.
139
140

NON-BUGS

142       All information is passed in CPU registers and the stack. The  callback
143       package is therefore multithread-safe.
144
145

PORTING

147       Porting  callback  consists  in first porting the vacall and trampoline
148       packages, then choosing a CPU register for  passing  the  closure  from
149       trampoline  to  vacall.   This register is normally the register desig‐
150       nated by STATIC_CHAIN_REGNUM in the  gcc  source,  file  gcc-2.7.2/con‐
151       fig/cpu/cpu.h.
152
153

AUTHOR

155       Bruno Haible <bruno@clisp.org>
156
157

ACKNOWLEDGEMENTS

159       Many ideas were cribbed from the gcc source.
160
161
162
163
164                                1 January 2017                     CALLBACK(3)
Impressum