avcall.3
上传用户:shenzhenrh
上传日期:2013-05-12
资源大小:2904k
文件大小:8k
- .TH AVCALL 3 "14 January 2001"
- .SH NAME
- avcall - build a C argument list incrementally and call a C function on it.
- .SH SYNOPSIS
- .B #include <avcall.h>
- .LP
- .BI "av_alist " alist ";"
- .LP
- .BI av_start_ type "(" alist ", " "&func"
- .RI "[["c
- .BI ", "c
- .I return_typec
- .RB "]" ", "c
- .I "&return_value"c
- .RB "]" ");"
- .LP
- .BI av_ type "(" alist ", "c
- .RI "["c
- .IB arg_type ","c
- .RI "] "c
- .IB value ");"
- .LP
- .BI "av_call(" alist ");"
- .IX "av_alist" "" "fLav_alistfP (em avcall argument list declaration"
- .IX "av_start_type()" "" "fLav_start_type()fP (em initialize avcall function"
- .IX "av_type()" "" "fLav_type()fP (em push next argument in avcall list"
- .IX "av_call()" "" "fLav_call()fP (em finish avcall argument list and call function"
- .SH DESCRIPTION
- .LP
- 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
- .I avcall
- attempts to provide some degree of isolation from such architecture
- dependencies.
- The interface is like
- .BR stdarg (3)
- in reverse. All of the macros return 0 for success, < 0 for failure (e.g.,
- argument list overflow or type-not-supported).
- .RS 0
- .TP
- (1)
- .B #include <avcall.h>
- .nf
- and declare the argument list structure
- .BI "av_alist " alist ;
- .fi
- .TP
- (2)
- Set any special flags. This is architecture and compiler dependent.
- Compiler options that affect passing conventions may need to be flagged
- by
- .BR "#define" s
- before the
- .B "#include <avcall.h>"
- statement. However, the
- .I configure
- script should have determined which
- .BR "#define" s
- are needed and put them
- at the top of
- .BR avcall.h .
- .TP
- (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.
- .LP
- E.g.,
- .LP
- .BI "av_start_int (" alist ", " &func ", " &int_return );
- .LP
- .BI "av_start_double (" alist ", " &func ", " &double_return );
- .LP
- .BI "av_start_void (" alist ", " &func );
- .LP
- .nf
- .BI "av_start_struct (" alist ", " &func ", " struct_type ", " splittable ", "
- .BI " " &struct_return );
- .fi
- .LP
- .nf
- .BI "av_start_ptr (" alist ", " &func ", " pointer_type ", "
- .BI " " &pointer_return );
- .fi
- .LP
- The
- .I splittable
- flag specifies whether the
- .I 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),
- .I splittable
- is ignored and assumed to be 1. For structs of size > 2*sizeof(long),
- .I splittable
- is ignored and assumed to be 0. There are some handy macros for this:
- .nf
- .BI "av_word_splittable_1 (" type1 )
- .BI "av_word_splittable_2 (" type1 ", " type2 )
- .BI "av_word_splittable_3 (" type1 ", " type2 ", " type3 )
- .BI "av_word_splittable_4 (" type1 ", " type2 ", " type3 ", " type4 )
- .fi
- For a struct with three slots
- .nf
- .BI "struct { " "type1 id1" "; " "type2 id2" "; " "type3 id3" "; }"
- .fi
- you can specify
- .I splittable
- as
- .BI "av_word_splittable_3 (" type1 ", " type2 ", " type3 )
- .RB .
- .TP
- (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:
- .LP
- .BI "av_int (" alist ", " int_value );
- .LP
- .BI "av_double (" alist ", " double_value );
- .LP
- .BI "av_struct (" alist ", " struct_or_union_type ", " struct_value );
- .LP
- .BI "av_ptr (" alist ", " pointer_type ", " pointer_value );
- .TP
- (5)
- Call the function, set the return value, and tidy up:
- .LP
- .BI "av_call (" alist );
- .RE
- .SH 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-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:
- .B 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
- .B av_int(|)
- and
- .B av_double(|)
- rather than
- .B av_char(|),
- .B av_short(|)
- or
- .B av_float(|).
- If you use a K&R compiler, the avcall header files may be able to
- detect this and define
- .B av_float(|),
- etc, appropriately, but with an ANSI compiler there is no way
- .I avcall
- can know how a function was declared, so you have to correct the
- argument types yourself.
- (2) The explicit type arguments of the
- .B av_struct(|)
- and
- .B 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
- .B av_start_c
- .I typec
- .B (|)
- and
- .B av_c
- .I typec
- .B (|)
- macros may be defined.
- (3) The macros
- .BR av_start_longlong(|) ,
- .BR av_start_ulonglong(|) ,
- .B av_longlong(|)
- and
- .B av_ulonglong(|)
- work only if the C compiler has a working
- .B long long
- 64-bit integer type.
- (4) The struct types used in
- .B av_start_struct(|)
- and
- .B 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.
- .SH SEE ALSO
- .BR stdarg (3),
- .BR varargs (3).
- .SH 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 memory
- considers only the struct's size and alignment. This is inaccurate: for
- example, gcc on m68k-next returns
- .B "struct { char a,b,c; }"
- in registers and
- .B "struct { char a[3]; }"
- in memory, although both types have the same size and the same alignment.
- .SH NON-BUGS
- All information is passed in CPU registers and the stack. The
- .B avcall
- package is therefore multithread-safe.
- .SH 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
- .RI 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 __builtin_avcall(|). 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 probably
- help things along quite a bit here.
- .SH AUTHOR
- Bill Triggs <Bill.Triggs@inrialpes.fr>.
- .SH ACKNOWLEDGEMENTS
- 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, <zilla@ccrl.nj.nec.com> (for Sun4 & SGI), and Roy
- Featherstone'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 SECOND.