home *** CD-ROM | disk | FTP | other *** search
-
-
-
- AVCALL(3) AVCALL(3)
-
-
- NNAAMMEE
- avcall - build a C argument list incrementally and call a
- C function on it.
-
- SSYYNNOOPPSSIISS
- ##iinncclluuddee <<aavvccaallll..hh>>
-
- aavv__aalliisstt _a_l_i_s_t;;
-
- aavv__ssttaarrtt___t_y_p_e((_a_l_i_s_t,, _&_f_u_n_c [[,, _r_e_t_u_r_n___t_y_p_e],, _&_r_e_t_u_r_n___v_a_l_u_e
- ]));;
-
- aavv___t_y_p_e((_a_l_i_s_t,, [_a_r_g___t_y_p_e,,] _v_a_l_u_e));;
-
- aavv__ccaallll((_a_l_i_s_t));;
-
- DDEESSCCRRIIPPTTIIOONN
- This set of macros builds an argument list for a C func-
- tion and calls the function on it. It significantly
- reduces the amount of `glue' code required for parsers,
- debuggers, imbedded interpreters, C extensions to applica-
- tion programs and other situations where collections of
- functions need to be called on lists of externally-
- supplied arguments.
-
- Function calling conventions differ considerably on dif-
- ferent machines and _a_v_c_a_l_l attempts to provide some degree
- of isolation from such architecture dependencies.
-
- The interface is like ssttddaarrgg(3) in reverse. All of the
- macros return 0 for success, < 0 for failure (e.g., argu-
- ment list overflow or type-not-supported).
-
- (1) ##iinncclluuddee <<aavvccaallll..hh>>
- and declare the argument list structure
- aavv__aalliisstt _a_l_i_s_t;;
-
- (2) Set any special flags. This is architecture and
- compiler dependent. Compiler options that affect
- passing conventions may need to be flagged by
- ##ddeeffiinnees before the ##iinncclluuddee <<aavvccaallll..hh>> statement.
- However, the _c_o_n_f_i_g_u_r_e script should have deter-
- mined which ##ddeeffiinnees are needed and put them at the
- top of aavvccaallll..hh.
-
- (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, float, double, where `u'
- indicates `unsigned'). The macros for functions
- returning structures or pointers require an
- explicit type argument.
-
- E.g.,
-
-
-
- 10 March 1995 1
-
-
-
-
-
- AVCALL(3) AVCALL(3)
-
-
- aavv__ssttaarrtt__iinntt ((_a_l_i_s_t,, _&_f_u_n_c,, _&_i_n_t___r_e_t_u_r_n));;
-
- aavv__ssttaarrtt__ddoouubbllee ((_a_l_i_s_t,, _&_f_u_n_c,, _&_d_o_u_b_l_e___r_e_t_u_r_n));;
-
- aavv__ssttaarrtt__vvooiidd ((_a_l_i_s_t,, _&_f_u_n_c));;
-
- aavv__ssttaarrtt__ssttrruucctt ((_a_l_i_s_t,, _&_f_u_n_c,, _s_t_r_u_c_t___t_y_p_e,, _s_p_l_i_t_t_a_b_l_e,,
- _&_s_t_r_u_c_t___r_e_t_u_r_n));;
-
- aavv__ssttaarrtt__ppttrr ((_a_l_i_s_t,, _&_f_u_n_c,, _p_o_i_n_t_e_r___t_y_p_e,,
- _&_p_o_i_n_t_e_r___r_e_t_u_r_n));;
-
- The _s_p_l_i_t_t_a_b_l_e flag specifies whether the _s_t_r_u_c_t___t_y_p_e 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), _s_p_l_i_t_t_a_b_l_e is ignored and assumed to be 1.
- For structs of size > 2*sizeof(long), _s_p_l_i_t_t_a_b_l_e is
- ignored and assumed to be 0. There are some handy macros
- for this:
- aavv__wwoorrdd__sspplliittttaabbllee__11 ((_t_y_p_e_1))
- aavv__wwoorrdd__sspplliittttaabbllee__22 ((_t_y_p_e_1,, _t_y_p_e_2))
- aavv__wwoorrdd__sspplliittttaabbllee__33 ((_t_y_p_e_1,, _t_y_p_e_2,, _t_y_p_e_3))
- aavv__wwoorrdd__sspplliittttaabbllee__44 ((_t_y_p_e_1,, _t_y_p_e_2,, _t_y_p_e_3,, _t_y_p_e_4))
- For a struct with three slots
- ssttrruucctt {{ _t_y_p_e_1 _i_d_1;; _t_y_p_e_2 _i_d_2;; _t_y_p_e_3 _i_d_3;; }}
- you can specify _s_p_l_i_t_t_a_b_l_e as aavv__wwoorrdd__sspplliittttaabbllee__33 ((_t_y_p_e_1,,
- _t_y_p_e_2,, _t_y_p_e_3)) .
-
- (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:
-
- aavv__iinntt ((_a_l_i_s_t,, _i_n_t___v_a_l_u_e));;
-
- aavv__ddoouubbllee ((_a_l_i_s_t,, _d_o_u_b_l_e___v_a_l_u_e));;
-
- aavv__ssttrruucctt ((_a_l_i_s_t,, _s_t_r_u_c_t___o_r___u_n_i_o_n___t_y_p_e,, _s_t_r_u_c_t___v_a_l_u_e));;
-
- aavv__ppttrr ((_a_l_i_s_t,, _p_o_i_n_t_e_r___t_y_p_e,, _p_o_i_n_t_e_r___v_a_l_u_e));;
-
- (5) Call the function, set the return value, and tidy
- up:
-
- aavv__ccaallll ((_a_l_i_s_t));;
-
-
- NNOOTTEESS
- (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
-
-
-
- 10 March 1995 2
-
-
-
-
-
- AVCALL(3) AVCALL(3)
-
-
- 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:
- ffuunncc((((cchhaarr))cc,,((ffllooaatt))ff)) ). 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 aavv__iinntt(()) and aavv__ddoouubbllee(()) rather than
- aavv__cchhaarr(()),, aavv__sshhoorrtt(()) or aavv__ffllooaatt(()).. If you use a K&R
- compiler, the avcall header files may be able to detect
- this and define aavv__ffllooaatt(()),, etc, appropriately, but with
- an ANSI compiler there is no way _a_v_c_a_l_l can know how a
- function was declared, so you have to correct the argument
- types yourself.
-
- (2) The explicit type arguments of the aavv__ssttrruucctt(()) and
- aavv__ppttrr(()) macros are typically used to calculate size,
- alignment, and passing conventions. This may not be suf-
- ficient for some machines with unusual structure and
- pointer handling: in this case additional aavv__ssttaarrtt___t_y_p_e(())
- and aavv___t_y_p_e(()) macros may be defined.
-
-
- SSEEEE AALLSSOO
- ssttddaarrgg(3), vvaarraarrggss(3).
-
-
- BBUUGGSS
- The current implementations have been tested on a selec-
- tion 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 regis-
- ters or in memory considers only the struct's size and
- alignment. This is inaccurate: for example, gcc on m68k-
- next returns ssttrruucctt {{ cchhaarr aa,,bb,,cc;; }} in registers and
- ssttrruucctt {{ cchhaarr aa[[33]];; }} in memory, although both types have
- the same size and the same alignment.
-
-
- PPOORRTTIINNGG AAVVCCAALLLL
- 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.
-
-
-
-
- 10 March 1995 3
-
-
-
-
-
- AVCALL(3) AVCALL(3)
-
-
- Knowledge about argument passing conventions can be found
- in the gcc source, file gcc-2.6.3/config/_c_p_u/_c_p_u.h, sec-
- tion "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.
-
-
- AAUUTTHHOORR
- Bill Triggs <bill@robots.oxford.ac.uk>.
-
-
- AACCKKNNOOWWLLEEDDGGEEMMEENNTTSS
- 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.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 10 March 1995 4
-
-
-