public inbox for libffi-discuss@sourceware.org
 help / color / mirror / Atom feed
* Variadic functions and libffi
@ 2011-01-05 17:50 David Gilbert
  2011-01-05 18:37 ` Andrew Haley
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: David Gilbert @ 2011-01-05 17:50 UTC (permalink / raw)
  To: libffi-discuss; +Cc: Marcus.Shawcroft, cltang

Hi,
  As part of the linaro toolchain effort for ARM, I've been asked to
look at Variadic function calls in libffi,
specifically for the ARM 'hard float' (aka PCS_VFP or FFI_VFP, armhf)
variant and wanted to see what
people thought before I dived in to it.

  The ARM hard float variant is a variant of the ABI in which floating
point values are passed in floating point
registers (as opposed to the standard ABI where FP values are still
passed in integer registers).  What makes
this ABI a little unusual is that for variadic functions it just falls
back to the standard all-integer-register ABI, and
thus, as an example, in the function:

   double foo(double bar, char *str, ...)

the return value and the 'bar' would be passed in integer registers
even though they aren't actually variadic
parameters.

It doesn't seem like there is any way out of this except for an API
change to libffi to state that a variadic function is being
called - so as I see it the questions then are:

   1) Does libffi really support variadic functions and/or is there a
desire to?  There are big warnings in various places saying
 it doesn't - but then the testcases call variadic functions, and at
least Python and SWIG both show examples of using it (with FP values).
On the other hand there is an ancient gcc bug
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=26744 to fix variadic on
PPC MacOS
marked as 'wishlist' because libffi doesn't support variadic.

   2) What's a good/minimal API change.

   3) Which FFI users actually use variadics and are hitting problems.

As for an API change, as far as ARM hard float is concerned we don't
actually care which parameters are
variadic, we just care that the function is declared variadic, so a
minimal change would be to define a FFI_DEFAULT_VARIADIC_ABI
that is the same as FFI_DEFAULT_ABI on everything except ARM hard
float, in which case it's set to FFI_SYSV, and when calling
ffi_prep_cif you would pass FFI_DEFAULT_VARIADIC_ABI rather than
FFI_DEFAULT_ABI for variadic calls.

That's simple for ARM but it seems unfair on any other architecture
that needs to fix things up.

I've had some discussion with Marcus Shawcroft (cc'd) and it looks
like the right solution is to declare a

'ffi_prep_cif_variadic'

that is just like ffi_prep_cif but also takes a 'nnamedargs' to say
the number of fixed args (and hence which arg is the 1st variadic).
For all architectures that don't care this can just call ffi_prep_cif
and lose the extra arg, this should mean it won't break anything else,
but any architecture that did need to know which were variadic args
would have that information.

I know that there are some other architectures that currently don't
work with variadic FP args; some might have to do something
special, but it's possible that some may be fixable without them
needing this ABI change - e.g. some might be able to pass
the FP values both in memory and FP registers and get away with this.

Closures are a separate question; I wouldn't propose supporting
variadic closures - but closures that take a fixed number of
parameters
but then call a variadic function sound doable using the same
ffi_prep_cif_variadic modification.

I've started putting together a list of FFI users with comments on
whether they use variadics - it's here
https://wiki.linaro.org/WorkingGroups/ToolChain/FFIusers
and I'd appreciate all input - I'm especially interested if anyone has
a real world app/test that uses variadics through ffi with fp.

All comments welcome, if people are happy with the proposed change,
I'm happy to do the change to libffi for ARM and make sure it doesn't
break the other arch that I have access to.

Dave

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Variadic functions and libffi
  2011-01-05 17:50 Variadic functions and libffi David Gilbert
@ 2011-01-05 18:37 ` Andrew Haley
  2011-01-05 19:28 ` Chung-Lin Tang
  2011-01-06 10:36 ` Andrew Haley
  2 siblings, 0 replies; 8+ messages in thread
From: Andrew Haley @ 2011-01-05 18:37 UTC (permalink / raw)
  To: David Gilbert; +Cc: libffi-discuss, Marcus.Shawcroft, cltang

On 01/05/2011 05:47 PM, David Gilbert wrote:

 >    As part of the linaro toolchain effort for ARM, I've been asked to
 > look at Variadic function calls in libffi,
 > specifically for the ARM 'hard float' (aka PCS_VFP or FFI_VFP, armhf)
 > variant and wanted to see what
 > people thought before I dived in to it.
 >
 >    The ARM hard float variant is a variant of the ABI in which floating
 > point values are passed in floating point
 > registers (as opposed to the standard ABI where FP values are still
 > passed in integer registers).  What makes
 > this ABI a little unusual is that for variadic functions it just falls
 > back to the standard all-integer-register ABI, and
 > thus, as an example, in the function:
 >
 >     double foo(double bar, char *str, ...)
 >
 > the return value and the 'bar' would be passed in integer registers
 > even though they aren't actually variadic
 > parameters.

Oh dear.  I was hoping that this was never going to happen: we just use a
common ABI, and we've basically ignored the issue.

 > It doesn't seem like there is any way out of this except for an API
 > change to libffi to state that a variadic function is being
 > called - so as I see it the questions then are:
 >
 >     1) Does libffi really support variadic functions and/or is there a
 > desire to?  There are big warnings in various places saying
 >   it doesn't - but then the testcases call variadic functions, and at
 > least Python and SWIG both show examples of using it (with FP values).

Right, and often targets use the same ABI for both n-adic and
variadic functions, so it doesn't matter.

 > I've had some discussion with Marcus Shawcroft (cc'd) and it looks
 > like the right solution is to declare a
 >
 > 'ffi_prep_cif_variadic'

I guess this is basically OK, as it can default to ffi_prep_cif on all
the targets where there is no difference.  It might open a real can of
worms, though.

Let this be a lesson to all ABI designers...

Andrew.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Variadic functions and libffi
  2011-01-05 17:50 Variadic functions and libffi David Gilbert
  2011-01-05 18:37 ` Andrew Haley
@ 2011-01-05 19:28 ` Chung-Lin Tang
  2011-01-06 10:36 ` Andrew Haley
  2 siblings, 0 replies; 8+ messages in thread
From: Chung-Lin Tang @ 2011-01-05 19:28 UTC (permalink / raw)
  To: David Gilbert; +Cc: libffi-discuss, Marcus.Shawcroft

On 2011/1/6 01:47, David Gilbert wrote:
> 'ffi_prep_cif_variadic'
> 
> that is just like ffi_prep_cif but also takes a 'nnamedargs' to say
> the number of fixed args (and hence which arg is the 1st variadic).
> For all architectures that don't care this can just call ffi_prep_cif
> and lose the extra arg, this should mean it won't break anything else,
> but any architecture that did need to know which were variadic args
> would have that information.

That sounds like a reasonable design, although it seems possible to do
away with the 'nnamedargs', and treat ffi_prep_cif_variadic() as
effectively just "adding an ellipse (...)", and leave the variable
argument issues to ffi_call().

This will effectively delay some of the normal ffi_prep_cif() work to
ffi_call() (things like laying out the regs/stack for the variable
arguments), and may be slower when doing the calling, but should be a
more intuitive API design; users just create the needed arg-list at each
call, rather than creating a new ffi_cif instance for each variable
argument set.

That said, I think the proposed 'nnamedargs' style is still fine, for it
should be more straightforward to implement :)

Chung-Lin

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Variadic functions and libffi
  2011-01-05 17:50 Variadic functions and libffi David Gilbert
  2011-01-05 18:37 ` Andrew Haley
  2011-01-05 19:28 ` Chung-Lin Tang
@ 2011-01-06 10:36 ` Andrew Haley
  2011-01-06 11:35   ` Marcus Shawcroft
  2 siblings, 1 reply; 8+ messages in thread
From: Andrew Haley @ 2011-01-06 10:36 UTC (permalink / raw)
  To: David Gilbert; +Cc: libffi-discuss, Marcus.Shawcroft, cltang

On 01/05/2011 05:47 PM, David Gilbert wrote:
> Hi,
>    As part of the linaro toolchain effort for ARM, I've been asked to
> look at Variadic function calls in libffi,
> specifically for the ARM 'hard float' (aka PCS_VFP or FFI_VFP, armhf)
> variant and wanted to see what
> people thought before I dived in to it.
>
>    The ARM hard float variant is a variant of the ABI in which floating
> point values are passed in floating point
> registers (as opposed to the standard ABI where FP values are still
> passed in integer registers).  What makes
> this ABI a little unusual is that for variadic functions it just falls
> back to the standard all-integer-register ABI, and
> thus, as an example, in the function:
>
>     double foo(double bar, char *str, ...)
>
> the return value and the 'bar' would be passed in integer registers
> even though they aren't actually variadic
> parameters.
>
> It doesn't seem like there is any way out of this except for an API
> change to libffi to state that a variadic function is being
> called - so as I see it the questions then are:
>
>     1) Does libffi really support variadic functions and/or is there a
> desire to?  There are big warnings in various places saying
>   it doesn't - but then the testcases call variadic functions, and at
> least Python and SWIG both show examples of using it (with FP values).
> On the other hand there is an ancient gcc bug
> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=26744 to fix variadic on
> PPC MacOS
> marked as 'wishlist' because libffi doesn't support variadic.
>
>     2) What's a good/minimal API change.
>
>     3) Which FFI users actually use variadics and are hitting problems.
>
> As for an API change, as far as ARM hard float is concerned we don't
> actually care which parameters are
> variadic, we just care that the function is declared variadic, so a
> minimal change would be to define a FFI_DEFAULT_VARIADIC_ABI
> that is the same as FFI_DEFAULT_ABI on everything except ARM hard
> float, in which case it's set to FFI_SYSV, and when calling
> ffi_prep_cif you would pass FFI_DEFAULT_VARIADIC_ABI rather than
> FFI_DEFAULT_ABI for variadic calls.
>
> That's simple for ARM but it seems unfair on any other architecture
> that needs to fix things up.
>
> I've had some discussion with Marcus Shawcroft (cc'd) and it looks
> like the right solution is to declare a
>
> 'ffi_prep_cif_variadic'
>
> that is just like ffi_prep_cif but also takes a 'nnamedargs' to say
> the number of fixed args (and hence which arg is the 1st variadic).

I don't think this is such a great design, because you'd be doing the
calculation about where to put the args at the time of the call.  IMO
it makes more sense to do as much precomputation as possible, by
calling ffi_prep_cif_variadic with the actual number of fixed args and
the actual number of varargs you intend to pass.  In almost all usages
of libffi you really will know the number of arguments to be passed
when preparing the CIF.  If you can precompute all this stuff you can
even use a JIT to generate code for the call.

Andrew.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* RE: Variadic functions and libffi
  2011-01-06 10:36 ` Andrew Haley
@ 2011-01-06 11:35   ` Marcus Shawcroft
  2011-01-06 11:53     ` Andrew Haley
  0 siblings, 1 reply; 8+ messages in thread
From: Marcus Shawcroft @ 2011-01-06 11:35 UTC (permalink / raw)
  To: 'Andrew Haley', David Gilbert; +Cc: libffi-discuss, cltang


>> that is just like ffi_prep_cif but also takes a 'nnamedargs' to say
>> the number of fixed args (and hence which arg is the 1st variadic).
>
> I don't think this is such a great design, because you'd be doing the
> calculation about where to put the args at the time of the call.  IMO
> it makes more sense to do as much precomputation as possible, by
> calling ffi_prep_cif_variadic with the actual number of fixed args and
> the actual number of varargs you intend to pass.  In almost all usages
> of libffi you really will know the number of arguments to be passed
> when preparing the CIF.  If you can precompute all this stuff you can
> even use a JIT to generate code for the call.

The prototype David and I discussed has the form:

ffi_status ffi_prep_cif_variadic(ffi_cif *cif, ffi_abi abi, unsigned int
nargs, unsigned int nnamedargs, ffi_type *rtype, ffi_type **atypes);

Which makes available the total number of arguments, the number of named
arguments and hence the number of anonymous arguments up front.

Marcus



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Variadic functions and libffi
  2011-01-06 11:35   ` Marcus Shawcroft
@ 2011-01-06 11:53     ` Andrew Haley
  2011-01-06 15:03       ` Anthony Green
  0 siblings, 1 reply; 8+ messages in thread
From: Andrew Haley @ 2011-01-06 11:53 UTC (permalink / raw)
  To: Marcus Shawcroft; +Cc: David Gilbert, libffi-discuss, cltang

On 01/06/2011 11:34 AM, Marcus Shawcroft wrote:
>
>>> that is just like ffi_prep_cif but also takes a 'nnamedargs' to say
>>> the number of fixed args (and hence which arg is the 1st variadic).
>>
>> I don't think this is such a great design, because you'd be doing the
>> calculation about where to put the args at the time of the call.  IMO
>> it makes more sense to do as much precomputation as possible, by
>> calling ffi_prep_cif_variadic with the actual number of fixed args and
>> the actual number of varargs you intend to pass.  In almost all usages
>> of libffi you really will know the number of arguments to be passed
>> when preparing the CIF.  If you can precompute all this stuff you can
>> even use a JIT to generate code for the call.
>
> The prototype David and I discussed has the form:
>
> ffi_status ffi_prep_cif_variadic(ffi_cif *cif, ffi_abi abi, unsigned int
> nargs, unsigned int nnamedargs, ffi_type *rtype, ffi_type **atypes);
>
> Which makes available the total number of arguments, the number of named
> arguments and hence the number of anonymous arguments up front.

Ah, OK.  That seems reasonable.

Paging Anthony Green: I never understood why libffi didn't deal with
varargs -- was it a conscious design decision, or just something you
never got around to?

Andrew.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Variadic functions and libffi
  2011-01-06 11:53     ` Andrew Haley
@ 2011-01-06 15:03       ` Anthony Green
  2011-01-06 15:09         ` David Gilbert
  0 siblings, 1 reply; 8+ messages in thread
From: Anthony Green @ 2011-01-06 15:03 UTC (permalink / raw)
  To: Andrew Haley; +Cc: Marcus Shawcroft, David Gilbert, libffi-discuss, cltang

Andrew Haley <aph@redhat.com> writes:

> Paging Anthony Green: I never understood why libffi didn't deal with
> varargs -- was it a conscious design decision, or just something you
> never got around to?

It was not a conscious design decision.  None of the major libffi users
have ever required support for variadic calls, or if they did, none of
the supported ABIs required any special support.  The hard-float ARM ABI
appears to be the first.  

Marcus and I discussed his ideas a few weeks ago and patches are
definitely welcome.

AG

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Variadic functions and libffi
  2011-01-06 15:03       ` Anthony Green
@ 2011-01-06 15:09         ` David Gilbert
  0 siblings, 0 replies; 8+ messages in thread
From: David Gilbert @ 2011-01-06 15:09 UTC (permalink / raw)
  To: Anthony Green; +Cc: Andrew Haley, Marcus Shawcroft, libffi-discuss, cltang

On 6 January 2011 15:03, Anthony Green <green@redhat.com> wrote:
> Andrew Haley <aph@redhat.com> writes:
>
>> Paging Anthony Green: I never understood why libffi didn't deal with
>> varargs -- was it a conscious design decision, or just something you
>> never got around to?
>
> It was not a conscious design decision.  None of the major libffi users
> have ever required support for variadic calls, or if they did, none of
> the supported ABIs required any special support.

There is a big difference between those two cases; if none of the ffi
users actually call variadic functions there isn't a strong case to make the
change.   If there are users out there but they work on the current
architectures
then it's worth changing. Hence I'd really like to hear from any users.

>  The hard-float ARM ABI
> appears to be the first.
>
> Marcus and I discussed his ideas a few weeks ago and patches are
> definitely welcome.

OK, I'll do it - and post a patch here when I'm done; it should be a few
weeks or so.

Dave

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2011-01-06 15:09 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-01-05 17:50 Variadic functions and libffi David Gilbert
2011-01-05 18:37 ` Andrew Haley
2011-01-05 19:28 ` Chung-Lin Tang
2011-01-06 10:36 ` Andrew Haley
2011-01-06 11:35   ` Marcus Shawcroft
2011-01-06 11:53     ` Andrew Haley
2011-01-06 15:03       ` Anthony Green
2011-01-06 15:09         ` David Gilbert

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).