Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
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 ar-
       chitecture 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  re-
	      turn  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 ig-
       nored and assumed to be 1. For structs of size >	2*sizeof(long),	split-
       table 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  ex-
       plicit  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 de-
       clared, 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 un-
       packs 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)

Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=avcall&sektion=3&manpath=FreeBSD+Ports+14.3.quarterly>

home | help