Re: objc_msgSend problems on x86
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