brintos

brintos / llvm-project-archived public Read only

0
0
Text · 33.0 KiB · c577e43 Raw
945 lines · plain
1==================================2Block Implementation Specification3==================================4 5.. contents::6   :local:7 8History9=======10 11* 2008/7/14 - created.12* 2008/8/21 - revised, C++.13* 2008/9/24 - add ``NULL`` ``isa`` field to ``__block`` storage.14* 2008/10/1 - revise block layout to use a ``static`` descriptor structure.15* 2008/10/6 - revise block layout to use an unsigned long int flags.16* 2008/10/28 - specify use of ``_Block_object_assign`` and17  ``_Block_object_dispose`` for all "Object" types in helper functions.18* 2008/10/30 - revise new layout to have invoke function in same place.19* 2008/10/30 - add ``__weak`` support.20* 2010/3/16 - rev for stret return, signature field.21* 2010/4/6 - improved wording.22* 2013/1/6 - improved wording and converted to rst.23 24This document describes the Apple ABI implementation specification of Blocks.25 26The first shipping version of this ABI is found in Mac OS X 10.6, and shall be27referred to as 10.6.ABI. As of 2010/3/16, the following describes the ABI28contract with the runtime and the compiler, and, as necessary, will be referred29to as ABI.2010.3.16.30 31Since the Apple ABI references symbols from other elements of the system, any32attempt to use this ABI on systems prior to SnowLeopard is undefined.33 34High Level35==========36 37The ABI of ``Blocks`` consists of their layout and the runtime functions required38by the compiler.  A ``Block`` of type ``R (^)(P...)`` consists of a structure of39the following form:40 41.. code-block:: c42 43    struct Block_literal_1 {44        void *isa; // initialized to &_NSConcreteStackBlock or &_NSConcreteGlobalBlock45        int flags;46        int reserved;47        R (*invoke)(struct Block_literal_1 *, P...);48        struct Block_descriptor_1 {49            unsigned long int reserved;     // NULL50            unsigned long int size;         // sizeof(struct Block_literal_1)51            // optional helper functions52            void (*copy_helper)(void *dst, void *src);     // IFF (1<<25)53            void (*dispose_helper)(void *src);             // IFF (1<<25)54            // required ABI.2010.3.1655            const char *signature;                         // IFF (1<<30)56        } *descriptor;57        // imported variables58    };59 60The following flags bits are in use thusly for a possible ABI.2010.3.16:61 62.. code-block:: c63 64    enum {65        // Set to true on blocks that have captures (and thus are not true66        // global blocks) but are known not to escape for various other67        // reasons. For backward compatibility with old runtimes, whenever68        // BLOCK_IS_NOESCAPE is set, BLOCK_IS_GLOBAL is set too. Copying a69        // non-escaping block returns the original block and releasing such a70        // block is a no-op, which is exactly how global blocks are handled.71        BLOCK_IS_NOESCAPE      =  (1 << 23),72 73        BLOCK_HAS_COPY_DISPOSE =  (1 << 25),74        BLOCK_HAS_CTOR =          (1 << 26), // helpers have C++ code75        BLOCK_IS_GLOBAL =         (1 << 28),76        BLOCK_HAS_STRET =         (1 << 29), // IFF BLOCK_HAS_SIGNATURE77        BLOCK_HAS_SIGNATURE =     (1 << 30),78    };79 80In 10.6.ABI the (1<<29) was usually set and was always ignored by the runtime -81it had been a transitional marker that did not get deleted after the82transition. This bit is now paired with (1<<30), and represented as the pair83(3<<29), for the following combinations of valid bit settings, and their84meanings:85 86.. code-block:: c87 88    switch (flags & (3<<29)) {89      case (0<<29):      10.6.ABI, no signature field available90      case (1<<29):      10.6.ABI, no signature field available91      case (2<<29): ABI.2010.3.16, regular calling convention, presence of signature field92      case (3<<29): ABI.2010.3.16, stret calling convention, presence of signature field,93    }94 95The signature field is not always populated.96 97The following discussions are presented as 10.6.ABI otherwise.98 99``Block`` literals may occur within functions where the structure is created in100stack local memory.  They may also appear as initialization expressions for101``Block`` variables of global or ``static`` local variables.102 103When a ``Block`` literal expression is evaluated the stack based structure is104initialized as follows:105 1061. A ``static`` descriptor structure is declared and initialized as follows:107 108  a. The ``invoke`` function pointer is set to a function that takes the109  ``Block`` structure as its first argument and the rest of the arguments (if110  any) to the ``Block`` and executes the ``Block`` compound statement.111 112  b. The ``size`` field is set to the size of the following ``Block`` literal113  structure.114 115  c. The ``copy_helper`` and ``dispose_helper`` function pointers are set to116  respective helper functions if they are required by the ``Block`` literal.117 1182. A stack (or global) ``Block`` literal data structure is created and119   initialized as follows:120 121   a. The ``isa`` field is set to the address of the external122   ``_NSConcreteStackBlock``, which is a block of uninitialized memory supplied123   in ``libSystem``, or ``_NSConcreteGlobalBlock`` if this is a static or file124   level ``Block`` literal.125 126   b. The ``flags`` field is set to zero unless there are variables imported127   into the ``Block`` that need helper functions for program level128   ``Block_copy()`` and ``Block_release()`` operations, in which case the129   (1<<25) flags bit is set.130 131As an example, the ``Block`` literal expression:132 133.. code-block:: c134 135    ^ { printf("hello world\n"); }136 137would cause the following to be created on a 32-bit system:138 139.. code-block:: c140 141    struct __block_literal_1 {142        void *isa;143        int flags;144        int reserved;145        void (*invoke)(struct __block_literal_1 *);146        struct __block_descriptor_1 *descriptor;147    };148 149    void __block_invoke_1(struct __block_literal_1 *_block) {150        printf("hello world\n");151    }152 153    static struct __block_descriptor_1 {154        unsigned long int reserved;155        unsigned long int Block_size;156    } __block_descriptor_1 = { 0, sizeof(struct __block_literal_1) };157 158and where the ``Block`` literal itself appears:159 160.. code-block:: c161 162    struct __block_literal_1 _block_literal = {163         &_NSConcreteStackBlock,164         (1<<29), <uninitialized>,165         __block_invoke_1,166         &__block_descriptor_1167    };168 169A ``Block`` imports other ``Block`` references, ``const`` copies of other170variables, and variables marked ``__block``.  In Objective-C, variables may171additionally be objects.172 173When a ``Block`` literal expression is used as the initial value of a global174or ``static`` local variable, it is initialized as follows:175 176.. code-block:: c177 178    struct __block_literal_1 __block_literal_1 = {179          &_NSConcreteGlobalBlock,180          (1<<28)|(1<<29), <uninitialized>,181          __block_invoke_1,182          &__block_descriptor_1183    };184 185that is, a different address is provided as the first value and a particular186(1<<28) bit is set in the ``flags`` field, and otherwise it is the same as for187stack based ``Block`` literals.  This is an optimization that can be used for188any ``Block`` literal that imports no ``const`` or ``__block`` storage189variables.190 191Imported Variables192==================193 194Variables of ``auto`` storage class are imported as ``const`` copies.  Variables195of ``__block`` storage class are imported as a pointer to an enclosing data196structure.  Global variables are simply referenced and not considered as197imported.198 199Imported ``const`` copy variables200---------------------------------201 202Automatic storage variables not marked with ``__block`` are imported as203``const`` copies.204 205The simplest example is that of importing a variable of type ``int``:206 207.. code-block:: c208 209    int x = 10;210    void (^vv)(void) = ^{ printf("x is %d\n", x); }211    x = 11;212    vv();213 214which would be compiled to:215 216.. code-block:: c217 218    struct __block_literal_2 {219        void *isa;220        int flags;221        int reserved;222        void (*invoke)(struct __block_literal_2 *);223        struct __block_descriptor_2 *descriptor;224        const int x;225    };226 227    void __block_invoke_2(struct __block_literal_2 *_block) {228        printf("x is %d\n", _block->x);229    }230 231    static struct __block_descriptor_2 {232        unsigned long int reserved;233        unsigned long int Block_size;234    } __block_descriptor_2 = { 0, sizeof(struct __block_literal_2) };235 236and:237 238.. code-block:: c239 240    struct __block_literal_2 __block_literal_2 = {241          &_NSConcreteStackBlock,242          (1<<29), <uninitialized>,243          __block_invoke_2,244          &__block_descriptor_2,245          x246     };247 248In summary, scalars, structures, unions, and function pointers are generally249imported as ``const`` copies with no need for helper functions.250 251Imported ``const`` copy of ``Block`` reference252----------------------------------------------253 254The first case where copy and dispose helper functions are required is for the255case of when a ``Block`` itself is imported.  In this case both a256``copy_helper`` function and a ``dispose_helper`` function are needed.  The257``copy_helper`` function is passed both the existing stack based pointer and the258pointer to the new heap version and should call back into the runtime to259actually do the copy operation on the imported fields within the ``Block``. The260runtime functions are all described in :ref:`RuntimeHelperFunctions`.261 262A quick example:263 264.. code-block:: c265 266    void (^existingBlock)(void) = ...;267    void (^vv)(void) = ^{ existingBlock(); }268    vv();269 270    struct __block_literal_3 {271       ...; // existing block272    };273 274    struct __block_literal_4 {275        void *isa;276        int flags;277        int reserved;278        void (*invoke)(struct __block_literal_4 *);279        struct __block_literal_3 *const existingBlock;280    };281 282    void __block_invoke_4(struct __block_literal_2 *_block) {283       __block->existingBlock->invoke(__block->existingBlock);284    }285 286    void __block_copy_4(struct __block_literal_4 *dst, struct __block_literal_4 *src) {287         //_Block_copy_assign(&dst->existingBlock, src->existingBlock, 0);288         _Block_object_assign(&dst->existingBlock, src->existingBlock, BLOCK_FIELD_IS_BLOCK);289    }290 291    void __block_dispose_4(struct __block_literal_4 *src) {292         // was _Block_destroy293         _Block_object_dispose(src->existingBlock, BLOCK_FIELD_IS_BLOCK);294    }295 296    static struct __block_descriptor_4 {297        unsigned long int reserved;298        unsigned long int Block_size;299        void (*copy_helper)(struct __block_literal_4 *dst, struct __block_literal_4 *src);300        void (*dispose_helper)(struct __block_literal_4 *);301    } __block_descriptor_4 = {302        0,303        sizeof(struct __block_literal_4),304        __block_copy_4,305        __block_dispose_4,306    };307 308and where said ``Block`` is used:309 310.. code-block:: c311 312    struct __block_literal_4 _block_literal = {313          &_NSConcreteStackBlock,314          (1<<25)|(1<<29), <uninitialized>315          __block_invoke_4,316          & __block_descriptor_4317          existingBlock,318    };319 320Importing ``__attribute__((NSObject))`` variables321^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^322 323GCC introduces ``__attribute__((NSObject))`` on structure pointers to mean "this324is an object".  This is useful because many low level data structures are325declared as opaque structure pointers, e.g. ``CFStringRef``, ``CFArrayRef``,326etc.  When used from C, however, these are still really objects and are the327second case where that requires copy and dispose helper functions to be328generated.  The copy helper functions generated by the compiler should use the329``_Block_object_assign`` runtime helper function and in the dispose helper the330``_Block_object_dispose`` runtime helper function should be called.331 332For example, ``Block`` foo in the following:333 334.. code-block:: c335 336    struct Opaque *__attribute__((NSObject)) objectPointer = ...;337    ...338    void (^foo)(void) = ^{  CFPrint(objectPointer); };339 340would have the following helper functions generated:341 342.. code-block:: c343 344    void __block_copy_foo(struct __block_literal_5 *dst, struct __block_literal_5 *src) {345         _Block_object_assign(&dst->objectPointer, src-> objectPointer, BLOCK_FIELD_IS_OBJECT);346    }347 348    void __block_dispose_foo(struct __block_literal_5 *src) {349         _Block_object_dispose(src->objectPointer, BLOCK_FIELD_IS_OBJECT);350    }351 352Imported ``__block`` marked variables353-------------------------------------354 355Layout of ``__block`` marked variables356^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^357 358The compiler must embed variables that are marked ``__block`` in a specialized359structure of the form:360 361.. code-block:: c362 363    struct _block_byref_foo {364        void *isa;365        struct Block_byref *forwarding;366        int flags;   //refcount;367        int size;368        typeof(marked_variable) marked_variable;369    };370 371Variables of certain types require helper functions for when ``Block_copy()``372and ``Block_release()`` are performed upon a referencing ``Block``.  At the "C"373level only variables that are of type ``Block`` or ones that have374``__attribute__((NSObject))`` marked require helper functions.  In Objective-C375objects require helper functions and in C++ stack based objects require helper376functions. Variables that require helper functions use the form:377 378.. code-block:: c379 380    struct _block_byref_foo {381        void *isa;382        struct _block_byref_foo *forwarding;383        int flags;   //refcount;384        int size;385        // helper functions called via Block_copy() and Block_release()386        void (*byref_keep)(void  *dst, void *src);387        void (*byref_dispose)(void *);388        typeof(marked_variable) marked_variable;389    };390 391The structure is initialized such that:392 393    a. The ``forwarding`` pointer is set to the beginning of its enclosing394    structure.395 396    b. The ``size`` field is initialized to the total size of the enclosing397    structure.398 399    c. The ``flags`` field is set to either 0 if no helper functions are needed400    or (1<<25) if they are.401 402    d. The helper functions are initialized (if present).403 404    e. The variable itself is set to its initial value.405 406    f. The ``isa`` field is set to ``NULL``.407 408Access to ``__block`` variables from within its lexical scope409^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^410 411In order to "move" the variable to the heap upon a ``copy_helper`` operation the412compiler must rewrite access to such a variable to be indirect through the413structures ``forwarding`` pointer.  For example:414 415.. code-block:: c416 417    int __block i = 10;418    i = 11;419 420would be rewritten to be:421 422.. code-block:: c423 424    struct _block_byref_i {425      void *isa;426      struct _block_byref_i *forwarding;427      int flags;   //refcount;428      int size;429      int captured_i;430    } i = { NULL, &i, 0, sizeof(struct _block_byref_i), 10 };431 432    i.forwarding->captured_i = 11;433 434In the case of a ``Block`` reference variable being marked ``__block`` the435helper code generated must use the ``_Block_object_assign`` and436``_Block_object_dispose`` routines supplied by the runtime to make the437copies. For example:438 439.. code-block:: c440 441    __block void (voidBlock)(void) = blockA;442    voidBlock = blockB;443 444would translate into:445 446.. code-block:: c447 448    struct _block_byref_voidBlock {449        void *isa;450        struct _block_byref_voidBlock *forwarding;451        int flags;   //refcount;452        int size;453        void (*byref_keep)(struct _block_byref_voidBlock *dst, struct _block_byref_voidBlock *src);454        void (*byref_dispose)(struct _block_byref_voidBlock *);455        void (^captured_voidBlock)(void);456    };457 458    void _block_byref_keep_helper(struct _block_byref_voidBlock *dst, struct _block_byref_voidBlock *src) {459        //_Block_copy_assign(&dst->captured_voidBlock, src->captured_voidBlock, 0);460        _Block_object_assign(&dst->captured_voidBlock, src->captured_voidBlock, BLOCK_FIELD_IS_BLOCK | BLOCK_BYREF_CALLER);461    }462 463    void _block_byref_dispose_helper(struct _block_byref_voidBlock *param) {464        //_Block_destroy(param->captured_voidBlock, 0);465        _Block_object_dispose(param->captured_voidBlock, BLOCK_FIELD_IS_BLOCK | BLOCK_BYREF_CALLER)}466 467and:468 469.. code-block:: c470 471    struct _block_byref_voidBlock voidBlock = {( .forwarding=&voidBlock, .flags=(1<<25), .size=sizeof(struct _block_byref_voidBlock *),472        .byref_keep=_block_byref_keep_helper, .byref_dispose=_block_byref_dispose_helper,473        .captured_voidBlock=blockA )};474 475    voidBlock.forwarding->captured_voidBlock = blockB;476 477Importing ``__block`` variables into ``Blocks``478^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^479 480A ``Block`` that uses a ``__block`` variable in its compound statement body must481import the variable and emit ``copy_helper`` and ``dispose_helper`` helper482functions that, in turn, call back into the runtime to actually copy or release483the ``byref`` data block using the functions ``_Block_object_assign`` and484``_Block_object_dispose``.485 486For example:487 488.. code-block:: c489 490    int __block i = 2;491    functioncall(^{ i = 10; });492 493would translate to:494 495.. code-block:: c496 497    struct _block_byref_i {498        void *isa;  // set to NULL499        struct _block_byref_voidBlock *forwarding;500        int flags;   //refcount;501        int size;502        void (*byref_keep)(struct _block_byref_i *dst, struct _block_byref_i *src);503        void (*byref_dispose)(struct _block_byref_i *);504        int captured_i;505    };506 507 508    struct __block_literal_5 {509        void *isa;510        int flags;511        int reserved;512        void (*invoke)(struct __block_literal_5 *);513        struct __block_descriptor_5 *descriptor;514        struct _block_byref_i *i_holder;515    };516 517    void __block_invoke_5(struct __block_literal_5 *_block) {518       _block->forwarding->captured_i = 10;519    }520 521    void __block_copy_5(struct __block_literal_5 *dst, struct __block_literal_5 *src) {522         //_Block_byref_assign_copy(&dst->captured_i, src->captured_i);523         _Block_object_assign(&dst->captured_i, src->captured_i, BLOCK_FIELD_IS_BYREF | BLOCK_BYREF_CALLER);524    }525 526    void __block_dispose_5(struct __block_literal_5 *src) {527         //_Block_byref_release(src->captured_i);528         _Block_object_dispose(src->captured_i, BLOCK_FIELD_IS_BYREF | BLOCK_BYREF_CALLER);529    }530 531    static struct __block_descriptor_5 {532        unsigned long int reserved;533        unsigned long int Block_size;534        void (*copy_helper)(struct __block_literal_5 *dst, struct __block_literal_5 *src);535        void (*dispose_helper)(struct __block_literal_5 *);536    } __block_descriptor_5 = { 0, sizeof(struct __block_literal_5) __block_copy_5, __block_dispose_5 };537 538and:539 540.. code-block:: c541 542    struct _block_byref_i i = {( .isa=NULL, .forwarding=&i, .flags=0, .size=sizeof(struct _block_byref_i), .captured_i=2 )};543    struct __block_literal_5 _block_literal = {544          &_NSConcreteStackBlock,545          (1<<25)|(1<<29), <uninitialized>,546          __block_invoke_5,547          &__block_descriptor_5,548          &i,549    };550 551Importing ``__attribute__((NSObject))`` ``__block`` variables552^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^553 554A ``__block`` variable that is also marked ``__attribute__((NSObject))`` should555have ``byref_keep`` and ``byref_dispose`` helper functions that use556``_Block_object_assign`` and ``_Block_object_dispose``.557 558``__block`` escapes559^^^^^^^^^^^^^^^^^^^560 561Because ``Blocks`` referencing ``__block`` variables may have ``Block_copy()``562performed upon them the underlying storage for the variables may move to the563heap.  In Objective-C Garbage Collection Only compilation environments the heap564used is the garbage collected one and no further action is required.  Otherwise565the compiler must issue a call to potentially release any heap storage for566``__block`` variables at all escapes or terminations of their scope.  The call567should be:568 569.. code-block:: c570 571    _Block_object_dispose(&_block_byref_foo, BLOCK_FIELD_IS_BYREF);572 573Nesting574^^^^^^^575 576``Blocks`` may contain ``Block`` literal expressions.  Any variables used within577inner blocks are imported into all enclosing ``Block`` scopes even if the578variables are not used. This includes ``const`` imports as well as ``__block``579variables.580 581Objective C Extensions to ``Blocks``582====================================583 584Importing Objects585-----------------586 587Objects should be treated as ``__attribute__((NSObject))`` variables; all588``copy_helper``, ``dispose_helper``, ``byref_keep``, and ``byref_dispose``589helper functions should use ``_Block_object_assign`` and590``_Block_object_dispose``.  There should be no code generated that uses591``*-retain`` or ``*-release`` methods.592 593``Blocks`` as Objects594---------------------595 596The compiler will treat ``Blocks`` as objects when synthesizing property setters597and getters, will characterize them as objects when generating garbage598collection strong and weak layout information in the same manner as objects, and599will issue strong and weak write-barrier assignments in the same manner as600objects.601 602``__weak __block`` Support603--------------------------604 605Objective-C (and Objective-C++) support the ``__weak`` attribute on ``__block``606variables.  Under normal circumstances the compiler uses the Objective-C runtime607helper support functions ``objc_assign_weak`` and ``objc_read_weak``.  Both608should continue to be used for all reads and writes of ``__weak __block``609variables:610 611.. code-block:: c612 613    objc_read_weak(&block->byref_i->forwarding->i)614 615The ``__weak`` variable is stored in a ``_block_byref_foo`` structure and the616``Block`` has copy and dispose helpers for this structure that call:617 618.. code-block:: c619 620    _Block_object_assign(&dest->_block_byref_i, src-> _block_byref_i, BLOCK_FIELD_IS_WEAK | BLOCK_FIELD_IS_BYREF);621 622and:623 624.. code-block:: c625 626    _Block_object_dispose(src->_block_byref_i, BLOCK_FIELD_IS_WEAK | BLOCK_FIELD_IS_BYREF);627 628In turn, the ``block_byref`` copy support helpers distinguish between whether629the ``__block`` variable is a ``Block`` or not and should either call:630 631.. code-block:: c632 633    _Block_object_assign(&dest->_block_byref_i, src->_block_byref_i, BLOCK_FIELD_IS_WEAK | BLOCK_FIELD_IS_OBJECT | BLOCK_BYREF_CALLER);634 635for something declared as an object or:636 637.. code-block:: c638 639    _Block_object_assign(&dest->_block_byref_i, src->_block_byref_i, BLOCK_FIELD_IS_WEAK | BLOCK_FIELD_IS_BLOCK | BLOCK_BYREF_CALLER);640 641for something declared as a ``Block``.642 643A full example follows:644 645.. code-block:: c646 647    __block __weak id obj = <initialization expression>;648    functioncall(^{ [obj somemessage]; });649 650would translate to:651 652.. code-block:: c653 654    struct _block_byref_obj {655        void *isa;  // uninitialized656        struct _block_byref_obj *forwarding;657        int flags;   //refcount;658        int size;659        void (*byref_keep)(struct _block_byref_i *dst, struct _block_byref_i *src);660        void (*byref_dispose)(struct _block_byref_i *);661        id captured_obj;662    };663 664    void _block_byref_obj_keep(struct _block_byref_voidBlock *dst, struct _block_byref_voidBlock *src) {665        //_Block_copy_assign(&dst->captured_obj, src->captured_obj, 0);666        _Block_object_assign(&dst->captured_obj, src->captured_obj, BLOCK_FIELD_IS_OBJECT | BLOCK_FIELD_IS_WEAK | BLOCK_BYREF_CALLER);667    }668 669    void _block_byref_obj_dispose(struct _block_byref_voidBlock *param) {670        //_Block_destroy(param->captured_obj, 0);671        _Block_object_dispose(param->captured_obj, BLOCK_FIELD_IS_OBJECT | BLOCK_FIELD_IS_WEAK | BLOCK_BYREF_CALLER);672    };673 674for the block ``byref`` part and:675 676.. code-block:: c677 678    struct __block_literal_5 {679        void *isa;680        int flags;681        int reserved;682        void (*invoke)(struct __block_literal_5 *);683        struct __block_descriptor_5 *descriptor;684        struct _block_byref_obj *byref_obj;685    };686 687    void __block_invoke_5(struct __block_literal_5 *_block) {688       [objc_read_weak(&_block->byref_obj->forwarding->captured_obj) somemessage];689    }690 691    void __block_copy_5(struct __block_literal_5 *dst, struct __block_literal_5 *src) {692         //_Block_byref_assign_copy(&dst->byref_obj, src->byref_obj);693         _Block_object_assign(&dst->byref_obj, src->byref_obj, BLOCK_FIELD_IS_BYREF | BLOCK_FIELD_IS_WEAK);694    }695 696    void __block_dispose_5(struct __block_literal_5 *src) {697         //_Block_byref_release(src->byref_obj);698         _Block_object_dispose(src->byref_obj, BLOCK_FIELD_IS_BYREF | BLOCK_FIELD_IS_WEAK);699    }700 701    static struct __block_descriptor_5 {702        unsigned long int reserved;703        unsigned long int Block_size;704        void (*copy_helper)(struct __block_literal_5 *dst, struct __block_literal_5 *src);705        void (*dispose_helper)(struct __block_literal_5 *);706    } __block_descriptor_5 = { 0, sizeof(struct __block_literal_5), __block_copy_5, __block_dispose_5 };707 708and within the compound statement:709 710.. code-block:: c711 712    truct _block_byref_obj obj = {( .forwarding=&obj, .flags=(1<<25), .size=sizeof(struct _block_byref_obj),713                     .byref_keep=_block_byref_obj_keep, .byref_dispose=_block_byref_obj_dispose,714                     .captured_obj = <initialization expression> )};715 716    truct __block_literal_5 _block_literal = {717         &_NSConcreteStackBlock,718         (1<<25)|(1<<29), <uninitialized>,719         __block_invoke_5,720         &__block_descriptor_5,721         &obj,        // a reference to the on-stack structure containing "captured_obj"722    };723 724 725    functioncall(_block_literal->invoke(&_block_literal));726 727C++ Support728===========729 730Within a block stack based C++ objects are copied into ``const`` copies using731the copy constructor.  It is an error if a stack based C++ object is used within732a block if it does not have a copy constructor.  In addition both copy and733destroy helper routines must be synthesized for the block to support the734``Block_copy()`` operation, and the flags work marked with the (1<<26) bit in735addition to the (1<<25) bit.  The copy helper should call the constructor using736appropriate offsets of the variable within the supplied stack based block source737and heap based destination for all ``const`` constructed copies, and similarly738should call the destructor in the destroy routine.739 740As an example, suppose a C++ class ``FOO`` existed with a copy constructor.741Within a code block a stack version of a ``FOO`` object is declared and used742within a ``Block`` literal expression:743 744.. code-block:: c++745 746    {747        FOO foo;748        void (^block)(void) = ^{ printf("%d\n", foo.value()); };749    }750 751The compiler would synthesize:752 753.. code-block:: c++754 755    struct __block_literal_10 {756        void *isa;757        int flags;758        int reserved;759        void (*invoke)(struct __block_literal_10 *);760        struct __block_descriptor_10 *descriptor;761        const FOO foo;762    };763 764    void __block_invoke_10(struct __block_literal_10 *_block) {765       printf("%d\n", _block->foo.value());766    }767 768    void __block_copy_10(struct __block_literal_10 *dst, struct __block_literal_10 *src) {769         FOO_ctor(&dst->foo, &src->foo);770    }771 772    void __block_dispose_10(struct __block_literal_10 *src) {773         FOO_dtor(&src->foo);774    }775 776    static struct __block_descriptor_10 {777        unsigned long int reserved;778        unsigned long int Block_size;779        void (*copy_helper)(struct __block_literal_10 *dst, struct __block_literal_10 *src);780        void (*dispose_helper)(struct __block_literal_10 *);781    } __block_descriptor_10 = { 0, sizeof(struct __block_literal_10), __block_copy_10, __block_dispose_10 };782 783and the code would be:784 785.. code-block:: c++786 787    {788      FOO foo;789      comp_ctor(&foo); // default constructor790      struct __block_literal_10 _block_literal = {791        &_NSConcreteStackBlock,792        (1<<25)|(1<<26)|(1<<29), <uninitialized>,793        __block_invoke_10,794        &__block_descriptor_10,795       };796       comp_ctor(&_block_literal->foo, &foo);  // const copy into stack version797       struct __block_literal_10 &block = &_block_literal;  // assign literal to block variable798       block->invoke(block);    // invoke block799       comp_dtor(&_block_literal->foo); // destroy stack version of const block copy800       comp_dtor(&foo); // destroy original version801    }802 803 804C++ objects stored in ``__block`` storage start out on the stack in a805``block_byref`` data structure as do other variables.  Such objects (if not806``const`` objects) must support a regular copy constructor.  The ``block_byref``807data structure will have copy and destroy helper routines synthesized by the808compiler.  The copy helper will have code created to perform the copy809constructor based on the initial stack ``block_byref`` data structure, and will810also set the (1<<26) bit in addition to the (1<<25) bit.  The destroy helper811will have code to do the destructor on the object stored within the supplied812``block_byref`` heap data structure.  For example,813 814.. code-block:: c++815 816    __block FOO blockStorageFoo;817 818requires the normal constructor for the embedded ``blockStorageFoo`` object:819 820.. code-block:: c++821 822    FOO_ctor(& _block_byref_blockStorageFoo->blockStorageFoo);823 824and at scope termination the destructor:825 826.. code-block:: c++827 828    FOO_dtor(& _block_byref_blockStorageFoo->blockStorageFoo);829 830Note that the forwarding indirection is *NOT* used.831 832The compiler would need to generate (if used from a block literal) the following833copy/dispose helpers:834 835.. code-block:: c++836 837    void _block_byref_obj_keep(struct _block_byref_blockStorageFoo *dst, struct _block_byref_blockStorageFoo *src) {838         FOO_ctor(&dst->blockStorageFoo, &src->blockStorageFoo);839    }840 841    void _block_byref_obj_dispose(struct _block_byref_blockStorageFoo *src) {842         FOO_dtor(&src->blockStorageFoo);843    }844 845for the appropriately named constructor and destructor for the class/struct846``FOO``.847 848To support member variable and function access the compiler will synthesize a849``const`` pointer to a block version of the ``this`` pointer.850 851.. _RuntimeHelperFunctions:852 853Runtime Helper Functions854========================855 856The runtime helper functions are described in857``/usr/local/include/Block_private.h``.  To summarize their use, a ``Block``858requires copy/dispose helpers if it imports any block variables, ``__block``859storage variables, ``__attribute__((NSObject))`` variables, or C++ ``const``860copied objects with constructor/destructors.  The (1<<26) bit is set and861functions are generated.862 863The block copy helper function should, for each of the variables of the type864mentioned above, call:865 866.. code-block:: c867 868     _Block_object_assign(&dst->target, src->target, BLOCK_FIELD_<apropos>);869 870in the copy helper and:871 872.. code-block:: c873 874    _Block_object_dispose(->target, BLOCK_FIELD_<apropos>);875 876in the dispose helper where ``<apropos>`` is:877 878.. code-block:: c879 880    enum {881        BLOCK_FIELD_IS_OBJECT   =  3,  // id, NSObject, __attribute__((NSObject)), block, ...882        BLOCK_FIELD_IS_BLOCK    =  7,  // a block variable883        BLOCK_FIELD_IS_BYREF    =  8,  // the on stack structure holding the __block variable884 885        BLOCK_FIELD_IS_WEAK     = 16,  // declared __weak886 887        BLOCK_BYREF_CALLER      = 128, // called from byref copy/dispose helpers888    };889 890and of course the constructors/destructors for ``const`` copied C++ objects.891 892The ``block_byref`` data structure similarly requires copy/dispose helpers for893block variables, ``__attribute__((NSObject))`` variables, or C++ ``const``894copied objects with constructor/destructors, and again the (1<<26) bit is set895and functions are generated in the same manner.896 897Under ObjC we allow ``__weak`` as an attribute on ``__block`` variables, and898this causes the addition of ``BLOCK_FIELD_IS_WEAK`` orred onto the899``BLOCK_FIELD_IS_BYREF`` flag when copying the ``block_byref`` structure in the900``Block`` copy helper, and onto the ``BLOCK_FIELD_<apropos>`` field within the901``block_byref`` copy/dispose helper calls.902 903The prototypes, and summary, of the helper functions are:904 905.. code-block:: c906 907    /* Certain field types require runtime assistance when being copied to the908       heap.  The following function is used to copy fields of types: blocks,909       pointers to byref structures, and objects (including910       __attribute__((NSObject)) pointers.  BLOCK_FIELD_IS_WEAK is orthogonal to911       the other choices which are mutually exclusive.  Only in a Block copy912       helper will one see BLOCK_FIELD_IS_BYREF.913    */914    void _Block_object_assign(void *destAddr, const void *object, const int flags);915 916    /* Similarly a compiler generated dispose helper needs to call back for each917       field of the byref data structure.  (Currently the implementation only918       packs one field into the byref structure but in principle there could be919       more).  The same flags used in the copy helper should be used for each920       call generated to this function:921    */922    void _Block_object_dispose(const void *object, const int flags);923 924Copyright925=========926 927Copyright 2008-2010 Apple, Inc.928Permission is hereby granted, free of charge, to any person obtaining a copy929of this software and associated documentation files (the "Software"), to deal930in the Software without restriction, including without limitation the rights931to use, copy, modify, merge, publish, distribute, sublicense, and/or sell932copies of the Software, and to permit persons to whom the Software is933furnished to do so, subject to the following conditions:934 935The above copyright notice and this permission notice shall be included in936all copies or substantial portions of the Software.937 938THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR939IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,940FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE941AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER942LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,943OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN944THE SOFTWARE.945