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
{
[self printf: "Format %s %d %f%c", "string", 42, 42.0, '\n'];
@throw self;
}
+ nothing { return 0; }
@end
int main(void)
{
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)));
objc_msgSend(TestCls, @selector(nothing));
objc_msgSend(TestCls, @selector(missing));

@ -621,6 +621,9 @@ static void remove_dtable(InitializingDtable* meta_buffer)
{
LOCK(&initialize_lock);
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.
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,
// because we will clean it up after this function.
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 %r8
push %r9
//push %r9 # Fudge to ensure stack alignment stays at 16 bytes, or SSE dies
sub $0x98, %rsp
movups %xmm0, 0x80(%rsp)
@ -99,7 +98,7 @@
mov %rdx, %rsi # move _cmd to where the callee expects it to be
.endif
.cfi_def_cfa_offset 80
.cfi_adjust_cfa_offset 0xD8
call slowMsgLookup # Call the slow lookup function
mov %rax, %r10 # Load the returned IMP
@ -117,7 +116,6 @@
movups 0x10(%rsp), %xmm7
add $0x98, %rsp
//pop %r9 # Fudge to ensure stack alignment stays at 16 bytes, or SSE dies
pop %r9
pop %r8
pop %rcx

Loading…
Cancel
Save