Provided by: libffcall-dev_2.2-1_amd64 bug


       avcall - build a C argument list incrementally and call a C function on it.


       #include <avcall.h>

       av_alist alist;

       av_start_type(alist, &func [[, return_type], &return_value ]);

       av_type(alist, [arg_type,] value);



       This  set of macros builds an argument list for a C function and calls the function on it.
       It significantly reduces the amount  of  `glue'  code  required  for  parsers,  debuggers,
       imbedded  interpreters,  C  extensions  to application programs and other situations where
       collections of functions need to be called on lists of externally-supplied arguments.

       Function calling conventions differ considerably on different machines and avcall attempts
       to provide some degree of isolation from such architecture dependencies.

       The  interface  is  like stdarg(3) in reverse. All of the macros return 0 for success, < 0
       for failure (e.g., argument list overflow or type-not-supported).

       (1)    #include <avcall.h>
              and declare the argument list structure
              av_alist alist;

       (2)    Set any special flags. This  is  architecture  and  compiler  dependent.   Compiler
              options  that  affect passing conventions may need to be flagged by #defines before
              the #include <avcall.h>  statement.  However,  the  configure  script  should  have
              determined which #defines are needed and put them at the top of avcall.h.

       (3)    Initialize  the  alist with the function address and return value pointer (if any).
              There is a separate macro for each simple return type ([u]char,  [u]short,  [u]int,
              [u]long,  [u]longlong,  float,  double, where `u' indicates `unsigned'). The macros
              for functions returning structures or pointers require an explicit type argument.


       av_start_int (alist, &func, &int_return);

       av_start_double (alist, &func, &double_return);

       av_start_void (alist, &func);

       av_start_struct (alist, &func, struct_type, splittable,

       av_start_ptr (alist, &func, pointer_type,

       The splittable flag specifies whether the struct_type 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), 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:
       av_word_splittable_1 (type1)
       av_word_splittable_2 (type1, type2)
       av_word_splittable_3 (type1, type2, type3)
       av_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 av_word_splittable_3 (type1, type2, type3) .

       (4)    Push the arguments on to the list in order. Again there is a macro for each  simple
              built-in  type, and the macros for structure and pointer arguments require an extra
              type argument:

       av_int (alist, int_value);

       av_double (alist, double_value);

       av_struct (alist, struct_or_union_type, struct_value);

       av_ptr (alist, pointer_type, pointer_value);

       (5)    Call the function, set the return value, and tidy up:

       av_call (alist);


       (1) Functions whose first declaration is in Kernighan & Ritchie  style  (i.e.,  without  a
       typed  argument list) MUST use default K&R C expression promotions (char and short to int,
       float to double) whether they are compiled by a K&R or an ANSI compiler, because the  true
       argument  types  may not be known at the call point. Such functions typically back-convert
       their arguments to the declared types on function entry. (In fact, the only way to pass  a
       true  char,  short  or  float  in  K&R C is by an explicit cast: func((char)c,(float)f) ).
       Similarly, some K&R compilers (such as Sun cc on the sparc) actually return a float  as  a

       Hence,  for  arguments  of  functions  declared  in  K&R style you should use av_int() and
       av_double() rather than av_char(), av_short() or av_float().  If you use a  K&R  compiler,
       the  avcall  header  files  may  be  able  to  detect  this  and  define  av_float(), etc,
       appropriately, but with an ANSI compiler there is no way avcall can know  how  a  function
       was declared, so you have to correct the argument types yourself.

       (2)  The explicit type arguments of the av_struct() and av_ptr() macros are typically used
       to calculate size, alignment, and passing conventions.  This may  not  be  sufficient  for
       some  machines  with  unusual  structure  and  pointer  handling:  in this case additional
       av_start_type() and av_type() macros may be defined.

       (3) The macros av_start_longlong(), av_start_ulonglong(), av_longlong() and av_ulonglong()
       work only if the C compiler has a working long long 64-bit integer type.

       (4)  The  struct types used in av_start_struct() and av_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.


       stdarg(3), varargs(3).


       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 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.


       All information is passed in CPU registers and the stack. The avcall package is  therefore


       Ports,  bug-fixes,  and  suggestions  are  most  welcome. The macros required for argument
       pushing are pretty grungy, but it does seem to be possible to port avcall to  a  range  of
       machines.  Ports  to  non-standard or non-32-bit machines are especially welcome so we can
       sort the interface out before it's too late.

       Knowledge about argument passing  conventions  can  be  found  in  the  gcc  source,  file
       gcc-2.6.3/config/cpu/cpu.h, section "Stack layout; function entry, exit and calling."

       Some  of the grunge is usually handled by a C or assembly level glue routine that actually
       pushes the arguments, calls the function and unpacks any return  value.   This  is  called
       avcall_call().  A  precompiled  assembler  version  for  people  without  gcc is also made
       available. The routine should ideally have flags for  the  passing  conventions  of  other

       Many  of  the current routines waste a lot of stack space and generally do hairy things to
       stack frames - a bit more assembly code would probably help things along quite a bit here.


       Bill Triggs <>.


       Some initial ideas were stolen from the C interface  to  the  Zelk  extensions  to  Oliver
       Laumann's  Elk  scheme interpreter by J.P.Lewis, NEC C&C Research, <>
       (for Sun4 & SGI), and Roy Featherstone's <>  personal  C  interface
       library  for  Sun[34]  & SGI.  I also looked at the machine-dependent parts of the GCC and
       GDB distributions, and put the gcc asm() extensions to good use. Thanks guys!

       This work was partly supported by EC-ESPRIT Basic Research Action SECOND.

                                           23 July 2017                                 AVCALL(3)