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

NAME

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

SYNOPSIS

10       #include <avcall.h>
11
12       av_alist alist;
13
14       av_start_type(alist, &func [[, return_type], &return_value ]);
15
16       av_type(alist, [arg_type,] value);
17
18       av_call(alist);
19

DESCRIPTION

21       This set of macros builds an argument list for a C function  and  calls
22       the  function on it. It significantly reduces the amount of `glue' code
23       required for parsers, debuggers, imbedded interpreters, C extensions to
24       application  programs  and  other situations where collections of func‐
25       tions need to be called on lists of externally-supplied arguments.
26
27       Function calling conventions differ considerably on different  machines
28       and  avcall  attempts  to  provide  some  degree of isolation from such
29       architecture dependencies.
30
31       The interface is like stdarg(3) in reverse. All of the macros return  0
32       for success, < 0 for failure (e.g., argument list overflow or type-not-
33       supported).
34
35       (1)    #include <avcall.h>
36              and declare the argument list structure
37              av_alist alist;
38
39       (2)    Set any special flags. This is architecture and compiler  depen‐
40              dent.  Compiler options that affect passing conventions may need
41              to be flagged by #defines before the #include <avcall.h>  state‐
42              ment. However, the configure script should have determined which
43              #defines are needed and put them at the top of avcall.h.
44
45       (3)    Initialize the alist with the function address and return  value
46              pointer  (if  any).  There  is  a separate macro for each simple
47              return type ([u]char, [u]short,  [u]int,  [u]long,  [u]longlong,
48              float,  double,  where `u' indicates `unsigned'). The macros for
49              functions returning structures or pointers require  an  explicit
50              type argument.
51
52       E.g.,
53
54       av_start_int (alist, &func, &int_return);
55
56       av_start_double (alist, &func, &double_return);
57
58       av_start_void (alist, &func);
59
60       av_start_struct (alist, &func, struct_type, splittable,
61                        &struct_return);
62
63       av_start_ptr (alist, &func, pointer_type,
64                     &pointer_return);
65
66       The  splittable  flag specifies whether the struct_type can be returned
67       in registers such that every struct field fits  entirely  in  a  single
68       register.   This   needs   to   be   specified   for  structs  of  size
69       2*sizeof(long). For structs of  size  <=  sizeof(long),  splittable  is
70       ignored  and  assumed  to  be  1. For structs of size > 2*sizeof(long),
71       splittable is ignored and assumed to be 0. There are some handy  macros
72       for this:
73       av_word_splittable_1 (type1)
74       av_word_splittable_2 (type1, type2)
75       av_word_splittable_3 (type1, type2, type3)
76       av_word_splittable_4 (type1, type2, type3, type4)
77       For a struct with three slots
78       struct { type1 id1; type2 id2; type3 id3; }
79       you  can  specify  splittable  as  av_word_splittable_3  (type1, type2,
80       type3) .
81
82       (4)    Push the arguments on to the list in order.  Again  there  is  a
83              macro  for  each simple built-in type, and the macros for struc‐
84              ture and pointer arguments require an extra type argument:
85
86       av_int (alist, int_value);
87
88       av_double (alist, double_value);
89
90       av_struct (alist, struct_or_union_type, struct_value);
91
92       av_ptr (alist, pointer_type, pointer_value);
93
94       (5)    Call the function, set the return value, and tidy up:
95
96       av_call (alist);
97
98

NOTES

100       (1) Functions whose first declaration is in Kernighan &  Ritchie  style
101       (i.e., without a typed argument list) MUST use default K&R C expression
102       promotions (char and short to int, float to double)  whether  they  are
103       compiled  by a K&R or an ANSI compiler, because the true argument types
104       may not be known at the call point. Such functions typically  back-con‐
105       vert their arguments to the declared types on function entry. (In fact,
106       the only way to pass a true char, short or float in  K&R  C  is  by  an
107       explicit cast: func((char)c,(float)f) ).  Similarly, some K&R compilers
108       (such as Sun cc on the sparc) actually return a float as a double.
109
110       Hence, for arguments of functions declared in K&R style you should  use
111       av_int()   and   av_double()   rather  than  av_char(),  av_short()  or
112       av_float().  If you use a K&R compiler, the avcall header files may  be
113       able to detect this and define av_float(), etc, appropriately, but with
114       an ANSI compiler there is no way avcall can know  how  a  function  was
115       declared, so you have to correct the argument types yourself.
116
117       (2)  The explicit type arguments of the av_struct() and av_ptr() macros
118       are typically used to calculate size, alignment,  and  passing  conven‐
119       tions.   This  may  not  be  sufficient  for some machines with unusual
120       structure and pointer handling: in this case additional av_start_type()
121       and av_type() macros may be defined.
122
123       (3) The macros av_start_longlong(), av_start_ulonglong(), av_longlong()
124       and av_ulonglong() work only if the C compiler has a working long  long
125       64-bit integer type.
126
127       (4)  The  struct  types  used in av_start_struct() and av_struct() must
128       only contain (signed or unsigned)  int,  long,  long  long  or  pointer
129       fields.   Struct  types  containing  (signed  or unsigned) char, short,
130       float, double or other structs are not supported.
131
132

SEE ALSO

134       stdarg(3), varargs(3).
135
136

BUGS

138       The current implementations have been tested on a selection  of  common
139       cases but there are probably still many bugs.
140
141       There  are  typically built-in limits on the size of the argument-list,
142       which may also include the size of any structure arguments.
143
144       The decision whether a struct is to be returned in registers or in mem‐
145       ory considers only the struct's size and alignment. This is inaccurate:
146       for example, gcc on m68k-next returns struct { char a,b,c; } in  regis‐
147       ters  and struct { char a[3]; } in memory, although both types have the
148       same size and the same alignment.
149
150

NON-BUGS

152       All information is passed in CPU registers and the  stack.  The  avcall
153       package is therefore multithread-safe.
154
155

PORTING AVCALL

157       Ports, bug-fixes, and suggestions are most welcome. The macros required
158       for argument pushing are pretty grungy, but it does seem to be possible
159       to  port  avcall  to  a  range  of  machines.  Ports to non-standard or
160       non-32-bit machines are especially welcome so we can sort the interface
161       out before it's too late.
162
163       Knowledge  about  argument  passing conventions can be found in the gcc
164       source, file gcc-2.6.3/config/cpu/cpu.h, section "Stack  layout;  func‐
165       tion entry, exit and calling."
166
167       Some  of  the  grunge  is usually handled by a C or assembly level glue
168       routine that actually pushes the  arguments,  calls  the  function  and
169       unpacks  any return value.  This is called avcall_call(). A precompiled
170       assembler version for people without gcc is also  made  available.  The
171       routine  should ideally have flags for the passing conventions of other
172       compilers.
173
174       Many of the current routines waste a lot of stack space  and  generally
175       do hairy things to stack frames - a bit more assembly code would proba‐
176       bly help things along quite a bit here.
177
178

AUTHOR

180       Bill Triggs <Bill.Triggs@inrialpes.fr>.
181
182

ACKNOWLEDGEMENTS

184       Some initial ideas were stolen from the C interface to the Zelk  exten‐
185       sions  to Oliver Laumann's Elk scheme interpreter by J.P.Lewis, NEC C&C
186       Research, <zilla@ccrl.nj.nec.com> (for Sun4 & SGI),  and  Roy  Feather‐
187       stone's  <roy@robots.oxford.ac.uk>  personal  C  interface  library for
188       Sun[34] & SGI.  I also looked at the machine-dependent parts of the GCC
189       and  GDB  distributions,  and put the gcc asm() extensions to good use.
190       Thanks guys!
191
192       This work was partly supported by EC-ESPRIT Basic Research Action  SEC‐
193       OND.
194
195
196
197
198                                 23 July 2017                        AVCALL(3)
Impressum