[Vm-dev] FFI: Vararg function how to tell callee how many arguments i passed?

Eliot Miranda eliot.miranda at gmail.com
Mon Sep 27 17:27:34 UTC 2010


On Mon, Sep 27, 2010 at 2:28 AM, Bert Freudenberg <bert at freudenbergs.de>wrote:

>
>
> On 27.09.2010, at 01:23, Igor Stasenko wrote:
>
> >
> > On 27 September 2010 02:12, Levente Uzonyi <leves at elte.hu> wrote:
> >>
> >> On Mon, 27 Sep 2010, Igor Stasenko wrote:
> >>
> >>>
> >>> Suppose i want to call printf() using FFI.
> >>> But it is a variable argument function. What should do to let it know
> >>> how many arguments i passed?
> >>
> >> I think you don't tell it, it guesses the number of arguments from the
> first
> >> argument. If you pass invalid arguments, something bad will happen. :)
> >>
> >
> > Yeah.. i inspected the assembly (gcc -s) for printf call,
> > and there is only pushes of arguments , no extra info.
>
> Vararg functions are specially compiled. They do not use the regular
> platform calling conventions. That's because the same compiled function
> needs to be able to take any type of argument. Whereas e.g. floats are
> normally passed on the float stack, in a vararg function call they might be
> passed on the regular stack. Also they are converted to doubles at the
> calling side, just as chars and shorts are promoted to ints.
>
> So at the calling site the compiler has to do special magic to construct
> the argument list. It can only do this if you actually provide a vararg
> call. That is, you need to literally write a printf() call to make this
> work. There is no portable way around this - the C FAQ states (*)
>
> Q: How can I call a function with an argument list built up at run time?
> A: There is no guaranteed or portable way to do this.
>
> Squeak's FFI does not support vararg functions yet. There are other FFIs
> that do (CLISP's vacall library, Rubinius FFI), so taking a look there might
> help if anyone wants to implement this.
>

While the image-level facilities may not exist the VM
provides primitiveCalloutWithArgs which implements
ExternalFunction>>invokeWithArguments: and that could be used to do varargs
calls.  One has to synthesize the ExternalFunction because the primitive
still needs a type vector for the arguments.   But I think it could do the
job.

cheers
Eliot

>
> - Bert -
>
> (*) http://c-faq.com/varargs/invvarargs.html
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/vm-dev/attachments/20100927/dffe95d5/attachment.htm


More information about the Vm-dev mailing list