/* * When Blocks or Block_byrefs hold objects then their copy routine helpers use this entry point * to do the assignment. */ void _Block_object_assign(void *destAddr, const void *object, const int flags) { //printf("_Block_object_assign(*%p, %p, %x)\n", destAddr, object, flags); if ((flags & BLOCK_BYREF_CALLER) == BLOCK_BYREF_CALLER) { if ((flags & BLOCK_FIELD_IS_WEAK) == BLOCK_FIELD_IS_WEAK) { _Block_assign_weak(object, destAddr); } else { // do *not* retain or *copy* __block variables whatever they are _Block_assign((void *)object, destAddr); } } else if ((flags & BLOCK_FIELD_IS_BYREF) == BLOCK_FIELD_IS_BYREF) { // copying a __block reference from the stack Block to the heap // flags will indicate if it holds a __weak reference and needs a special isa _Block_byref_assign_copy(destAddr, object, flags); } // (this test must be before next one) else if ((flags & BLOCK_FIELD_IS_BLOCK) == BLOCK_FIELD_IS_BLOCK) { // copying a Block declared variable from the stack Block to the heap _Block_assign(_Block_copy_internal(object, flags), destAddr); } // (this test must be after previous one) else if ((flags & BLOCK_FIELD_IS_OBJECT) == BLOCK_FIELD_IS_OBJECT) { //printf("retaining object at %p\n", object); _Block_retain_object(object); //printf("done retaining object at %p\n", object); _Block_assign((void *)object, destAddr); } }
// SPI, also internal. Called from NSAutoBlock only under GC void *_Block_copy_collectable(const void *aBlock) { return _Block_copy_internal(aBlock, 0); }
void *_Block_copy(const void *arg) { return _Block_copy_internal(arg, WANTS_ONE); }
// // When Blocks or Block_byrefs hold objects then their copy routine helpers use this entry point // to do the assignment. // void _Block_object_assign(void *destAddr, const void *object, const int flags) { switch (osx_assumes(flags & BLOCK_ALL_COPY_DISPOSE_FLAGS)) { case BLOCK_FIELD_IS_OBJECT: /******* id object = ...; [^{ object; } copy]; ********/ _Block_retain_object(object); _Block_assign((void *)object, destAddr); break; case BLOCK_FIELD_IS_BLOCK: /******* void (^object)(void) = ...; [^{ object; } copy]; ********/ _Block_assign(_Block_copy_internal(object, false), destAddr); break; case BLOCK_FIELD_IS_BYREF | BLOCK_FIELD_IS_WEAK: case BLOCK_FIELD_IS_BYREF: /******* // copy the onstack __block container to the heap __block ... x; __weak __block ... x; [^{ x; } copy]; ********/ _Block_byref_assign_copy(destAddr, object, flags); break; case BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_OBJECT: case BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_BLOCK: /******* // copy the actual field held in the __block container __block id object; __block void (^object)(void); [^{ object; } copy]; ********/ // under manual retain release __block object/block variables are dangling _Block_assign((void *)object, destAddr); break; case BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_OBJECT | BLOCK_FIELD_IS_WEAK: case BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_BLOCK | BLOCK_FIELD_IS_WEAK: /******* // copy the actual field held in the __block container __weak __block id object; __weak __block void (^object)(void); [^{ object; } copy]; ********/ _Block_assign_weak(object, destAddr); break; default: break; } }
void *_Block_copy(const void *arg) { return _Block_copy_internal(arg, true); }
// SPI, also internal. Called from NSAutoBlock only under GC BLOCK_EXPORT void *_Block_copy_collectable(const void *aBlock) { return _Block_copy_internal(aBlock, false); }