Mailing Lists: Apple Mailing Lists

Image of Mac OS face in stamp
 
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: objc_msgSend problems on x86



Ack, at 2/11/06, Greg Parker said:

Rosyna wrote:
bool isEqual=objc_msgSend(string, NSSelectorFromString(CFSTR("isEqualToString:")), otherString);

On the PPC will work just fine 100% of the time. If I run the same code on the ICBMs it'll return true even when the strings weren't equal at all in some rare cases. It also shows an error in GCC

Even worse was trying something like:

if (objc_msgSend(string, NSSelectorFromString(CFSTR("isEqualToString:")), otherString))

which returns true the far majority of the time even when it the strings are not equal. However, if I change the code to read:

if ((signed char(*)(id, SEL, id)objc_msgSend)(string, NSSelectorFromString(CFSTR("isEqualToString:")), otherString))

it always returns the correct value. Is there a reason for this change between the PPC and the x86?

The problem is that this code is sloppy with its types, and in this case the PPC instruction set is more forgiving than i386.

I was guessing as much for the PPC but am very glad to get a concrete answer.

* For floating-point return values on i386, use objc_msgSend_fpret() instead of objc_msgSend() itself.

That's very good to know. I was wondering about this case as well. I'm assuming I'd have to do the same magic function typecast on objc_msgSend_fpret() that I have to do on objc_msgSend() if I want a float and not a double?


The PPC assembly (at -O3) looks like this:

    "+[Test returnFalse]":
        xor r3,r4,r3
        subfic r0,r3,0
        adde r3,r0,r3
        blr

The compiler optimizer is being clever here, using some arithmetic to do the comparison without any branches. Suffice to say that the return value is in register r3, and that a NO return sets all of register r3 to zero. In general, the instructions used to compute a one-byte BOOL value also set the rest of the register to zero when returning NO.


On i386, the assembly looks like this:

    "+[Test returnFalse]":
        pushl   %ebp
        movl    %esp, %ebp
        movl    12(%ebp), %eax
        cmpl    8(%ebp), %eax
        sete    %al
        popl    %ebp
        ret

Here, the return value is placed in register al, which is another name for the first byte of the four-byte register eax. Importantly, the other three bytes of eax are left as random garbage, which is different from the PPC case. This is usually ok because BOOL is only one byte, but in this case it causes trouble, as we'll see below.

That explains it then, many thanks.


--


Sincerely, Rosyna Keller Technical Support/Holy Knight/Always needs a hug

Unsanity: Unsane Tools for Insanely Great People

It's either this, or imagining Phil Schiller in a thong.
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/email@hidden

This email sent to email@hidden
References: 
 >Re: objc_msgSend problems on x86 (From: Greg Parker <email@hidden>)



Visit the Apple Store online or at retail locations.
1-800-MY-APPLE

Contact Apple | Terms of Use | Privacy Policy

Copyright © 2007 Apple Inc. All rights reserved.