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