Fix some corner cases where exceptions are thrown through +initialize.

main
theraven 14 years ago
parent 3259504d4c
commit 855f2601c9

@ -53,12 +53,22 @@ Class TestCls;
+ (void)initialize + (void)initialize
{ {
[self printf: "Format %s %d %f%c", "string", 42, 42.0, '\n']; [self printf: "Format %s %d %f%c", "string", 42, 42.0, '\n'];
@throw self;
} }
+ nothing { return 0; } + nothing { return 0; }
@end @end
int main(void) int main(void)
{ {
TestCls = objc_getClass("Test"); TestCls = objc_getClass("Test");
int exceptionThrown = 0;
@try {
objc_msgSend(TestCls, @selector(foo));
} @catch (id e)
{
assert((TestCls == e) && "Exceptions propagate out of +initialize");
exceptionThrown = 1;
}
assert(exceptionThrown);
assert((id)0x42 == objc_msgSend(TestCls, @selector(foo))); assert((id)0x42 == objc_msgSend(TestCls, @selector(foo)));
objc_msgSend(TestCls, @selector(nothing)); objc_msgSend(TestCls, @selector(nothing));
objc_msgSend(TestCls, @selector(missing)); objc_msgSend(TestCls, @selector(missing));

@ -621,6 +621,9 @@ static void remove_dtable(InitializingDtable* meta_buffer)
{ {
LOCK(&initialize_lock); LOCK(&initialize_lock);
InitializingDtable *buffer = meta_buffer->next; InitializingDtable *buffer = meta_buffer->next;
// Install the dtable:
meta_buffer->class->dtable = meta_buffer->dtable;
buffer->class->dtable = buffer->dtable;
// Remove the look-aside buffer entry. // Remove the look-aside buffer entry.
if (temporary_dtables == meta_buffer) if (temporary_dtables == meta_buffer)
{ {
@ -728,10 +731,4 @@ PRIVATE void objc_send_initialize(id object)
// insert it into a global list, even though it's a temporary variable, // insert it into a global list, even though it's a temporary variable,
// because we will clean it up after this function. // because we will clean it up after this function.
initializeSlot->method((id)class, initializeSel); initializeSlot->method((id)class, initializeSel);
// Install the real dtable for both the class and the metaclass. We can do
// this without the lock, because now both ways of accessing the dtable are
// safe. We only need the lock when we remove the cached version.
meta->dtable = dtable;
class->dtable = class_dtable;
} }

@ -72,7 +72,6 @@
push %rcx push %rcx
push %r8 push %r8
push %r9 push %r9
//push %r9 # Fudge to ensure stack alignment stays at 16 bytes, or SSE dies
sub $0x98, %rsp sub $0x98, %rsp
movups %xmm0, 0x80(%rsp) movups %xmm0, 0x80(%rsp)
@ -99,7 +98,7 @@
mov %rdx, %rsi # move _cmd to where the callee expects it to be mov %rdx, %rsi # move _cmd to where the callee expects it to be
.endif .endif
.cfi_def_cfa_offset 80 .cfi_adjust_cfa_offset 0xD8
call slowMsgLookup # Call the slow lookup function call slowMsgLookup # Call the slow lookup function
mov %rax, %r10 # Load the returned IMP mov %rax, %r10 # Load the returned IMP
@ -117,7 +116,6 @@
movups 0x10(%rsp), %xmm7 movups 0x10(%rsp), %xmm7
add $0x98, %rsp add $0x98, %rsp
//pop %r9 # Fudge to ensure stack alignment stays at 16 bytes, or SSE dies
pop %r9 pop %r9
pop %r8 pop %r8
pop %rcx pop %rcx

Loading…
Cancel
Save