File ffcall/callback/callback.man from the latest check-in





CALLBACK(3)                                           CALLBACK(3)


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

SSYYNNOOPPSSIISS
       ##iinncclluuddee <<ccaallllbbaacckk..hh>>

       vvooiidd _f_u_n_c_t_i_o_n ((_d_a_t_a,, _a_l_i_s_t))
         vvooiidd** _d_a_t_a;;
         vvaa__aalliisstt _a_l_i_s_t;;
       {{
         vvaa__ssttaarrtt___t_y_p_e((_a_l_i_s_t[[,, _r_e_t_u_r_n___t_y_p_e]]));;
         _a_r_g == vvaa__aarrgg___t_y_p_e((_a_l_i_s_t[[,, _a_r_g___t_y_p_e]]));;
         vvaa__rreettuurrnn___t_y_p_e((_a_l_i_s_t[[[[,, _r_e_t_u_r_n___t_y_p_e]],, _r_e_t_u_r_n___v_a_l_u_e]]));;
       }}

       _c_a_l_l_b_a_c_k == aalllloocc__ccaallllbbaacckk((_&_f_u_n_c_t_i_o_n,, _d_a_t_a));;

       ffrreeee__ccaallllbbaacckk((_c_a_l_l_b_a_c_k));;

       iiss__ccaallllbbaacckk((_c_a_l_l_b_a_c_k))
       ccaallllbbaacckk__aaddddrreessss((_c_a_l_l_b_a_c_k))
       ccaallllbbaacckk__ddaattaa((_c_a_l_l_b_a_c_k))

DDEESSCCRRIIPPTTIIOONN
       These functions implement _c_l_o_s_u_r_e_s with variable arguments
       as first-class C functions.

       Closures  as  _f_i_r_s_t_-_c_l_a_s_s  _C _f_u_n_c_t_i_o_n_s 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.

       _c_a_l_l_b_a_c_k ==  aalllloocc__ccaallllbbaacckk((_&_f_u_n_c_t_i_o_n,,  _d_a_t_a))  allocates  a
       callback.  When  _c_a_l_l_b_a_c_k gets called, it arranges to call
       _f_u_n_c_t_i_o_n, passing _d_a_t_a as first argument  and,  as  second
       argument, the entire sequence of arguments passed to _c_a_l_l_-
       _b_a_c_k.

       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 _v_a_c_a_l_l package, see below.

       The  callbacks are functions with indefinite extent: _c_a_l_l_-
       _b_a_c_k is only deallocated when  ffrreeee__ccaallllbbaacckk((_c_a_l_l_b_a_c_k))  is
       called.

       iiss__ccaallllbbaacckk((_c_a_l_l_b_a_c_k))  checks whether the C function _c_a_l_l_-
       _b_a_c_k was produced by a call to  _a_l_l_o_c___c_a_l_l_b_a_c_k.   If  this
       returns true, the arguments given to _a_l_l_o_c___c_a_l_l_b_a_c_k can be
       retrieved:

           ccaallllbbaacckk__aaddddrreessss((_c_a_l_l_b_a_c_k)) returns _&_f_u_n_c_t_i_o_n,



                         14 January 2001                        1





CALLBACK(3)                                           CALLBACK(3)


           ccaallllbbaacckk__ddaattaa((_c_a_l_l_b_a_c_k)) returns _d_a_t_a.


VVAACCAALLLL MMAACCRROOSS
       Within _f_u_n_c_t_i_o_n, the following macros can be used to  walk
       through the argument list and specify a return value:

       vvaa__ssttaarrtt___t_y_p_e((_a_l_i_s_t[[,, _r_e_t_u_r_n___t_y_p_e]]));;
              starts the walk through the argument list and spec-
              ifies the return type.

       _a_r_g == vvaa__aarrgg___t_y_p_e((_a_l_i_s_t[[,, _a_r_g___t_y_p_e]]));;
              fetches the next argument from the argument list.

       vvaa__rreettuurrnn___t_y_p_e((_a_l_i_s_t[[[[,, _r_e_t_u_r_n___t_y_p_e]],, _r_e_t_u_r_n___v_a_l_u_e]]));;
              ends the walk through the argument list and  speci-
              fies the return value.

       The  _t_y_p_e in vvaa__ssttaarrtt___t_y_p_e and vvaa__rreettuurrnn___t_y_p_e shall be one
       of vvooiidd, iinntt, uuiinntt, lloonngg, uulloonngg, lloonngglloonngg, uulloonngglloonngg, ddoouu--
       bbllee,  ssttrruucctt, ppttrr or (for ANSI C calling conventions only)
       cchhaarr, sscchhaarr, uucchhaarr, sshhoorrtt, uusshhoorrtt, ffllooaatt, depending on the
       class of _r_e_t_u_r_n___t_y_p_e.

       The  _t_y_p_e  specifiers  in vvaa__ssttaarrtt___t_y_p_e and vvaa__rreettuurrnn___t_y_p_e
       must be the same.  The _r_e_t_u_r_n___t_y_p_e  specifiers  passed  to
       vvaa__ssttaarrtt___t_y_p_e and vvaa__rreettuurrnn___t_y_p_e must be the same.

       The  _t_y_p_e  in vvaa__aarrgg___t_y_p_e shall be one of iinntt, uuiinntt, lloonngg,
       uulloonngg, lloonngglloonngg, uulloonngglloonngg, ddoouubbllee, ssttrruucctt,  ppttrr  or  (for
       ANSI  C  calling  conventions  only)  cchhaarr,  sscchhaarr, uucchhaarr,
       sshhoorrtt, uusshhoorrtt, ffllooaatt, depending on the class of  _a_r_g___t_y_p_e.

       In  vvaa__ssttaarrtt__ssttrruucctt((_a_l_i_s_t,,  _r_e_t_u_r_n___t_y_p_e,,  _s_p_l_i_t_t_a_b_l_e));; the
       _s_p_l_i_t_t_a_b_l_e flag specifies whether the  struct  _r_e_t_u_r_n___t_y_p_e
       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), _s_p_l_i_t_t_a_b_l_e is ignored and assumed to
       be  1. For structs of size > 2*sizeof(long), _s_p_l_i_t_t_a_b_l_e is
       ignored and assumed to be 0. There are some  handy  macros
       for this:
       vvaa__wwoorrdd__sspplliittttaabbllee__11 ((_t_y_p_e_1))
       vvaa__wwoorrdd__sspplliittttaabbllee__22 ((_t_y_p_e_1,, _t_y_p_e_2))
       vvaa__wwoorrdd__sspplliittttaabbllee__33 ((_t_y_p_e_1,, _t_y_p_e_2,, _t_y_p_e_3))
       vvaa__wwoorrdd__sspplliittttaabbllee__44 ((_t_y_p_e_1,, _t_y_p_e_2,, _t_y_p_e_3,, _t_y_p_e_4))
       For a struct with three slots
       ssttrruucctt {{ _t_y_p_e_1 _i_d_1;; _t_y_p_e_2 _i_d_2;; _t_y_p_e_3 _i_d_3;; }}
       you can specify _s_p_l_i_t_t_a_b_l_e as vvaa__wwoorrdd__sspplliittttaabbllee__33 ((_t_y_p_e_1,,
       _t_y_p_e_2,, _t_y_p_e_3)) .


NNOOTTEESS
       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  _t_y_p_e  values  cchhaarr,  sscchhaarr,
       uucchhaarr, sshhoorrtt, uusshhoorrtt, ffllooaatt.  As prescribed by the default
       K&R C expression promotions, they have to use iinntt  instead
       of cchhaarr, sscchhaarr, uucchhaarr, sshhoorrtt, uusshhoorrtt and ddoouubbllee instead of
       ffllooaatt.

       The  macros   vvaa__ssttaarrtt__lloonngglloonngg(()),   vvaa__ssttaarrtt__uulloonngglloonngg(()),
       vvaa__rreettuurrnn__lloonngglloonngg(()),               vvaa__rreettuurrnn__uulloonngglloonngg(()),
       vvaa__aarrgg__lloonngglloonngg(()) and vvaa__aarrgg__uulloonngglloonngg(()) work only if  the
       C compiler has a working lloonngg lloonngg 64-bit integer type.

       The struct types used in vvaa__ssttaarrtt__ssttrruucctt(()) and vvaa__ssttrruucctt(())
       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.


SSEEEE AALLSSOO
       vvaaccaallll(3), ttrraammppoolliinnee(3).


BBUUGGSS
       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 ssttrruucctt {{  cchhaarr  aa,,bb,,cc;;  }}  in  registers  and
       ssttrruucctt  {{ cchhaarr aa[[33]];; }} in memory, although both types have
       the same size and the same alignment.

       <<ccaallllbbaacckk..hh>>  cannot  be  included  when  <<vvaarraarrggss..hh>>   or
       <<ssttddaarrgg..hh>> is included.  (Name clash for vvaa__aalliisstt.)

       The argument list can only be walked once.


NNOONN--BBUUGGSS
       All  information is passed in CPU registers and the stack.
       The ccaallllbbaacckk package is therefore multithread-safe.


PPOORRTTIINNGG
       Porting ccaallllbbaacckk consists in first porting the vvaaccaallll  and
       ttrraammppoolliinnee  packages,  then  choosing  a  CPU register for
       passing the  closure  from  ttrraammppoolliinnee  to  vvaaccaallll.   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/_c_p_u/_c_p_u.h.


AAUUTTHHOORR
       Bruno Haible <bruno@clisp.org>


AACCKKNNOOWWLLEEDDGGEEMMEENNTTSS
       Many ideas were cribbed from the gcc source.














































                         14 January 2001                        4