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