Re: Returning values from objc_msgSend etc
Re: Returning values from objc_msgSend etc
- Subject: Re: Returning values from objc_msgSend etc
- From: Greg Parker <email@hidden>
- Date: Fri, 29 Feb 2008 11:46:09 -0800
On Feb 29, 2008, at 11:05 AM, Duncan McGregor wrote:
Are there any Objective-C wizards out there who could review a few
conceptual and practical issues I have returning values from
objc_msgSend and its friends?
I've just released Rococoa, a generic replacement for the Cocoa-Java
bridge, under LGPL. Some things do not work as expected on PPC. I know
I really need to understand how objc_msgSend works, but cannot find a
complete discussion anywhere.
The first thing to do is read and understand the Mac OS X ABI Function
Call Guide. Objective-C messages follow the C calling conventions.
http://developer.apple.com/documentation/DeveloperTools/Conceptual/LowLevelABI/Introduction.html
Then the rules work like this. Note that the answers may differ for
each architecture.
* If the return value is stored in one x87 floating-point register,
use objc_msgSend_fpret. This includes i386 float/double/long double
and x86_64 long double (but not float/double). On other architectures,
objc_msgSend_fpret is identical to objc_msgSend.
* If the return value is stored in two x87 floating-point registers,
use objc_msgSend_fp2ret. I think this is for i386/x86_64 _Complex long
double only, but might also apply to a struct composed of two long
double fields.
* If the return value is a struct, and the struct's address is passed
as the first parameter, use objc_msgSend_stret. Note that some small
structs on some architectures are returned in registers instead; don't
use objc_msgSend_stret for them.
* If the return value is a ppc/ppc64 vector, stop. Objective-C
messages don't support vector parameters.
* For everything else, use objc_msgSend.
When in doubt, write Objective-C code that returns the type you want,
compile it, and use whichever function the generated assembly code
chose. This is usually the way to go for structure returns, because
each architecture has its own arcane rules about which structs are
returned in registers and which are returned on the stack. ppc64
struct return in particular is incomprehensible. And the compiler is
always right; if the compiler and the documentation disagree about
function calls, the documentation is changed.
* If both objc_msgSend_stret and objc_msgSend hack the stack to return
different sized return values, why are there 2 functions?
For sufficiently-large structures on all architectures, the caller
passes the address of the storage for the return value as the first
parameter. This means the other parameters are shifted. That in turn
means objc_msgSend and objc_msgSend_stret need to look in different
places to find `self` and `_cmd`.
Also, on i386, the callee pops that struct-return parameter, unlike
the other parameters which are popped by the caller. So
objc_msgSend_stret needs to pop the extra value when a message is sent
to nil, and objc_msgSend doesn't.
* Should I call objc_msgSend_stret when returning longs on PPC?
No. On ppc, longs are 32-bit and returned in a single register. 64-bit
integers are returned in two registers. Both cases use objc_msgSend.
* Do I really need to call objc_msgSend_fpret for floating point on
Intel?
Yes. If a message is sent to nil, objc_msgSend_fpret pushes a zero on
the x87 floating-point stack for the caller to pop. objc_msgSend can't
do that, because the caller isn't expecting to pop anything.
--
Greg Parker email@hidden Runtime Wrangler
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden