Problem implementing faults in Objective-C
Frederic Stark
fstark@almonde.com
Tue Jun 21 17:20:00 GMT 2005
Timothy J. Wood wrote:
[crunch]
>> The code works correctly under Mac OS X.
I just checked under linux/gcc 3.4 and the code works fine there. Maybe
this is a gcc 3.2 specific problem. I'll check gcc 3.4 windows one of
those days.
> The Apple runtime doesn't have this design choice, so it can't really
> have this problem.
You are right. I just disassembled a small variation on the thing, and
gcc 3.2 generates:
0x401406 <x>: push %ebp
0x401407 <x+1>: mov %esp,%ebp
0x401409 <x+3>: push %edi
0x40140a <x+4>: push %esi
0x40140b <x+5>: push %ebx
0x40140c <x+6>: sub $0xc,%esp
0x40140f <x+9>: sub $0x4,%esp
0x401412 <x+12>: sub $0x4,%esp
0x401415 <x+15>: push $0x4041f0
0x40141a <x+20>: mov 0x8(%ebp),%esi
0x40141d <x+23>: push %esi
0x40141e <x+24>: call 0x4017b0 <objc_msg_lookup>
0x401423 <x+29>: add $0xc,%esp
0x401426 <x+32>: mov %eax,%edi
0x401428 <x+34>: sub $0x4,%esp
0x40142b <x+37>: push $0x4041e8
0x401430 <x+42>: mov 0x8(%ebp),%ebx
0x401433 <x+45>: push %ebx
0x401434 <x+46>: call 0x4017b0 <objc_msg_lookup>
0x401439 <x+51>: add $0x8,%esp
0x40143c <x+54>: push $0x4041e8
0x401441 <x+59>: push %ebx
0x401442 <x+60>: call *%eax
0x401444 <x+62>: add $0xc,%esp
0x401447 <x+65>: push %eax
0x401448 <x+66>: push $0x4041f0
0x40144d <x+71>: push %esi
0x40144e <x+72>: call *%edi
0x401450 <x+74>: add $0x10,%esp
0x401453 <x+77>: lea 0xfffffff4(%ebp),%esp
0x401456 <x+80>: pop %ebx
0x401457 <x+81>: pop %esi
0x401458 <x+82>: pop %edi
0x401459 <x+83>: pop %ebp
0x40145a <x+84>: ret
It looks like the two objc_msg_lookup are made before the actual call
(0x401442 and 0x40144e)
> I don't think so; seems like a bug in the GNU ObjC runtime support in
> the compiler. I suppose the runtime maintainers might choose to define
> this as a bug in your code, but isa-swizzling is a fairly common and
> _extremely_ useful pattern in ObjC (see CoreData, NSZombie, etc.) so
> that'd not be my stance, obviously :)
As in my code the real classes are all subclass of a specific one, I
worked around the problem by implementing:
- (void)forwardInvocation:(NSInvocation *)anInvocation
{
if (![self respondsToSelector:[anInvocation selector]])
[super forwardInvocation:anInvocation];
[anInvocation invoke];
}
in the 'B' class.
Thanks for the help (and it have been a loooong time since we last
exchanged emails on the omni dev list...)
--fred
More information about the Gcc
mailing list