Skip navigation.
 
mlRe: Returning values from objc_msgSend etc
FROM : Greg Parker
DATE : Fri Feb 29 20:46:09 2008

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_removed>    Runtime Wrangler

Related mailsAuthorDate
mlReturning values from objc_msgSend etc Duncan McGregor Feb 29, 20:05
mlRe: Returning values from objc_msgSend etc Greg Parker Feb 29, 20:46
mlRe: Returning values from objc_msgSend etc Sherm Pendley Mar 1, 10:22
mlRe: Returning values from objc_msgSend etc Greg Parker Mar 1, 14:00
mlRe: Returning values from objc_msgSend etc Bill Bumgarner Mar 1, 18:30
mlRe: Returning values from objc_msgSend etc Sherm Pendley Mar 2, 00:22
mlRe: Returning values from objc_msgSend etc Duncan McGregor Mar 3, 11:52
mlRe: Returning values from objc_msgSend etc Ronald Oussoren Mar 3, 12:10
mlRe: Returning values from objc_msgSend etc Sherm Pendley Mar 3, 12:54
mlRe: Returning values from objc_msgSend etc Sherm Pendley Mar 31, 17:19
mlRe: Returning values from objc_msgSend etc Sherm Pendley Mar 31, 17:34
mlRe: Returning values from objc_msgSend etc Jean-Daniel Dupas Mar 31, 17:54
mlRe: Returning values from objc_msgSend etc Greg Parker Mar 31, 19:03
mlRe: Returning values from objc_msgSend etc Sherm Pendley Mar 31, 23:19