This is the mail archive of the libffi-discuss@sourceware.org mailing list for the libffi project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: closure api return value types problem


On Mar 27, 2010, at 6:02 AM, Sergei Trofimovich wrote:

>> The "ffi_arg" type is meant to represent the largest integral type held in a register, more or less.  It is assumed that "resp" points to the appropriately-sized memory.
> Aha, thanks!
> 
> I'd like to clarify more questions for myself:
> 1. If closure return type is integral - we have always have to use 'ffi_arg' as return:
>   Say, closure returning char will be the following:
>   *(ffi_arg*)resp = 'z';
>   The question is what types are integral? All except float, double and struct?
>   How about uint64_t on 32bit platform? Does C platform ABI describe how it should
>   be passed from function?

I really don't know anything more than what I gleaned from reading the code.

> 
> 2. Why integral return types (but not argument types) are so special?
>   I could imagine platforms, which do not support 'byte store' operations at all
>   (or efficiently).
>   But then argument parameters could be handled the same way:
>      uchar arg1  = (uchar)*(ffi_arg*)arg[0];
>   instead of current
>      uchar arg1  = *(uchar*)arg[0];
>   Was it the reason to treat returns in such a strange way?
> 

Probably things were written according to the first platform supported, and then all others followed suit.  So you can imagine that the same storage was used for char, short, and int (i.e. the memory block required for stack storage of the type, which is likely where the callback return value was to be stored).  

It's generally less work to use the native integral operator size (ffi_arg) than to calculate the correct byte offset based on byte ordering, pass in the pointer, then potentially extract and manipulate the value.  If the return value is supposed to go on the stack, then you just pass in the stack address, and the dereferencing writes the return value directly to the stack.  If not, the return value is copied in toto into a register, without having to copy a smaller value into just part of the register depending on byte ordering.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]