File: avcall.man

package info (click to toggle)
ffcall 2.5-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 9,024 kB
  • sloc: asm: 100,607; ansic: 50,932; sh: 5,630; makefile: 1,588; cpp: 2
file content (198 lines) | stat: -rw-r--r-- 10,271 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
AVCALL(3)                  Library Functions Manual                  AVCALL(3)



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

SYNOPSIS
       #include <avcall.h>

       av_alist alist;

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

       av_type(alist, [arg_type,] value);

       av_call(alist);

DESCRIPTION
       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 func‐
       tions 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  depen‐
              dent.  Compiler options that affect passing conventions may need
              to be flagged by #defines before the #include <avcall.h>  state‐
              ment. 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.

       E.g.,

       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,
                        &struct_return);

       av_start_ptr (alist, &func, pointer_type,
                     &pointer_return);

       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 struc‐
              ture 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);


NOTES
       (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-con‐
       vert 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 double.

       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  conven‐
       tions.   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.


SEE ALSO
       stdarg(3), varargs(3).


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


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


PORTING AVCALL
       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;  func‐
       tion 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
       compilers.

       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 proba‐
       bly help things along quite a bit here.


AUTHOR
       Bill Triggs <Bill.Triggs@inrialpes.fr>.


ACKNOWLEDGEMENTS
       Some initial ideas were stolen from the C interface to the Zelk  exten‐
       sions  to Oliver Laumann's Elk scheme interpreter by J.P.Lewis, NEC C&C
       Research, <zilla@ccrl.nj.nec.com> (for Sun4 & SGI),  and  Roy  Feather‐
       stone's  <roy@robots.oxford.ac.uk>  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  SEC‐
       OND.




                                 23 July 2017                        AVCALL(3)