


CALLBACK(3)                                           CALLBACK(3)


NAME
       callback - closures with variable arguments as first-class
       C functions

SYNOPSIS
       #include <callback.h>

       void function (data, alist)
         void* data;
         va_alist alist;
       {
         va_start_type(alist[, return_type]);
         arg = va_arg_type(alist[, arg_type]);
         va_return_type(alist[[, return_type], return_value]);
       }

       callback = alloc_callback(&function, data);

       free_callback(callback);

       is_callback(callback)
       callback_address(callback)
       callback_data(callback)

DESCRIPTION
       These functions implement closures with variable arguments
       as first-class C functions.

       Closures  as  first-class  C functions means that they fit
       into a function pointer and can be called exactly like any
       other  C function. Moreover, they can be called with vari-
       able arguments and can return variable return values.

       callback =  alloc_callback(&function,  data)  allocates  a
       callback.  When  callback gets called, it arranges to call
       function, passing data as first argument  and,  as  second
       argument, the entire sequence of arguments passed to call-
       back.

       Function calling conventions differ considerably  on  dif-
       ferent  machines, therefore the arguments are accessed and
       the result value is stored through the same macros as used
       by the vacall package, see below.

       The  callbacks are functions with indefinite extent: call-
       back is only deallocated when  free_callback(callback)  is
       called.

       is_callback(callback)  checks whether the C function call-
       back was produced by a call to  alloc_callback.   If  this
       returns true, the arguments given to alloc_callback can be
       retrieved:

           callback_address(callback) returns &function,



                         14 January 2001                        1





CALLBACK(3)                                           CALLBACK(3)


           callback_data(callback) returns data.


VACALL MACROS
       Within function, the following macros can be used to  walk
       through the argument list and specify a return value:

       va_start_type(alist[, return_type]);
              starts the walk through the argument list and spec-
              ifies the return type.

       arg = va_arg_type(alist[, arg_type]);
              fetches the next argument from the argument list.

       va_return_type(alist[[, return_type], return_value]);
              ends the walk through the argument list and  speci-
              fies the return value.

       The  type in va_start_type and va_return_type shall be one
       of void, int, uint, long, ulong, longlong, ulonglong, dou-
       ble,  struct, ptr or (for ANSI C calling conventions only)
       char, schar, uchar, short, ushort, float, depending on the
       class of return_type.

       The  type  specifiers  in va_start_type and va_return_type
       must be the same.  The return_type  specifiers  passed  to
       va_start_type and va_return_type must be the same.

       The  type  in va_arg_type shall be one of int, uint, long,
       ulong, longlong, ulonglong, double, struct,  ptr  or  (for
       ANSI  C  calling  conventions  only)  char,  schar, uchar,
       short, ushort, float, depending on the class of  arg_type.

       In  va_start_struct(alist,  return_type,  splittable); the
       splittable flag specifies whether the  struct  return_type
       can  be returned in registers such that every struct field
       fits entirely in a single register. This needs to be spec-
       ified  for  structs of size 2*sizeof(long). For structs of
       size <= sizeof(long), splittable is ignored and assumed to
       be  1. For structs of size > 2*sizeof(long), splittable is
       ignored and assumed to be 0. There are some  handy  macros
       for this:
       va_word_splittable_1 (type1)
       va_word_splittable_2 (type1, type2)
       va_word_splittable_3 (type1, type2, type3)
       va_word_splittable_4 (type1, type2, type3, type4)
       For a struct with three slots
       struct { type1 id1; type2 id2; type3 id3; }
       you can specify splittable as va_word_splittable_3 (type1,
       type2, type3) .


NOTES
       Functions which want to emulate Kernighan & Ritchie  style



                         14 January 2001                        2





CALLBACK(3)                                           CALLBACK(3)


       functions  (i.e.,  in  ANSI  C,  functions without a typed
       argument list) cannot use the  type  values  char,  schar,
       uchar, short, ushort, float.  As prescribed by the default
       K&R C expression promotions, they have to use int  instead
       of char, schar, uchar, short, ushort and double instead of
       float.

       The  macros   va_start_longlong(),   va_start_ulonglong(),
       va_return_longlong(),               va_return_ulonglong(),
       va_arg_longlong() and va_arg_ulonglong() work only if  the
       C compiler has a working long long 64-bit integer type.

       The struct types used in va_start_struct() and va_struct()
       must 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.


SEE ALSO
       vacall(3), trampoline(3).


BUGS
       The  current  implementations have been tested on a selec-
       tion 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 regis-
       ters or in memory considers only  the  struct's  size  and
       alignment.  This  is inaccurate: for example, gcc on m68k-
       next returns struct {  char  a,b,c;  }  in  registers  and
       struct  { char a[3]; } in memory, although both types have
       the same size and the same alignment.

       <callback.h>  cannot  be  included  when  <varargs.h>   or
       <stdarg.h> is included.  (Name clash for va_alist.)

       The argument list can only be walked once.


NON-BUGS
       All  information is passed in CPU registers and the stack.
       The callback package is therefore multithread-safe.


PORTING
       Porting callback consists in first porting the vacall  and
       trampoline  packages,  then  choosing  a  CPU register for
       passing the  closure  from  trampoline  to  vacall.   This



                         14 January 2001                        3





CALLBACK(3)                                           CALLBACK(3)


       register   is   normally   the   register   designated  by
       STATIC_CHAIN_REGNUM in the gcc source, file gcc-2.7.2/con-
       fig/cpu/cpu.h.


AUTHOR
       Bruno Haible <haible@clisp.cons.org>


ACKNOWLEDGEMENTS
       Many ideas were cribbed from the gcc source.














































                         14 January 2001                        4


