Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't this Block have copy and dispose pointers in its descriptor?

According to the Block_private.h file, whenever a block is declared in an Objective-c file, the following structures are created in the object file to represent it:

struct Block_descriptor {
    unsigned long int reserved;
    unsigned long int size;
    void (*copy)(void *dst, void *src);
    void (*dispose)(void *);
};

struct Block_layout {
    void *isa;
    int flags;
    int reserved; 
    void (*invoke)(void *, ...);
    struct Block_descriptor *descriptor;
    /* Imported variables. */
};

However, when I generate an assembly file, with clang -S ..., from

int(^squared)(int) = ^(int i) {
    return i*i;
};

I get the following snippet that represents the block:

    .type   .L.str210,@object       # @.str210
.L.str210:
    .asciz   "i12@?0i8"
    .size   .L.str210, 9

    .type   __block_descriptor_tmp,@object # @__block_descriptor_tmp
    .section    .rodata,"a",@progbits
    .align  16
__block_descriptor_tmp:
    .quad   0                       # 0x0
    .quad   32                      # 0x20
    .quad   .L.str210
    .quad   0
    .size   __block_descriptor_tmp, 32

    .type   __block_literal_global,@object # @__block_literal_global
    .align  8
__block_literal_global:
    .quad   _NSConcreteGlobalBlock
    .long   1342177280              # 0x50000000
    .long   0                       # 0x0
    .quad   __main_block_invoke
    .quad   __block_descriptor_tmp
    .size   __block_literal_global, 32

So, __block_literal_global and __block_descriptor_tmp are a Block_layout and a Block_descriptor, respectively. But, as you can see, the third field of __block_descriptor_tmp, which should be a void (*copy)(void *dst, void *src) according to Block_private.h, is a const char * that points to the block's type encoding.

My question is: what does a block descriptor structure look like, exactly? Is my Block_private.h file deprecated, so that Block_descriptor implementation is currently different from the one I presented? If my file is right, why is the third field of __block_descriptor_tmp a const char *, not a void (*copy)(void *dst, void *src)?

like image 269
LuisABOL Avatar asked Feb 04 '13 02:02

LuisABOL


1 Answers

The copy and dispose helpers are only included if the block has captures that need to be managed (Practically speaking: objects & __block vars)

If they are present then block->flags & BLOCK_HAS_COPY_DISPOSE

Everything you need to know is outlined here: http://clang.llvm.org/docs/Block-ABI-Apple.html

like image 94
Fjölnir Avatar answered Nov 15 '22 06:11

Fjölnir