• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: objc_msgSend problems on x86
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: objc_msgSend problems on x86


  • Subject: Re: objc_msgSend problems on x86
  • From: Rosyna <email@hidden>
  • Date: Sat, 11 Feb 2006 16:57:20 -0700

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   ëp
        movl    %esp, ëp
        movl    12(ëp), êx
        cmpl    8(ëp), êx
        sete    %al
        popl    ëp
        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:
This email sent to email@hidden


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

  • Prev by Date: Re: NSString and char *
  • Next by Date: RE: NSString and char *
  • Previous by thread: Re: NSString and char *
  • Next by thread: Re: objc_msgSend problems on x86
  • Index(es):
    • Date
    • Thread