avcall.html
来自「FinC编译器源代码」· HTML 代码 · 共 266 行
HTML
266 行
<HEAD><TITLE> AVCALL manual page </TITLE></HEAD><BODY><H1>AVCALL manual page</H1><UL><LI> <A HREF="#Name">Name</A><LI> <A HREF="#Synopsis">Synopsis</A><LI> <A HREF="#Description">Description</A><LI> <A HREF="#Notes">Notes</A><LI> <A HREF="#See also">See also</A><LI> <A HREF="#Bugs">Bugs</A><LI> <A HREF="#Non-Bugs">Non-Bugs</A><LI> <A HREF="#Porting AVCALL">Porting AVCALL</A><LI> <A HREF="#Author">Author</A><LI> <A HREF="#Acknowledgements">Acknowledgements</A></UL><P><HR><A NAME="Name"><H2>Name</H2></A>avcall - build a C argument list incrementally and call aC function on it.<A NAME="Synopsis"><H2>Synopsis</H2></A><PRE><CODE>#include <avcall.h></CODE><CODE>av_alist <VAR>alist</VAR>;</CODE><CODE>av_start_<VAR>type</VAR> (<VAR>alist</VAR>, &<VAR>func</VAR>, [[<VAR>return_type</VAR>,] &<VAR>return_value</VAR>]);</CODE><CODE>av_<VAR>type</VAR> (<VAR>alist</VAR>, [<VAR>arg_type</VAR>,] <VAR>value</VAR>);</CODE><CODE>av_call(<VAR>alist</VAR>);</CODE></PRE><A NAME="Description"><H2>Description</H2></A>This set of macros builds an argument list for a C functionand calls the function on it. It significantlyreduces the amount of `glue' code required for parsers,debuggers, imbedded interpreters, C extensions to applicationprograms and other situations where collections offunctions need to be called on lists of externally-supplied arguments.<P>Function calling conventions differ considerably on differentmachines and <CODE>avcall</CODE> attempts to provide some degreeof isolation from such architecture dependencies.<P>The interface is like <A HREF="stdarg(3)"><CODE><B>stdarg</B></CODE></A>(3) in reverse. All of themacros return 0 for success, < 0 for failure (e.g., argumentlist overflow or type-not-supported).<P><OL><LI> <CODE>#include <avcall.h></CODE> and declare the argument liststructure <CODE>av_alist <VAR>alist</VAR>;</CODE><P><LI> Set any special flags. This is architecture and compilerdependent.Compiler options that affect passing conventions may needto be flagged by <CODE>#define</CODE>s before the <CODE>#include <avcall.h></CODE>statement. However, the <SAMP>configure</SAMP> script should havedetermined which <CODE>#define</CODE>s are needed and put themat the top of <SAMP>avcall.h</SAMP>.<P><LI> Initialize the alist with the function address andreturn value pointer (if any). There is a separate macrofor 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 structuresor pointers require an explicit type argument.<P>E.g.,<PRE><CODE>av_start_int (<VAR>alist</VAR>, &<VAR>func</VAR>, &<VAR>int_return</VAR>);</CODE><CODE>av_start_double (<VAR>alist</VAR>, &<VAR>func</VAR>, &<VAR>double_return</VAR>);</CODE><CODE>av_start_void (<VAR>alist</VAR>, &<VAR>func</VAR>);</CODE><CODE>av_start_struct (<VAR>alist</VAR>, &<VAR>func</VAR>, <VAR>struct_type</VAR>, <VAR>splittable</VAR>, &<VAR>struct_return</VAR>);</CODE><CODE>av_start_ptr (<VAR>alist</VAR>, &<VAR>func</VAR>, <VAR>pointer_type</VAR>, &<VAR>pointer_return</VAR>);</CODE></PRE>The <VAR>splittable</VAR> flag specifies whether the <VAR>struct_type</VAR> canbe returned in registers such that every struct field fitsentirely in a single register. This needs to be specifiedfor structs of size <SAMP>2*sizeof(long)</SAMP>. For structs of size<= <SAMP>sizeof(long)</SAMP>, splittable is ignored and assumed to be 1.For structs of size > <SAMP>2*sizeof(long)</SAMP>, splittable isignored and assumed to be 0. There are some handy macrosfor this:<PRE><CODE>av_word_splittable_1 (<VAR>type1</VAR>)</CODE><CODE>av_word_splittable_2 (<VAR>type1</VAR>, <VAR>type2</VAR>)</CODE><CODE>av_word_splittable_3 (<VAR>type1</VAR>, <VAR>type2</VAR>, <VAR>type3</VAR>)</CODE><CODE>av_word_splittable_4 (<VAR>type1</VAR>, <VAR>type2</VAR>, <VAR>type3</VAR>, <VAR>type4</VAR>)</CODE></PRE>For a struct with three slots<PRE><CODE>struct { <VAR>type1 id1</VAR>; <VAR>type2 id2</VAR>; <VAR>type3 id3</VAR>; }</CODE></PRE>you can specify <VAR>splittable</VAR> as<CODE>av_word_splittable_3 (<VAR>type1</VAR>, <VAR>type2</VAR>, <VAR>type3</VAR>)</CODE>.<P><LI> Push the arguments on to the list in order. Againthere is a macro for each simple built-in type, and themacros for structure and pointer arguments require anextra type argument:<PRE><CODE>av_int (<VAR>alist</VAR>, <VAR>int_value</VAR>);</CODE><CODE>av_double (<VAR>alist</VAR>, <VAR>double_value</VAR>);</CODE><CODE>av_struct (<VAR>alist</VAR>, <VAR>struct_or_union_type</VAR>, <VAR>struct_value</VAR>);</CODE><CODE>av_ptr (<VAR>alist</VAR>, <VAR>pointer_type</VAR>, <VAR>pointer_value</VAR>);</CODE></PRE><LI> Call the function, set the return value, and tidy up:<CODE>av_call (<VAR>alist</VAR>);</CODE></OL><A NAME="Notes"><H2>Notes</H2></A><OL><LI> Functions whose first declaration is in Kernighan &Ritchie style (i.e., without a typed argument list) MUSTuse default K&R C expression promotions (<CODE>char</CODE> and <CODE>short</CODE> to<CODE>int</CODE>, <CODE>float</CODE> to <CODE>double</CODE>) whether they are compiled by a K&Ror an ANSI compiler, because the true argument types maynot be known at the call point. Such functions typicallyback-convert their arguments to the declared types onfunction entry. (In fact, the only way to pass a true<CODE>char</CODE>, <CODE>short</CODE> or <CODE>float</CODE> in K&R C is by an explicit cast:<CODE>func((char)c,(float)f)</CODE> ). Similarly, some K&R compilers(such as Sun <SAMP>cc</SAMP> on the sparc) actually return a <CODE>float</CODE> as a<CODE>double</CODE>.<P>Hence, for arguments of functions declared in K&R styleyou should use <CODE>av_int()</CODE> and </CODE>av_double()</CODE> rather than<CODE>av_char()</CODE>, <CODE>av_short()</CODE> or <CODE>av_float()</CODE>. If you use a K&Rcompiler, the avcall header files may be able to detectthis and define <CODE>av_float()</CODE>, etc, appropriately, but withan ANSI compiler there is no way <B>avcall</B> can know how afunction was declared, so you have to correct the argumenttypes yourself.<P><LI> The explicit type arguments of the <CODE>av_struct()</CODE> and<CODE>av_ptr()</CODE> macros are typically used to calculate size,alignment, and passing conventions. This may not be sufficient for some machines with unusual structure andpointer handling: in this case additional <CODE>av_start_<VAR>type</VAR>()</CODE>and <CODE>av_<VAR>type</VAR>()</CODE> macros may be defined.<P><LI> The macros <CODE>av_start_longlong()</CODE>,<CODE>av_start_ulonglong()</CODE>, <CODE>av_longlong()</CODE> and<CODE>av_ulonglong()</CODE> work only if the C compiler has a working<CODE>long long</CODE> 64-bit integer type.<P><LI> The struct types used in <CODE>av_start_struct()</CODE> and<CODE>av_struct()</CODE> must only contain (signed or unsigned) int,long, long long or pointer fields. Struct types containing(signed or unsigned) char, short, float, double or otherstructs are not supported.<P></OL><A NAME="See also"><H2>See also</H2></A><A HREF="stdarg(3)"><CODE><B>stdarg</B></CODE></A>(3), <A HREF="varargs(3)"><CODE><B>varargs</B></CODE></A>(3).<A NAME="Bugs"><H2>Bugs</H2></A><UL><LI>The current implementations have been tested on a selectionof common cases but there are probably still manybugs.<LI>There are typically built-in limits on the size of theargument-list, which may also include the size of anystructure arguments.<LI>The decision whether a struct is to be returned in registers or in memoryconsiders only the struct's size and alignment. This is inaccurate: forexample, gcc on m68k-next returns<CODE>struct { char a,b,c; }</CODE>in registers and<CODE>struct { char a[3]; }</CODE>in memory, although both types have the same size and the same alignment.</UL><A NAME="Non-Bugs"><H2>Non-Bugs</H2></A>All information is passed in CPU registers and the stack.The <CODE><B>avcall</B></CODE> package is therefore multithread-safe.<A NAME="Porting AVCALL"><H2>Porting AVCALL</H2></A>Ports, bug-fixes, and suggestions are most welcome. Themacros required for argument pushing are pretty grungy,but it does seem to be possible to port avcall to a rangeof machines. Ports to non-standard or non-32-bit machinesare especially welcome so we can sort the interface outbefore it's too late.<P>Knowledge about argument passing conventions can be foundin the gcc source, file <SAMP>gcc-2.6.3/config/<VAR>cpu</VAR>/<VAR>cpu</VAR>.h</SAMP>, section<SAMP>"Stack layout; function entry, exit and calling."</SAMP><P>Some of the grunge is usually handled by a C or assemblylevel glue routine that actually pushes the arguments,calls the function and unpacks any return value. This iscalled <CODE>__builtin_avcall()</CODE>. A precompiled assembler version forpeople without gcc is also made available. The routine should ideallyhave flags for the passing conventions of other compilers.<P>Many of the current routines waste a lot of stack spaceand generally do hairy things to stack frames - a bit moreassembly code would probably help things along quite a bithere.<P><A NAME="Author"><H2>Author</H2></A>Bill Triggs <Bill.Triggs@inrialpes.fr>, <Bill.Triggs@imag.fr>.<A NAME="Acknowledgements"><H2>Acknowledgements</H2></A>Some initial ideas were stolen from the C interface to theZelk extensions to Oliver Laumann's Elk scheme interpreterby J.P.Lewis, NEC C&C Research, <zilla@ccrl.nj.nec.com>(for Sun4 & SGI), and Roy Featherstone's<roy@robots.oxford.ac.uk> personal C interface library forSun3, Sun4 & SGI. I also looked at the machine-dependentparts of the GCC and GDB distributions, and put the gcc<CODE>asm()</CODE> extensions to good use. Thanks guys!<P>This work was partly supported by EC-ESPRIT Basic ResearchAction SECOND.<P><HR><ADDRESS>AVCALL manual page<BR>Bruno Haible <bruno@clisp.org></ADDRESS><P>Last modified: 14 January 2001.</BODY>
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?