Forwarding is broken for Objective-C on x86_64, but it works on i386.
The self pointer is wrong after a message is forwarded on x86_64.
Here's the output, and the sample code:
output on 32-bit:
forwarding for selector display from 134536384 to 134536136
worked, self == receiver
foo is 1234567890, and should be 1234567890
output on 64-bit:
forwarding for selector display from 6330720 to 6330224
broken, self != receiver
foo is 6330224, and should be 1234567890
sample code:
// Objective-C x86_64 bug: self is wrong on forward;
// broken on gcc-4.1.2, 4.3.0, and 4.3.1
#include <stdio.h>
#include <stdlib.h>
#include <objc/Object.h>
#include <objc/objc-api.h>
id forwarder, receiver;
@interface Forwarder:Object
{
id receiver;
}
-initWithReceiver:theReceiver;
@end
@interface Receiver:Object
{
int foo;
}
-display;
-initWithFoo:(int)theFoo;
@end
@implementation Receiver
-initWithFoo:(int)theFoo
{
foo = theFoo;
return self;
}
-display
{
if (self == receiver) {
printf("worked, self == receiver\n");
} else {
printf("broken, self != receiver\n");
}
printf("foo is %d, and should be %d\n", foo, 1234567890);
return self;
}
@end
@implementation Forwarder
-initWithReceiver:theReceiver
{
[super init];
receiver = theReceiver;
return self;
}
-(retval_t) forward:(SEL)theSel:(arglist_t)theArgFrame
{
if (receiver) {
printf("forwarding for selector %s from %ld to %ld\n",
sel_get_name(theSel), self, receiver);
//return objc_msg_sendv(itsNextLink, theSel, theArgFrame);
return [receiver performv:theSel:theArgFrame];
} else {
return [self doesNotRecognize:theSel];
}
}
@end
int main()
{
receiver = [[Receiver alloc] initWithFoo:1234567890];
forwarder = [[Forwarder alloc] initWithReceiver:receiver];
[forwarder display];
exit(EXIT_SUCCESS);
return 0;
}