1*67e74705SXin Li================================== 2*67e74705SXin LiBlock Implementation Specification 3*67e74705SXin Li================================== 4*67e74705SXin Li 5*67e74705SXin Li.. contents:: 6*67e74705SXin Li :local: 7*67e74705SXin Li 8*67e74705SXin LiHistory 9*67e74705SXin Li======= 10*67e74705SXin Li 11*67e74705SXin Li* 2008/7/14 - created. 12*67e74705SXin Li* 2008/8/21 - revised, C++. 13*67e74705SXin Li* 2008/9/24 - add ``NULL`` ``isa`` field to ``__block`` storage. 14*67e74705SXin Li* 2008/10/1 - revise block layout to use a ``static`` descriptor structure. 15*67e74705SXin Li* 2008/10/6 - revise block layout to use an unsigned long int flags. 16*67e74705SXin Li* 2008/10/28 - specify use of ``_Block_object_assign`` and 17*67e74705SXin Li ``_Block_object_dispose`` for all "Object" types in helper functions. 18*67e74705SXin Li* 2008/10/30 - revise new layout to have invoke function in same place. 19*67e74705SXin Li* 2008/10/30 - add ``__weak`` support. 20*67e74705SXin Li* 2010/3/16 - rev for stret return, signature field. 21*67e74705SXin Li* 2010/4/6 - improved wording. 22*67e74705SXin Li* 2013/1/6 - improved wording and converted to rst. 23*67e74705SXin Li 24*67e74705SXin LiThis document describes the Apple ABI implementation specification of Blocks. 25*67e74705SXin Li 26*67e74705SXin LiThe first shipping version of this ABI is found in Mac OS X 10.6, and shall be 27*67e74705SXin Lireferred to as 10.6.ABI. As of 2010/3/16, the following describes the ABI 28*67e74705SXin Licontract with the runtime and the compiler, and, as necessary, will be referred 29*67e74705SXin Lito as ABI.2010.3.16. 30*67e74705SXin Li 31*67e74705SXin LiSince the Apple ABI references symbols from other elements of the system, any 32*67e74705SXin Liattempt to use this ABI on systems prior to SnowLeopard is undefined. 33*67e74705SXin Li 34*67e74705SXin LiHigh Level 35*67e74705SXin Li========== 36*67e74705SXin Li 37*67e74705SXin LiThe ABI of ``Blocks`` consist of their layout and the runtime functions required 38*67e74705SXin Liby the compiler. A ``Block`` consists of a structure of the following form: 39*67e74705SXin Li 40*67e74705SXin Li.. code-block:: c 41*67e74705SXin Li 42*67e74705SXin Li struct Block_literal_1 { 43*67e74705SXin Li void *isa; // initialized to &_NSConcreteStackBlock or &_NSConcreteGlobalBlock 44*67e74705SXin Li int flags; 45*67e74705SXin Li int reserved; 46*67e74705SXin Li void (*invoke)(void *, ...); 47*67e74705SXin Li struct Block_descriptor_1 { 48*67e74705SXin Li unsigned long int reserved; // NULL 49*67e74705SXin Li unsigned long int size; // sizeof(struct Block_literal_1) 50*67e74705SXin Li // optional helper functions 51*67e74705SXin Li void (*copy_helper)(void *dst, void *src); // IFF (1<<25) 52*67e74705SXin Li void (*dispose_helper)(void *src); // IFF (1<<25) 53*67e74705SXin Li // required ABI.2010.3.16 54*67e74705SXin Li const char *signature; // IFF (1<<30) 55*67e74705SXin Li } *descriptor; 56*67e74705SXin Li // imported variables 57*67e74705SXin Li }; 58*67e74705SXin Li 59*67e74705SXin LiThe following flags bits are in use thusly for a possible ABI.2010.3.16: 60*67e74705SXin Li 61*67e74705SXin Li.. code-block:: c 62*67e74705SXin Li 63*67e74705SXin Li enum { 64*67e74705SXin Li BLOCK_HAS_COPY_DISPOSE = (1 << 25), 65*67e74705SXin Li BLOCK_HAS_CTOR = (1 << 26), // helpers have C++ code 66*67e74705SXin Li BLOCK_IS_GLOBAL = (1 << 28), 67*67e74705SXin Li BLOCK_HAS_STRET = (1 << 29), // IFF BLOCK_HAS_SIGNATURE 68*67e74705SXin Li BLOCK_HAS_SIGNATURE = (1 << 30), 69*67e74705SXin Li }; 70*67e74705SXin Li 71*67e74705SXin LiIn 10.6.ABI the (1<<29) was usually set and was always ignored by the runtime - 72*67e74705SXin Liit had been a transitional marker that did not get deleted after the 73*67e74705SXin Litransition. This bit is now paired with (1<<30), and represented as the pair 74*67e74705SXin Li(3<<30), for the following combinations of valid bit settings, and their 75*67e74705SXin Limeanings: 76*67e74705SXin Li 77*67e74705SXin Li.. code-block:: c 78*67e74705SXin Li 79*67e74705SXin Li switch (flags & (3<<29)) { 80*67e74705SXin Li case (0<<29): 10.6.ABI, no signature field available 81*67e74705SXin Li case (1<<29): 10.6.ABI, no signature field available 82*67e74705SXin Li case (2<<29): ABI.2010.3.16, regular calling convention, presence of signature field 83*67e74705SXin Li case (3<<29): ABI.2010.3.16, stret calling convention, presence of signature field, 84*67e74705SXin Li } 85*67e74705SXin Li 86*67e74705SXin LiThe signature field is not always populated. 87*67e74705SXin Li 88*67e74705SXin LiThe following discussions are presented as 10.6.ABI otherwise. 89*67e74705SXin Li 90*67e74705SXin Li``Block`` literals may occur within functions where the structure is created in 91*67e74705SXin Listack local memory. They may also appear as initialization expressions for 92*67e74705SXin Li``Block`` variables of global or ``static`` local variables. 93*67e74705SXin Li 94*67e74705SXin LiWhen a ``Block`` literal expression is evaluated the stack based structure is 95*67e74705SXin Liinitialized as follows: 96*67e74705SXin Li 97*67e74705SXin Li1. A ``static`` descriptor structure is declared and initialized as follows: 98*67e74705SXin Li 99*67e74705SXin Li a. The ``invoke`` function pointer is set to a function that takes the 100*67e74705SXin Li ``Block`` structure as its first argument and the rest of the arguments (if 101*67e74705SXin Li any) to the ``Block`` and executes the ``Block`` compound statement. 102*67e74705SXin Li 103*67e74705SXin Li b. The ``size`` field is set to the size of the following ``Block`` literal 104*67e74705SXin Li structure. 105*67e74705SXin Li 106*67e74705SXin Li c. The ``copy_helper`` and ``dispose_helper`` function pointers are set to 107*67e74705SXin Li respective helper functions if they are required by the ``Block`` literal. 108*67e74705SXin Li 109*67e74705SXin Li2. A stack (or global) ``Block`` literal data structure is created and 110*67e74705SXin Li initialized as follows: 111*67e74705SXin Li 112*67e74705SXin Li a. The ``isa`` field is set to the address of the external 113*67e74705SXin Li ``_NSConcreteStackBlock``, which is a block of uninitialized memory supplied 114*67e74705SXin Li in ``libSystem``, or ``_NSConcreteGlobalBlock`` if this is a static or file 115*67e74705SXin Li level ``Block`` literal. 116*67e74705SXin Li 117*67e74705SXin Li b. The ``flags`` field is set to zero unless there are variables imported 118*67e74705SXin Li into the ``Block`` that need helper functions for program level 119*67e74705SXin Li ``Block_copy()`` and ``Block_release()`` operations, in which case the 120*67e74705SXin Li (1<<25) flags bit is set. 121*67e74705SXin Li 122*67e74705SXin LiAs an example, the ``Block`` literal expression: 123*67e74705SXin Li 124*67e74705SXin Li.. code-block:: c 125*67e74705SXin Li 126*67e74705SXin Li ^ { printf("hello world\n"); } 127*67e74705SXin Li 128*67e74705SXin Liwould cause the following to be created on a 32-bit system: 129*67e74705SXin Li 130*67e74705SXin Li.. code-block:: c 131*67e74705SXin Li 132*67e74705SXin Li struct __block_literal_1 { 133*67e74705SXin Li void *isa; 134*67e74705SXin Li int flags; 135*67e74705SXin Li int reserved; 136*67e74705SXin Li void (*invoke)(struct __block_literal_1 *); 137*67e74705SXin Li struct __block_descriptor_1 *descriptor; 138*67e74705SXin Li }; 139*67e74705SXin Li 140*67e74705SXin Li void __block_invoke_1(struct __block_literal_1 *_block) { 141*67e74705SXin Li printf("hello world\n"); 142*67e74705SXin Li } 143*67e74705SXin Li 144*67e74705SXin Li static struct __block_descriptor_1 { 145*67e74705SXin Li unsigned long int reserved; 146*67e74705SXin Li unsigned long int Block_size; 147*67e74705SXin Li } __block_descriptor_1 = { 0, sizeof(struct __block_literal_1), __block_invoke_1 }; 148*67e74705SXin Li 149*67e74705SXin Liand where the ``Block`` literal itself appears: 150*67e74705SXin Li 151*67e74705SXin Li.. code-block:: c 152*67e74705SXin Li 153*67e74705SXin Li struct __block_literal_1 _block_literal = { 154*67e74705SXin Li &_NSConcreteStackBlock, 155*67e74705SXin Li (1<<29), <uninitialized>, 156*67e74705SXin Li __block_invoke_1, 157*67e74705SXin Li &__block_descriptor_1 158*67e74705SXin Li }; 159*67e74705SXin Li 160*67e74705SXin LiA ``Block`` imports other ``Block`` references, ``const`` copies of other 161*67e74705SXin Livariables, and variables marked ``__block``. In Objective-C, variables may 162*67e74705SXin Liadditionally be objects. 163*67e74705SXin Li 164*67e74705SXin LiWhen a ``Block`` literal expression is used as the initial value of a global 165*67e74705SXin Lior ``static`` local variable, it is initialized as follows: 166*67e74705SXin Li 167*67e74705SXin Li.. code-block:: c 168*67e74705SXin Li 169*67e74705SXin Li struct __block_literal_1 __block_literal_1 = { 170*67e74705SXin Li &_NSConcreteGlobalBlock, 171*67e74705SXin Li (1<<28)|(1<<29), <uninitialized>, 172*67e74705SXin Li __block_invoke_1, 173*67e74705SXin Li &__block_descriptor_1 174*67e74705SXin Li }; 175*67e74705SXin Li 176*67e74705SXin Lithat is, a different address is provided as the first value and a particular 177*67e74705SXin Li(1<<28) bit is set in the ``flags`` field, and otherwise it is the same as for 178*67e74705SXin Listack based ``Block`` literals. This is an optimization that can be used for 179*67e74705SXin Liany ``Block`` literal that imports no ``const`` or ``__block`` storage 180*67e74705SXin Livariables. 181*67e74705SXin Li 182*67e74705SXin LiImported Variables 183*67e74705SXin Li================== 184*67e74705SXin Li 185*67e74705SXin LiVariables of ``auto`` storage class are imported as ``const`` copies. Variables 186*67e74705SXin Liof ``__block`` storage class are imported as a pointer to an enclosing data 187*67e74705SXin Listructure. Global variables are simply referenced and not considered as 188*67e74705SXin Liimported. 189*67e74705SXin Li 190*67e74705SXin LiImported ``const`` copy variables 191*67e74705SXin Li--------------------------------- 192*67e74705SXin Li 193*67e74705SXin LiAutomatic storage variables not marked with ``__block`` are imported as 194*67e74705SXin Li``const`` copies. 195*67e74705SXin Li 196*67e74705SXin LiThe simplest example is that of importing a variable of type ``int``: 197*67e74705SXin Li 198*67e74705SXin Li.. code-block:: c 199*67e74705SXin Li 200*67e74705SXin Li int x = 10; 201*67e74705SXin Li void (^vv)(void) = ^{ printf("x is %d\n", x); } 202*67e74705SXin Li x = 11; 203*67e74705SXin Li vv(); 204*67e74705SXin Li 205*67e74705SXin Liwhich would be compiled to: 206*67e74705SXin Li 207*67e74705SXin Li.. code-block:: c 208*67e74705SXin Li 209*67e74705SXin Li struct __block_literal_2 { 210*67e74705SXin Li void *isa; 211*67e74705SXin Li int flags; 212*67e74705SXin Li int reserved; 213*67e74705SXin Li void (*invoke)(struct __block_literal_2 *); 214*67e74705SXin Li struct __block_descriptor_2 *descriptor; 215*67e74705SXin Li const int x; 216*67e74705SXin Li }; 217*67e74705SXin Li 218*67e74705SXin Li void __block_invoke_2(struct __block_literal_2 *_block) { 219*67e74705SXin Li printf("x is %d\n", _block->x); 220*67e74705SXin Li } 221*67e74705SXin Li 222*67e74705SXin Li static struct __block_descriptor_2 { 223*67e74705SXin Li unsigned long int reserved; 224*67e74705SXin Li unsigned long int Block_size; 225*67e74705SXin Li } __block_descriptor_2 = { 0, sizeof(struct __block_literal_2) }; 226*67e74705SXin Li 227*67e74705SXin Liand: 228*67e74705SXin Li 229*67e74705SXin Li.. code-block:: c 230*67e74705SXin Li 231*67e74705SXin Li struct __block_literal_2 __block_literal_2 = { 232*67e74705SXin Li &_NSConcreteStackBlock, 233*67e74705SXin Li (1<<29), <uninitialized>, 234*67e74705SXin Li __block_invoke_2, 235*67e74705SXin Li &__block_descriptor_2, 236*67e74705SXin Li x 237*67e74705SXin Li }; 238*67e74705SXin Li 239*67e74705SXin LiIn summary, scalars, structures, unions, and function pointers are generally 240*67e74705SXin Liimported as ``const`` copies with no need for helper functions. 241*67e74705SXin Li 242*67e74705SXin LiImported ``const`` copy of ``Block`` reference 243*67e74705SXin Li---------------------------------------------- 244*67e74705SXin Li 245*67e74705SXin LiThe first case where copy and dispose helper functions are required is for the 246*67e74705SXin Licase of when a ``Block`` itself is imported. In this case both a 247*67e74705SXin Li``copy_helper`` function and a ``dispose_helper`` function are needed. The 248*67e74705SXin Li``copy_helper`` function is passed both the existing stack based pointer and the 249*67e74705SXin Lipointer to the new heap version and should call back into the runtime to 250*67e74705SXin Liactually do the copy operation on the imported fields within the ``Block``. The 251*67e74705SXin Liruntime functions are all described in :ref:`RuntimeHelperFunctions`. 252*67e74705SXin Li 253*67e74705SXin LiA quick example: 254*67e74705SXin Li 255*67e74705SXin Li.. code-block:: c 256*67e74705SXin Li 257*67e74705SXin Li void (^existingBlock)(void) = ...; 258*67e74705SXin Li void (^vv)(void) = ^{ existingBlock(); } 259*67e74705SXin Li vv(); 260*67e74705SXin Li 261*67e74705SXin Li struct __block_literal_3 { 262*67e74705SXin Li ...; // existing block 263*67e74705SXin Li }; 264*67e74705SXin Li 265*67e74705SXin Li struct __block_literal_4 { 266*67e74705SXin Li void *isa; 267*67e74705SXin Li int flags; 268*67e74705SXin Li int reserved; 269*67e74705SXin Li void (*invoke)(struct __block_literal_4 *); 270*67e74705SXin Li struct __block_literal_3 *const existingBlock; 271*67e74705SXin Li }; 272*67e74705SXin Li 273*67e74705SXin Li void __block_invoke_4(struct __block_literal_2 *_block) { 274*67e74705SXin Li __block->existingBlock->invoke(__block->existingBlock); 275*67e74705SXin Li } 276*67e74705SXin Li 277*67e74705SXin Li void __block_copy_4(struct __block_literal_4 *dst, struct __block_literal_4 *src) { 278*67e74705SXin Li //_Block_copy_assign(&dst->existingBlock, src->existingBlock, 0); 279*67e74705SXin Li _Block_object_assign(&dst->existingBlock, src->existingBlock, BLOCK_FIELD_IS_BLOCK); 280*67e74705SXin Li } 281*67e74705SXin Li 282*67e74705SXin Li void __block_dispose_4(struct __block_literal_4 *src) { 283*67e74705SXin Li // was _Block_destroy 284*67e74705SXin Li _Block_object_dispose(src->existingBlock, BLOCK_FIELD_IS_BLOCK); 285*67e74705SXin Li } 286*67e74705SXin Li 287*67e74705SXin Li static struct __block_descriptor_4 { 288*67e74705SXin Li unsigned long int reserved; 289*67e74705SXin Li unsigned long int Block_size; 290*67e74705SXin Li void (*copy_helper)(struct __block_literal_4 *dst, struct __block_literal_4 *src); 291*67e74705SXin Li void (*dispose_helper)(struct __block_literal_4 *); 292*67e74705SXin Li } __block_descriptor_4 = { 293*67e74705SXin Li 0, 294*67e74705SXin Li sizeof(struct __block_literal_4), 295*67e74705SXin Li __block_copy_4, 296*67e74705SXin Li __block_dispose_4, 297*67e74705SXin Li }; 298*67e74705SXin Li 299*67e74705SXin Liand where said ``Block`` is used: 300*67e74705SXin Li 301*67e74705SXin Li.. code-block:: c 302*67e74705SXin Li 303*67e74705SXin Li struct __block_literal_4 _block_literal = { 304*67e74705SXin Li &_NSConcreteStackBlock, 305*67e74705SXin Li (1<<25)|(1<<29), <uninitialized> 306*67e74705SXin Li __block_invoke_4, 307*67e74705SXin Li & __block_descriptor_4 308*67e74705SXin Li existingBlock, 309*67e74705SXin Li }; 310*67e74705SXin Li 311*67e74705SXin LiImporting ``__attribute__((NSObject))`` variables 312*67e74705SXin Li^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 313*67e74705SXin Li 314*67e74705SXin LiGCC introduces ``__attribute__((NSObject))`` on structure pointers to mean "this 315*67e74705SXin Liis an object". This is useful because many low level data structures are 316*67e74705SXin Lideclared as opaque structure pointers, e.g. ``CFStringRef``, ``CFArrayRef``, 317*67e74705SXin Lietc. When used from C, however, these are still really objects and are the 318*67e74705SXin Lisecond case where that requires copy and dispose helper functions to be 319*67e74705SXin Ligenerated. The copy helper functions generated by the compiler should use the 320*67e74705SXin Li``_Block_object_assign`` runtime helper function and in the dispose helper the 321*67e74705SXin Li``_Block_object_dispose`` runtime helper function should be called. 322*67e74705SXin Li 323*67e74705SXin LiFor example, ``Block`` foo in the following: 324*67e74705SXin Li 325*67e74705SXin Li.. code-block:: c 326*67e74705SXin Li 327*67e74705SXin Li struct Opaque *__attribute__((NSObject)) objectPointer = ...; 328*67e74705SXin Li ... 329*67e74705SXin Li void (^foo)(void) = ^{ CFPrint(objectPointer); }; 330*67e74705SXin Li 331*67e74705SXin Liwould have the following helper functions generated: 332*67e74705SXin Li 333*67e74705SXin Li.. code-block:: c 334*67e74705SXin Li 335*67e74705SXin Li void __block_copy_foo(struct __block_literal_5 *dst, struct __block_literal_5 *src) { 336*67e74705SXin Li _Block_object_assign(&dst->objectPointer, src-> objectPointer, BLOCK_FIELD_IS_OBJECT); 337*67e74705SXin Li } 338*67e74705SXin Li 339*67e74705SXin Li void __block_dispose_foo(struct __block_literal_5 *src) { 340*67e74705SXin Li _Block_object_dispose(src->objectPointer, BLOCK_FIELD_IS_OBJECT); 341*67e74705SXin Li } 342*67e74705SXin Li 343*67e74705SXin LiImported ``__block`` marked variables 344*67e74705SXin Li------------------------------------- 345*67e74705SXin Li 346*67e74705SXin LiLayout of ``__block`` marked variables 347*67e74705SXin Li^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 348*67e74705SXin Li 349*67e74705SXin LiThe compiler must embed variables that are marked ``__block`` in a specialized 350*67e74705SXin Listructure of the form: 351*67e74705SXin Li 352*67e74705SXin Li.. code-block:: c 353*67e74705SXin Li 354*67e74705SXin Li struct _block_byref_foo { 355*67e74705SXin Li void *isa; 356*67e74705SXin Li struct Block_byref *forwarding; 357*67e74705SXin Li int flags; //refcount; 358*67e74705SXin Li int size; 359*67e74705SXin Li typeof(marked_variable) marked_variable; 360*67e74705SXin Li }; 361*67e74705SXin Li 362*67e74705SXin LiVariables of certain types require helper functions for when ``Block_copy()`` 363*67e74705SXin Liand ``Block_release()`` are performed upon a referencing ``Block``. At the "C" 364*67e74705SXin Lilevel only variables that are of type ``Block`` or ones that have 365*67e74705SXin Li``__attribute__((NSObject))`` marked require helper functions. In Objective-C 366*67e74705SXin Liobjects require helper functions and in C++ stack based objects require helper 367*67e74705SXin Lifunctions. Variables that require helper functions use the form: 368*67e74705SXin Li 369*67e74705SXin Li.. code-block:: c 370*67e74705SXin Li 371*67e74705SXin Li struct _block_byref_foo { 372*67e74705SXin Li void *isa; 373*67e74705SXin Li struct _block_byref_foo *forwarding; 374*67e74705SXin Li int flags; //refcount; 375*67e74705SXin Li int size; 376*67e74705SXin Li // helper functions called via Block_copy() and Block_release() 377*67e74705SXin Li void (*byref_keep)(void *dst, void *src); 378*67e74705SXin Li void (*byref_dispose)(void *); 379*67e74705SXin Li typeof(marked_variable) marked_variable; 380*67e74705SXin Li }; 381*67e74705SXin Li 382*67e74705SXin LiThe structure is initialized such that: 383*67e74705SXin Li 384*67e74705SXin Li a. The ``forwarding`` pointer is set to the beginning of its enclosing 385*67e74705SXin Li structure. 386*67e74705SXin Li 387*67e74705SXin Li b. The ``size`` field is initialized to the total size of the enclosing 388*67e74705SXin Li structure. 389*67e74705SXin Li 390*67e74705SXin Li c. The ``flags`` field is set to either 0 if no helper functions are needed 391*67e74705SXin Li or (1<<25) if they are. 392*67e74705SXin Li 393*67e74705SXin Li d. The helper functions are initialized (if present). 394*67e74705SXin Li 395*67e74705SXin Li e. The variable itself is set to its initial value. 396*67e74705SXin Li 397*67e74705SXin Li f. The ``isa`` field is set to ``NULL``. 398*67e74705SXin Li 399*67e74705SXin LiAccess to ``__block`` variables from within its lexical scope 400*67e74705SXin Li^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 401*67e74705SXin Li 402*67e74705SXin LiIn order to "move" the variable to the heap upon a ``copy_helper`` operation the 403*67e74705SXin Licompiler must rewrite access to such a variable to be indirect through the 404*67e74705SXin Listructures ``forwarding`` pointer. For example: 405*67e74705SXin Li 406*67e74705SXin Li.. code-block:: c 407*67e74705SXin Li 408*67e74705SXin Li int __block i = 10; 409*67e74705SXin Li i = 11; 410*67e74705SXin Li 411*67e74705SXin Liwould be rewritten to be: 412*67e74705SXin Li 413*67e74705SXin Li.. code-block:: c 414*67e74705SXin Li 415*67e74705SXin Li struct _block_byref_i { 416*67e74705SXin Li void *isa; 417*67e74705SXin Li struct _block_byref_i *forwarding; 418*67e74705SXin Li int flags; //refcount; 419*67e74705SXin Li int size; 420*67e74705SXin Li int captured_i; 421*67e74705SXin Li } i = { NULL, &i, 0, sizeof(struct _block_byref_i), 10 }; 422*67e74705SXin Li 423*67e74705SXin Li i.forwarding->captured_i = 11; 424*67e74705SXin Li 425*67e74705SXin LiIn the case of a ``Block`` reference variable being marked ``__block`` the 426*67e74705SXin Lihelper code generated must use the ``_Block_object_assign`` and 427*67e74705SXin Li``_Block_object_dispose`` routines supplied by the runtime to make the 428*67e74705SXin Licopies. For example: 429*67e74705SXin Li 430*67e74705SXin Li.. code-block:: c 431*67e74705SXin Li 432*67e74705SXin Li __block void (voidBlock)(void) = blockA; 433*67e74705SXin Li voidBlock = blockB; 434*67e74705SXin Li 435*67e74705SXin Liwould translate into: 436*67e74705SXin Li 437*67e74705SXin Li.. code-block:: c 438*67e74705SXin Li 439*67e74705SXin Li struct _block_byref_voidBlock { 440*67e74705SXin Li void *isa; 441*67e74705SXin Li struct _block_byref_voidBlock *forwarding; 442*67e74705SXin Li int flags; //refcount; 443*67e74705SXin Li int size; 444*67e74705SXin Li void (*byref_keep)(struct _block_byref_voidBlock *dst, struct _block_byref_voidBlock *src); 445*67e74705SXin Li void (*byref_dispose)(struct _block_byref_voidBlock *); 446*67e74705SXin Li void (^captured_voidBlock)(void); 447*67e74705SXin Li }; 448*67e74705SXin Li 449*67e74705SXin Li void _block_byref_keep_helper(struct _block_byref_voidBlock *dst, struct _block_byref_voidBlock *src) { 450*67e74705SXin Li //_Block_copy_assign(&dst->captured_voidBlock, src->captured_voidBlock, 0); 451*67e74705SXin Li _Block_object_assign(&dst->captured_voidBlock, src->captured_voidBlock, BLOCK_FIELD_IS_BLOCK | BLOCK_BYREF_CALLER); 452*67e74705SXin Li } 453*67e74705SXin Li 454*67e74705SXin Li void _block_byref_dispose_helper(struct _block_byref_voidBlock *param) { 455*67e74705SXin Li //_Block_destroy(param->captured_voidBlock, 0); 456*67e74705SXin Li _Block_object_dispose(param->captured_voidBlock, BLOCK_FIELD_IS_BLOCK | BLOCK_BYREF_CALLER)} 457*67e74705SXin Li 458*67e74705SXin Liand: 459*67e74705SXin Li 460*67e74705SXin Li.. code-block:: c 461*67e74705SXin Li 462*67e74705SXin Li struct _block_byref_voidBlock voidBlock = {( .forwarding=&voidBlock, .flags=(1<<25), .size=sizeof(struct _block_byref_voidBlock *), 463*67e74705SXin Li .byref_keep=_block_byref_keep_helper, .byref_dispose=_block_byref_dispose_helper, 464*67e74705SXin Li .captured_voidBlock=blockA )}; 465*67e74705SXin Li 466*67e74705SXin Li voidBlock.forwarding->captured_voidBlock = blockB; 467*67e74705SXin Li 468*67e74705SXin LiImporting ``__block`` variables into ``Blocks`` 469*67e74705SXin Li^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 470*67e74705SXin Li 471*67e74705SXin LiA ``Block`` that uses a ``__block`` variable in its compound statement body must 472*67e74705SXin Liimport the variable and emit ``copy_helper`` and ``dispose_helper`` helper 473*67e74705SXin Lifunctions that, in turn, call back into the runtime to actually copy or release 474*67e74705SXin Lithe ``byref`` data block using the functions ``_Block_object_assign`` and 475*67e74705SXin Li``_Block_object_dispose``. 476*67e74705SXin Li 477*67e74705SXin LiFor example: 478*67e74705SXin Li 479*67e74705SXin Li.. code-block:: c 480*67e74705SXin Li 481*67e74705SXin Li int __block i = 2; 482*67e74705SXin Li functioncall(^{ i = 10; }); 483*67e74705SXin Li 484*67e74705SXin Liwould translate to: 485*67e74705SXin Li 486*67e74705SXin Li.. code-block:: c 487*67e74705SXin Li 488*67e74705SXin Li struct _block_byref_i { 489*67e74705SXin Li void *isa; // set to NULL 490*67e74705SXin Li struct _block_byref_voidBlock *forwarding; 491*67e74705SXin Li int flags; //refcount; 492*67e74705SXin Li int size; 493*67e74705SXin Li void (*byref_keep)(struct _block_byref_i *dst, struct _block_byref_i *src); 494*67e74705SXin Li void (*byref_dispose)(struct _block_byref_i *); 495*67e74705SXin Li int captured_i; 496*67e74705SXin Li }; 497*67e74705SXin Li 498*67e74705SXin Li 499*67e74705SXin Li struct __block_literal_5 { 500*67e74705SXin Li void *isa; 501*67e74705SXin Li int flags; 502*67e74705SXin Li int reserved; 503*67e74705SXin Li void (*invoke)(struct __block_literal_5 *); 504*67e74705SXin Li struct __block_descriptor_5 *descriptor; 505*67e74705SXin Li struct _block_byref_i *i_holder; 506*67e74705SXin Li }; 507*67e74705SXin Li 508*67e74705SXin Li void __block_invoke_5(struct __block_literal_5 *_block) { 509*67e74705SXin Li _block->forwarding->captured_i = 10; 510*67e74705SXin Li } 511*67e74705SXin Li 512*67e74705SXin Li void __block_copy_5(struct __block_literal_5 *dst, struct __block_literal_5 *src) { 513*67e74705SXin Li //_Block_byref_assign_copy(&dst->captured_i, src->captured_i); 514*67e74705SXin Li _Block_object_assign(&dst->captured_i, src->captured_i, BLOCK_FIELD_IS_BYREF | BLOCK_BYREF_CALLER); 515*67e74705SXin Li } 516*67e74705SXin Li 517*67e74705SXin Li void __block_dispose_5(struct __block_literal_5 *src) { 518*67e74705SXin Li //_Block_byref_release(src->captured_i); 519*67e74705SXin Li _Block_object_dispose(src->captured_i, BLOCK_FIELD_IS_BYREF | BLOCK_BYREF_CALLER); 520*67e74705SXin Li } 521*67e74705SXin Li 522*67e74705SXin Li static struct __block_descriptor_5 { 523*67e74705SXin Li unsigned long int reserved; 524*67e74705SXin Li unsigned long int Block_size; 525*67e74705SXin Li void (*copy_helper)(struct __block_literal_5 *dst, struct __block_literal_5 *src); 526*67e74705SXin Li void (*dispose_helper)(struct __block_literal_5 *); 527*67e74705SXin Li } __block_descriptor_5 = { 0, sizeof(struct __block_literal_5) __block_copy_5, __block_dispose_5 }; 528*67e74705SXin Li 529*67e74705SXin Liand: 530*67e74705SXin Li 531*67e74705SXin Li.. code-block:: c 532*67e74705SXin Li 533*67e74705SXin Li struct _block_byref_i i = {( .forwarding=&i, .flags=0, .size=sizeof(struct _block_byref_i) )}; 534*67e74705SXin Li struct __block_literal_5 _block_literal = { 535*67e74705SXin Li &_NSConcreteStackBlock, 536*67e74705SXin Li (1<<25)|(1<<29), <uninitialized>, 537*67e74705SXin Li __block_invoke_5, 538*67e74705SXin Li &__block_descriptor_5, 539*67e74705SXin Li 2, 540*67e74705SXin Li }; 541*67e74705SXin Li 542*67e74705SXin LiImporting ``__attribute__((NSObject))`` ``__block`` variables 543*67e74705SXin Li^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 544*67e74705SXin Li 545*67e74705SXin LiA ``__block`` variable that is also marked ``__attribute__((NSObject))`` should 546*67e74705SXin Lihave ``byref_keep`` and ``byref_dispose`` helper functions that use 547*67e74705SXin Li``_Block_object_assign`` and ``_Block_object_dispose``. 548*67e74705SXin Li 549*67e74705SXin Li``__block`` escapes 550*67e74705SXin Li^^^^^^^^^^^^^^^^^^^ 551*67e74705SXin Li 552*67e74705SXin LiBecause ``Blocks`` referencing ``__block`` variables may have ``Block_copy()`` 553*67e74705SXin Liperformed upon them the underlying storage for the variables may move to the 554*67e74705SXin Liheap. In Objective-C Garbage Collection Only compilation environments the heap 555*67e74705SXin Liused is the garbage collected one and no further action is required. Otherwise 556*67e74705SXin Lithe compiler must issue a call to potentially release any heap storage for 557*67e74705SXin Li``__block`` variables at all escapes or terminations of their scope. The call 558*67e74705SXin Lishould be: 559*67e74705SXin Li 560*67e74705SXin Li.. code-block:: c 561*67e74705SXin Li 562*67e74705SXin Li _Block_object_dispose(&_block_byref_foo, BLOCK_FIELD_IS_BYREF); 563*67e74705SXin Li 564*67e74705SXin LiNesting 565*67e74705SXin Li^^^^^^^ 566*67e74705SXin Li 567*67e74705SXin Li``Blocks`` may contain ``Block`` literal expressions. Any variables used within 568*67e74705SXin Liinner blocks are imported into all enclosing ``Block`` scopes even if the 569*67e74705SXin Livariables are not used. This includes ``const`` imports as well as ``__block`` 570*67e74705SXin Livariables. 571*67e74705SXin Li 572*67e74705SXin LiObjective C Extensions to ``Blocks`` 573*67e74705SXin Li==================================== 574*67e74705SXin Li 575*67e74705SXin LiImporting Objects 576*67e74705SXin Li----------------- 577*67e74705SXin Li 578*67e74705SXin LiObjects should be treated as ``__attribute__((NSObject))`` variables; all 579*67e74705SXin Li``copy_helper``, ``dispose_helper``, ``byref_keep``, and ``byref_dispose`` 580*67e74705SXin Lihelper functions should use ``_Block_object_assign`` and 581*67e74705SXin Li``_Block_object_dispose``. There should be no code generated that uses 582*67e74705SXin Li``*-retain`` or ``*-release`` methods. 583*67e74705SXin Li 584*67e74705SXin Li``Blocks`` as Objects 585*67e74705SXin Li--------------------- 586*67e74705SXin Li 587*67e74705SXin LiThe compiler will treat ``Blocks`` as objects when synthesizing property setters 588*67e74705SXin Liand getters, will characterize them as objects when generating garbage 589*67e74705SXin Licollection strong and weak layout information in the same manner as objects, and 590*67e74705SXin Liwill issue strong and weak write-barrier assignments in the same manner as 591*67e74705SXin Liobjects. 592*67e74705SXin Li 593*67e74705SXin Li``__weak __block`` Support 594*67e74705SXin Li-------------------------- 595*67e74705SXin Li 596*67e74705SXin LiObjective-C (and Objective-C++) support the ``__weak`` attribute on ``__block`` 597*67e74705SXin Livariables. Under normal circumstances the compiler uses the Objective-C runtime 598*67e74705SXin Lihelper support functions ``objc_assign_weak`` and ``objc_read_weak``. Both 599*67e74705SXin Lishould continue to be used for all reads and writes of ``__weak __block`` 600*67e74705SXin Livariables: 601*67e74705SXin Li 602*67e74705SXin Li.. code-block:: c 603*67e74705SXin Li 604*67e74705SXin Li objc_read_weak(&block->byref_i->forwarding->i) 605*67e74705SXin Li 606*67e74705SXin LiThe ``__weak`` variable is stored in a ``_block_byref_foo`` structure and the 607*67e74705SXin Li``Block`` has copy and dispose helpers for this structure that call: 608*67e74705SXin Li 609*67e74705SXin Li.. code-block:: c 610*67e74705SXin Li 611*67e74705SXin Li _Block_object_assign(&dest->_block_byref_i, src-> _block_byref_i, BLOCK_FIELD_IS_WEAK | BLOCK_FIELD_IS_BYREF); 612*67e74705SXin Li 613*67e74705SXin Liand: 614*67e74705SXin Li 615*67e74705SXin Li.. code-block:: c 616*67e74705SXin Li 617*67e74705SXin Li _Block_object_dispose(src->_block_byref_i, BLOCK_FIELD_IS_WEAK | BLOCK_FIELD_IS_BYREF); 618*67e74705SXin Li 619*67e74705SXin LiIn turn, the ``block_byref`` copy support helpers distinguish between whether 620*67e74705SXin Lithe ``__block`` variable is a ``Block`` or not and should either call: 621*67e74705SXin Li 622*67e74705SXin Li.. code-block:: c 623*67e74705SXin Li 624*67e74705SXin Li _Block_object_assign(&dest->_block_byref_i, src->_block_byref_i, BLOCK_FIELD_IS_WEAK | BLOCK_FIELD_IS_OBJECT | BLOCK_BYREF_CALLER); 625*67e74705SXin Li 626*67e74705SXin Lifor something declared as an object or: 627*67e74705SXin Li 628*67e74705SXin Li.. code-block:: c 629*67e74705SXin Li 630*67e74705SXin Li _Block_object_assign(&dest->_block_byref_i, src->_block_byref_i, BLOCK_FIELD_IS_WEAK | BLOCK_FIELD_IS_BLOCK | BLOCK_BYREF_CALLER); 631*67e74705SXin Li 632*67e74705SXin Lifor something declared as a ``Block``. 633*67e74705SXin Li 634*67e74705SXin LiA full example follows: 635*67e74705SXin Li 636*67e74705SXin Li.. code-block:: c 637*67e74705SXin Li 638*67e74705SXin Li __block __weak id obj = <initialization expression>; 639*67e74705SXin Li functioncall(^{ [obj somemessage]; }); 640*67e74705SXin Li 641*67e74705SXin Liwould translate to: 642*67e74705SXin Li 643*67e74705SXin Li.. code-block:: c 644*67e74705SXin Li 645*67e74705SXin Li struct _block_byref_obj { 646*67e74705SXin Li void *isa; // uninitialized 647*67e74705SXin Li struct _block_byref_obj *forwarding; 648*67e74705SXin Li int flags; //refcount; 649*67e74705SXin Li int size; 650*67e74705SXin Li void (*byref_keep)(struct _block_byref_i *dst, struct _block_byref_i *src); 651*67e74705SXin Li void (*byref_dispose)(struct _block_byref_i *); 652*67e74705SXin Li id captured_obj; 653*67e74705SXin Li }; 654*67e74705SXin Li 655*67e74705SXin Li void _block_byref_obj_keep(struct _block_byref_voidBlock *dst, struct _block_byref_voidBlock *src) { 656*67e74705SXin Li //_Block_copy_assign(&dst->captured_obj, src->captured_obj, 0); 657*67e74705SXin Li _Block_object_assign(&dst->captured_obj, src->captured_obj, BLOCK_FIELD_IS_OBJECT | BLOCK_FIELD_IS_WEAK | BLOCK_BYREF_CALLER); 658*67e74705SXin Li } 659*67e74705SXin Li 660*67e74705SXin Li void _block_byref_obj_dispose(struct _block_byref_voidBlock *param) { 661*67e74705SXin Li //_Block_destroy(param->captured_obj, 0); 662*67e74705SXin Li _Block_object_dispose(param->captured_obj, BLOCK_FIELD_IS_OBJECT | BLOCK_FIELD_IS_WEAK | BLOCK_BYREF_CALLER); 663*67e74705SXin Li }; 664*67e74705SXin Li 665*67e74705SXin Lifor the block ``byref`` part and: 666*67e74705SXin Li 667*67e74705SXin Li.. code-block:: c 668*67e74705SXin Li 669*67e74705SXin Li struct __block_literal_5 { 670*67e74705SXin Li void *isa; 671*67e74705SXin Li int flags; 672*67e74705SXin Li int reserved; 673*67e74705SXin Li void (*invoke)(struct __block_literal_5 *); 674*67e74705SXin Li struct __block_descriptor_5 *descriptor; 675*67e74705SXin Li struct _block_byref_obj *byref_obj; 676*67e74705SXin Li }; 677*67e74705SXin Li 678*67e74705SXin Li void __block_invoke_5(struct __block_literal_5 *_block) { 679*67e74705SXin Li [objc_read_weak(&_block->byref_obj->forwarding->captured_obj) somemessage]; 680*67e74705SXin Li } 681*67e74705SXin Li 682*67e74705SXin Li void __block_copy_5(struct __block_literal_5 *dst, struct __block_literal_5 *src) { 683*67e74705SXin Li //_Block_byref_assign_copy(&dst->byref_obj, src->byref_obj); 684*67e74705SXin Li _Block_object_assign(&dst->byref_obj, src->byref_obj, BLOCK_FIELD_IS_BYREF | BLOCK_FIELD_IS_WEAK); 685*67e74705SXin Li } 686*67e74705SXin Li 687*67e74705SXin Li void __block_dispose_5(struct __block_literal_5 *src) { 688*67e74705SXin Li //_Block_byref_release(src->byref_obj); 689*67e74705SXin Li _Block_object_dispose(src->byref_obj, BLOCK_FIELD_IS_BYREF | BLOCK_FIELD_IS_WEAK); 690*67e74705SXin Li } 691*67e74705SXin Li 692*67e74705SXin Li static struct __block_descriptor_5 { 693*67e74705SXin Li unsigned long int reserved; 694*67e74705SXin Li unsigned long int Block_size; 695*67e74705SXin Li void (*copy_helper)(struct __block_literal_5 *dst, struct __block_literal_5 *src); 696*67e74705SXin Li void (*dispose_helper)(struct __block_literal_5 *); 697*67e74705SXin Li } __block_descriptor_5 = { 0, sizeof(struct __block_literal_5), __block_copy_5, __block_dispose_5 }; 698*67e74705SXin Li 699*67e74705SXin Liand within the compound statement: 700*67e74705SXin Li 701*67e74705SXin Li.. code-block:: c 702*67e74705SXin Li 703*67e74705SXin Li truct _block_byref_obj obj = {( .forwarding=&obj, .flags=(1<<25), .size=sizeof(struct _block_byref_obj), 704*67e74705SXin Li .byref_keep=_block_byref_obj_keep, .byref_dispose=_block_byref_obj_dispose, 705*67e74705SXin Li .captured_obj = <initialization expression> )}; 706*67e74705SXin Li 707*67e74705SXin Li truct __block_literal_5 _block_literal = { 708*67e74705SXin Li &_NSConcreteStackBlock, 709*67e74705SXin Li (1<<25)|(1<<29), <uninitialized>, 710*67e74705SXin Li __block_invoke_5, 711*67e74705SXin Li &__block_descriptor_5, 712*67e74705SXin Li &obj, // a reference to the on-stack structure containing "captured_obj" 713*67e74705SXin Li }; 714*67e74705SXin Li 715*67e74705SXin Li 716*67e74705SXin Li functioncall(_block_literal->invoke(&_block_literal)); 717*67e74705SXin Li 718*67e74705SXin LiC++ Support 719*67e74705SXin Li=========== 720*67e74705SXin Li 721*67e74705SXin LiWithin a block stack based C++ objects are copied into ``const`` copies using 722*67e74705SXin Lithe copy constructor. It is an error if a stack based C++ object is used within 723*67e74705SXin Lia block if it does not have a copy constructor. In addition both copy and 724*67e74705SXin Lidestroy helper routines must be synthesized for the block to support the 725*67e74705SXin Li``Block_copy()`` operation, and the flags work marked with the (1<<26) bit in 726*67e74705SXin Liaddition to the (1<<25) bit. The copy helper should call the constructor using 727*67e74705SXin Liappropriate offsets of the variable within the supplied stack based block source 728*67e74705SXin Liand heap based destination for all ``const`` constructed copies, and similarly 729*67e74705SXin Lishould call the destructor in the destroy routine. 730*67e74705SXin Li 731*67e74705SXin LiAs an example, suppose a C++ class ``FOO`` existed with a copy constructor. 732*67e74705SXin LiWithin a code block a stack version of a ``FOO`` object is declared and used 733*67e74705SXin Liwithin a ``Block`` literal expression: 734*67e74705SXin Li 735*67e74705SXin Li.. code-block:: c++ 736*67e74705SXin Li 737*67e74705SXin Li { 738*67e74705SXin Li FOO foo; 739*67e74705SXin Li void (^block)(void) = ^{ printf("%d\n", foo.value()); }; 740*67e74705SXin Li } 741*67e74705SXin Li 742*67e74705SXin LiThe compiler would synthesize: 743*67e74705SXin Li 744*67e74705SXin Li.. code-block:: c++ 745*67e74705SXin Li 746*67e74705SXin Li struct __block_literal_10 { 747*67e74705SXin Li void *isa; 748*67e74705SXin Li int flags; 749*67e74705SXin Li int reserved; 750*67e74705SXin Li void (*invoke)(struct __block_literal_10 *); 751*67e74705SXin Li struct __block_descriptor_10 *descriptor; 752*67e74705SXin Li const FOO foo; 753*67e74705SXin Li }; 754*67e74705SXin Li 755*67e74705SXin Li void __block_invoke_10(struct __block_literal_10 *_block) { 756*67e74705SXin Li printf("%d\n", _block->foo.value()); 757*67e74705SXin Li } 758*67e74705SXin Li 759*67e74705SXin Li void __block_literal_10(struct __block_literal_10 *dst, struct __block_literal_10 *src) { 760*67e74705SXin Li FOO_ctor(&dst->foo, &src->foo); 761*67e74705SXin Li } 762*67e74705SXin Li 763*67e74705SXin Li void __block_dispose_10(struct __block_literal_10 *src) { 764*67e74705SXin Li FOO_dtor(&src->foo); 765*67e74705SXin Li } 766*67e74705SXin Li 767*67e74705SXin Li static struct __block_descriptor_10 { 768*67e74705SXin Li unsigned long int reserved; 769*67e74705SXin Li unsigned long int Block_size; 770*67e74705SXin Li void (*copy_helper)(struct __block_literal_10 *dst, struct __block_literal_10 *src); 771*67e74705SXin Li void (*dispose_helper)(struct __block_literal_10 *); 772*67e74705SXin Li } __block_descriptor_10 = { 0, sizeof(struct __block_literal_10), __block_copy_10, __block_dispose_10 }; 773*67e74705SXin Li 774*67e74705SXin Liand the code would be: 775*67e74705SXin Li 776*67e74705SXin Li.. code-block:: c++ 777*67e74705SXin Li 778*67e74705SXin Li { 779*67e74705SXin Li FOO foo; 780*67e74705SXin Li comp_ctor(&foo); // default constructor 781*67e74705SXin Li struct __block_literal_10 _block_literal = { 782*67e74705SXin Li &_NSConcreteStackBlock, 783*67e74705SXin Li (1<<25)|(1<<26)|(1<<29), <uninitialized>, 784*67e74705SXin Li __block_invoke_10, 785*67e74705SXin Li &__block_descriptor_10, 786*67e74705SXin Li }; 787*67e74705SXin Li comp_ctor(&_block_literal->foo, &foo); // const copy into stack version 788*67e74705SXin Li struct __block_literal_10 &block = &_block_literal; // assign literal to block variable 789*67e74705SXin Li block->invoke(block); // invoke block 790*67e74705SXin Li comp_dtor(&_block_literal->foo); // destroy stack version of const block copy 791*67e74705SXin Li comp_dtor(&foo); // destroy original version 792*67e74705SXin Li } 793*67e74705SXin Li 794*67e74705SXin Li 795*67e74705SXin LiC++ objects stored in ``__block`` storage start out on the stack in a 796*67e74705SXin Li``block_byref`` data structure as do other variables. Such objects (if not 797*67e74705SXin Li``const`` objects) must support a regular copy constructor. The ``block_byref`` 798*67e74705SXin Lidata structure will have copy and destroy helper routines synthesized by the 799*67e74705SXin Licompiler. The copy helper will have code created to perform the copy 800*67e74705SXin Liconstructor based on the initial stack ``block_byref`` data structure, and will 801*67e74705SXin Lialso set the (1<<26) bit in addition to the (1<<25) bit. The destroy helper 802*67e74705SXin Liwill have code to do the destructor on the object stored within the supplied 803*67e74705SXin Li``block_byref`` heap data structure. For example, 804*67e74705SXin Li 805*67e74705SXin Li.. code-block:: c++ 806*67e74705SXin Li 807*67e74705SXin Li __block FOO blockStorageFoo; 808*67e74705SXin Li 809*67e74705SXin Lirequires the normal constructor for the embedded ``blockStorageFoo`` object: 810*67e74705SXin Li 811*67e74705SXin Li.. code-block:: c++ 812*67e74705SXin Li 813*67e74705SXin Li FOO_ctor(& _block_byref_blockStorageFoo->blockStorageFoo); 814*67e74705SXin Li 815*67e74705SXin Liand at scope termination the destructor: 816*67e74705SXin Li 817*67e74705SXin Li.. code-block:: c++ 818*67e74705SXin Li 819*67e74705SXin Li FOO_dtor(& _block_byref_blockStorageFoo->blockStorageFoo); 820*67e74705SXin Li 821*67e74705SXin LiNote that the forwarding indirection is *NOT* used. 822*67e74705SXin Li 823*67e74705SXin LiThe compiler would need to generate (if used from a block literal) the following 824*67e74705SXin Licopy/dispose helpers: 825*67e74705SXin Li 826*67e74705SXin Li.. code-block:: c++ 827*67e74705SXin Li 828*67e74705SXin Li void _block_byref_obj_keep(struct _block_byref_blockStorageFoo *dst, struct _block_byref_blockStorageFoo *src) { 829*67e74705SXin Li FOO_ctor(&dst->blockStorageFoo, &src->blockStorageFoo); 830*67e74705SXin Li } 831*67e74705SXin Li 832*67e74705SXin Li void _block_byref_obj_dispose(struct _block_byref_blockStorageFoo *src) { 833*67e74705SXin Li FOO_dtor(&src->blockStorageFoo); 834*67e74705SXin Li } 835*67e74705SXin Li 836*67e74705SXin Lifor the appropriately named constructor and destructor for the class/struct 837*67e74705SXin Li``FOO``. 838*67e74705SXin Li 839*67e74705SXin LiTo support member variable and function access the compiler will synthesize a 840*67e74705SXin Li``const`` pointer to a block version of the ``this`` pointer. 841*67e74705SXin Li 842*67e74705SXin Li.. _RuntimeHelperFunctions: 843*67e74705SXin Li 844*67e74705SXin LiRuntime Helper Functions 845*67e74705SXin Li======================== 846*67e74705SXin Li 847*67e74705SXin LiThe runtime helper functions are described in 848*67e74705SXin Li``/usr/local/include/Block_private.h``. To summarize their use, a ``Block`` 849*67e74705SXin Lirequires copy/dispose helpers if it imports any block variables, ``__block`` 850*67e74705SXin Listorage variables, ``__attribute__((NSObject))`` variables, or C++ ``const`` 851*67e74705SXin Licopied objects with constructor/destructors. The (1<<26) bit is set and 852*67e74705SXin Lifunctions are generated. 853*67e74705SXin Li 854*67e74705SXin LiThe block copy helper function should, for each of the variables of the type 855*67e74705SXin Limentioned above, call: 856*67e74705SXin Li 857*67e74705SXin Li.. code-block:: c 858*67e74705SXin Li 859*67e74705SXin Li _Block_object_assign(&dst->target, src->target, BLOCK_FIELD_<appropo>); 860*67e74705SXin Li 861*67e74705SXin Liin the copy helper and: 862*67e74705SXin Li 863*67e74705SXin Li.. code-block:: c 864*67e74705SXin Li 865*67e74705SXin Li _Block_object_dispose(->target, BLOCK_FIELD_<appropo>); 866*67e74705SXin Li 867*67e74705SXin Liin the dispose helper where ``<appropo>`` is: 868*67e74705SXin Li 869*67e74705SXin Li.. code-block:: c 870*67e74705SXin Li 871*67e74705SXin Li enum { 872*67e74705SXin Li BLOCK_FIELD_IS_OBJECT = 3, // id, NSObject, __attribute__((NSObject)), block, ... 873*67e74705SXin Li BLOCK_FIELD_IS_BLOCK = 7, // a block variable 874*67e74705SXin Li BLOCK_FIELD_IS_BYREF = 8, // the on stack structure holding the __block variable 875*67e74705SXin Li 876*67e74705SXin Li BLOCK_FIELD_IS_WEAK = 16, // declared __weak 877*67e74705SXin Li 878*67e74705SXin Li BLOCK_BYREF_CALLER = 128, // called from byref copy/dispose helpers 879*67e74705SXin Li }; 880*67e74705SXin Li 881*67e74705SXin Liand of course the constructors/destructors for ``const`` copied C++ objects. 882*67e74705SXin Li 883*67e74705SXin LiThe ``block_byref`` data structure similarly requires copy/dispose helpers for 884*67e74705SXin Liblock variables, ``__attribute__((NSObject))`` variables, or C++ ``const`` 885*67e74705SXin Licopied objects with constructor/destructors, and again the (1<<26) bit is set 886*67e74705SXin Liand functions are generated in the same manner. 887*67e74705SXin Li 888*67e74705SXin LiUnder ObjC we allow ``__weak`` as an attribute on ``__block`` variables, and 889*67e74705SXin Lithis causes the addition of ``BLOCK_FIELD_IS_WEAK`` orred onto the 890*67e74705SXin Li``BLOCK_FIELD_IS_BYREF`` flag when copying the ``block_byref`` structure in the 891*67e74705SXin Li``Block`` copy helper, and onto the ``BLOCK_FIELD_<appropo>`` field within the 892*67e74705SXin Li``block_byref`` copy/dispose helper calls. 893*67e74705SXin Li 894*67e74705SXin LiThe prototypes, and summary, of the helper functions are: 895*67e74705SXin Li 896*67e74705SXin Li.. code-block:: c 897*67e74705SXin Li 898*67e74705SXin Li /* Certain field types require runtime assistance when being copied to the 899*67e74705SXin Li heap. The following function is used to copy fields of types: blocks, 900*67e74705SXin Li pointers to byref structures, and objects (including 901*67e74705SXin Li __attribute__((NSObject)) pointers. BLOCK_FIELD_IS_WEAK is orthogonal to 902*67e74705SXin Li the other choices which are mutually exclusive. Only in a Block copy 903*67e74705SXin Li helper will one see BLOCK_FIELD_IS_BYREF. 904*67e74705SXin Li */ 905*67e74705SXin Li void _Block_object_assign(void *destAddr, const void *object, const int flags); 906*67e74705SXin Li 907*67e74705SXin Li /* Similarly a compiler generated dispose helper needs to call back for each 908*67e74705SXin Li field of the byref data structure. (Currently the implementation only 909*67e74705SXin Li packs one field into the byref structure but in principle there could be 910*67e74705SXin Li more). The same flags used in the copy helper should be used for each 911*67e74705SXin Li call generated to this function: 912*67e74705SXin Li */ 913*67e74705SXin Li void _Block_object_dispose(const void *object, const int flags); 914*67e74705SXin Li 915*67e74705SXin LiCopyright 916*67e74705SXin Li========= 917*67e74705SXin Li 918*67e74705SXin LiCopyright 2008-2010 Apple, Inc. 919*67e74705SXin LiPermission is hereby granted, free of charge, to any person obtaining a copy 920*67e74705SXin Liof this software and associated documentation files (the "Software"), to deal 921*67e74705SXin Liin the Software without restriction, including without limitation the rights 922*67e74705SXin Lito use, copy, modify, merge, publish, distribute, sublicense, and/or sell 923*67e74705SXin Licopies of the Software, and to permit persons to whom the Software is 924*67e74705SXin Lifurnished to do so, subject to the following conditions: 925*67e74705SXin Li 926*67e74705SXin LiThe above copyright notice and this permission notice shall be included in 927*67e74705SXin Liall copies or substantial portions of the Software. 928*67e74705SXin Li 929*67e74705SXin LiTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 930*67e74705SXin LiIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 931*67e74705SXin LiFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 932*67e74705SXin LiAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 933*67e74705SXin LiLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 934*67e74705SXin LiOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 935*67e74705SXin LiTHE SOFTWARE. 936