diff --git a/Test/BlockImpTest.m b/Test/BlockImpTest.m index ce9931a..aa07499 100644 --- a/Test/BlockImpTest.m +++ b/Test/BlockImpTest.m @@ -24,8 +24,10 @@ __attribute__((objc_root_class)) int main(void) { + __block Class cls = objc_getClass("Foo"); __block int b = 0; void* blk = ^(id self, int a) { + assert(self == cls); b += a; return b; }; blk = Block_copy(blk); @@ -33,7 +35,6 @@ int main(void) char *type = block_copyIMPTypeEncoding_np(blk); assert(NULL != type); class_addMethod((objc_getMetaClass("Foo")), @selector(count:), imp, type); - Class cls = objc_getClass("Foo"); assert(2 == ((int(*)(id,SEL,int))imp)(cls, @selector(count:), 2)); free(type); assert(4 == [Foo count: 2]); @@ -45,6 +46,7 @@ int main(void) assert(imp_getBlock(imp) != (blk)); blk = ^(id self) { + assert(self == cls); struct big b = {1, 2, 3, 4, 5}; return b; }; diff --git a/Test/CMakeLists.txt b/Test/CMakeLists.txt index 9e292a7..09e5902 100644 --- a/Test/CMakeLists.txt +++ b/Test/CMakeLists.txt @@ -37,6 +37,7 @@ set(TESTS ResurrectInDealloc_arc.m RuntimeTest.m WeakBlock_arc.m + WeakRefLoad.m WeakReferences_arc.m WeakImportClass.m ivar_arc.m diff --git a/Test/WeakRefLoad.m b/Test/WeakRefLoad.m new file mode 100644 index 0000000..c851638 --- /dev/null +++ b/Test/WeakRefLoad.m @@ -0,0 +1,22 @@ +#include "Test.h" + +#define SIZE 5000 + +int main(int argc, const char * argv[]) +{ + id t = [Test new]; + id w1; + id w2; + objc_initWeak(&w1, t); + objc_initWeak(&w2, t); + [t release]; + assert(objc_loadWeakRetained(&w1) == nil); + assert(objc_loadWeakRetained(&w2) == nil); + assert(w1 == nil); + assert(w2 == nil); + assert(objc_loadWeakRetained(&w1) == nil); + assert(objc_loadWeakRetained(&w2) == nil); + assert(w1 == nil); + assert(w2 == nil); + return 0; +} diff --git a/arc.mm b/arc.mm index 4873fa8..8a504dc 100644 --- a/arc.mm +++ b/arc.mm @@ -897,9 +897,11 @@ extern "C" OBJC_PUBLIC id objc_loadWeakRetained(id* addr) // will acquire the lock before attempting to deallocate) if (obj == nil) { - // If we've destroyed this weak ref, then make sure that we also deallocate the object. - if (weakRefRelease(ref)) + // If the object is destroyed, drop this reference to the WeakRef + // struct. + if (ref != NULL) { + weakRefRelease(ref); *addr = nil; } return nil; diff --git a/block_trampolines.S b/block_trampolines.S index 70e321d..6107e7a 100644 --- a/block_trampolines.S +++ b/block_trampolines.S @@ -126,7 +126,7 @@ .thumb .macro trampoline arg0, arg1 sub r12, pc, #4095 - mov \arg0, \arg1 // Move self over _cmd + mov \arg1, \arg0 // Move self over _cmd ldr \arg0, [r12, #-5] // Load the block pointer over self ldr r12, [r12, #-1] // Jump to the block function bx r12 @@ -134,7 +134,7 @@ # else .macro trampoline arg0, arg1 sub r12, pc, #4096 - mov \arg0, \arg1 // Move self over _cmd + mov \arg1, \arg0 // Move self over _cmd ldr \arg0, [r12, #-8] // Load the block pointer over self ldr pc, [r12, #-4] // Jump to the block function .endm diff --git a/objc_msgSend.aarch64.S b/objc_msgSend.aarch64.S index a571bba..fd14d26 100644 --- a/objc_msgSend.aarch64.S +++ b/objc_msgSend.aarch64.S @@ -54,9 +54,9 @@ stp fp, lr, [sp, #192] add fp, sp, 192 stp \receiver, x8, [sp, #-16]! - .cfi_def_cfa fp, 0 - .cfi_offset fp, 0 - .cfi_offset lr, 8 + .cfi_def_cfa fp, 16 + .cfi_offset fp, -16 + .cfi_offset lr, -8 // We now have all argument registers, the link // register and the receiver spilled on the // stack, with sp containing @@ -76,10 +76,11 @@ ldp q4, q5, [sp, #144] ldp q6, q7, [sp, #176] ldp fp, lr, [sp, #208] - ldp \receiver, x8, [sp], #16 + ldp \receiver, x8, [sp], #(ARGUMENT_SPILL_SIZE + 16) br x9 6: - adr x10, SmallObjectClasses + adrp x10, :got:SmallObjectClasses + ldr x10, [x10, :got_lo12:SmallObjectClasses] ldr x9, [x10, x9, lsl #3] b 1b .cfi_endproc diff --git a/properties.m b/properties.m index c2216e9..7c1d9a8 100644 --- a/properties.m +++ b/properties.m @@ -302,7 +302,7 @@ objc_property_t* class_copyPropertyList(Class cls, unsigned int *outCount) unsigned int out = 0; for (struct objc_property_list *l=properties ; NULL!=l ; l=l->next) { - for (int i=0 ; icount ; i++) + for (int i=0 ; icount ; i++) { list[out++] = property_at_index(l, i); } diff --git a/protocol.c b/protocol.c index dd1061e..e0144e2 100644 --- a/protocol.c +++ b/protocol.c @@ -421,7 +421,7 @@ objc_property_t *protocol_copyPropertyList2(Protocol *p, unsigned int *outCount, unsigned int count = 0; for (struct objc_property_list *l=properties ; l!=NULL ; l=l->next) { - count += properties->count; + count += l->count; } if (0 == count) {