summaryrefslogtreecommitdiffstats
path: root/docs/Block-ABI-Apple.txt
diff options
context:
space:
mode:
Diffstat (limited to 'docs/Block-ABI-Apple.txt')
-rw-r--r--docs/Block-ABI-Apple.txt78
1 files changed, 39 insertions, 39 deletions
diff --git a/docs/Block-ABI-Apple.txt b/docs/Block-ABI-Apple.txt
index dd12036..4a97aa9 100644
--- a/docs/Block-ABI-Apple.txt
+++ b/docs/Block-ABI-Apple.txt
@@ -67,19 +67,21 @@ enum {
BLOCK_HAS_COPY_DISPOSE = (1 << 25),
BLOCK_HAS_CTOR = (1 << 26), // helpers have C++ code
BLOCK_IS_GLOBAL = (1 << 28),
- BLOCK_HAS_STRET = (1 << 29),
+ BLOCK_HAS_STRET = (1 << 29), // IFF BLOCK_HAS_SIGNATURE
BLOCK_HAS_SIGNATURE = (1 << 30),
};
-In 10.6.ABI the (1<<29) was unconditionally set and ignored by the runtime - it was a transitional marker that did not get deleted after the transition. This bit is now paired with (1<<30), and represented as the pair (3<<30), for the following combinations of valid bit settings, and their meanings.
+In 10.6.ABI the (1<<29) was usually set and was always ignored by the runtime - it had been a transitional marker that did not get deleted after the transition. This bit is now paired with (1<<30), and represented as the pair (3<<30), for the following combinations of valid bit settings, and their meanings.
switch (flags & (3<<29)) {
- case (0<<29): <unused> , error
+ case (0<<29): 10.6.ABI, no signature field available
case (1<<29): 10.6.ABI, no signature field available
case (2<<29): ABI.2010.3.16, regular calling convention, presence of signature field
case (3<<29): ABI.2010.3.16, stret calling convention, presence of signature field,
}
+The signature field is not always populated.
+
The following discussions are presented as 10.6.ABI otherwise.
Block literals may occur within functions where the structure is created in stack local memory. They may also appear as initialization expressions for Block variables of global or static local variables.
@@ -348,7 +350,7 @@ void _block_byref_dispose_helper(struct _block_byref_voidBlock *param) {
and
struct _block_byref_voidBlock voidBlock = {( .forwarding=&voidBlock, .flags=(1<<25), .size=sizeof(struct _block_byref_voidBlock *),
.byref_keep=_block_byref_keep_helper, .byref_dispose=_block_byref_dispose_helper,
- .captured_voidBlock=blockA };
+ .captured_voidBlock=blockA )};
voidBlock.forwarding->captured_voidBlock = blockB;
@@ -422,7 +424,9 @@ A __block variable that is also marked __attribute__((NSObject)) should have byr
2.3.5 __block escapes
-Because Blocks referencing __block variables may have Block_copy() performed upon them the underlying storage for the variables may move to the heap. In Objective-C Garbage Collection Only compilation environments the heap used is the garbage collected one and no further action is required. Otherwise the compiler must issue a call to potentially release any heap storage for __block variables at all escapes or terminations of their scope.
+Because Blocks referencing __block variables may have Block_copy() performed upon them the underlying storage for the variables may move to the heap. In Objective-C Garbage Collection Only compilation environments the heap used is the garbage collected one and no further action is required. Otherwise the compiler must issue a call to potentially release any heap storage for __block variables at all escapes or terminations of their scope. The call should be:
+
+ _Block_object_dispose(&_block_byref_xxx, BLOCK_FIELD_IS_BYREF);
2.3.6 Nesting
@@ -537,9 +541,9 @@ and within the compound statement:
4.0 C++ Support
-Within a block stack based C++ objects are copied as const copies using the const copy constructor. It is an error if a stack based C++ object is used within a block if it does not have a const copy constructor. In addition both copy and destroy helper routines must be synthesized for the block to support the Block_copy() operation, and the flags work marked with the (1<<26) bit in addition to the (1<<25) bit. The copy helper should call the constructor using appropriate offsets of the variable within the supplied stack based block source and heap based destination for all const constructed copies, and similarly should call the destructor in the destroy routine.
+Within a block stack based C++ objects are copied into const copies using the copy constructor. It is an error if a stack based C++ object is used within a block if it does not have a copy constructor. In addition both copy and destroy helper routines must be synthesized for the block to support the Block_copy() operation, and the flags work marked with the (1<<26) bit in addition to the (1<<25) bit. The copy helper should call the constructor using appropriate offsets of the variable within the supplied stack based block source and heap based destination for all const constructed copies, and similarly should call the destructor in the destroy routine.
-As an example, suppose a C++ class FOO existed with a const copy constructor. Within a code block a stack version of a FOO object is declared and used within a Block literal expression:
+As an example, suppose a C++ class FOO existed with a copy constructor. Within a code block a stack version of a FOO object is declared and used within a Block literal expression:
{
FOO foo;
@@ -562,11 +566,11 @@ void __block_invoke_10(struct __block_literal_10 *_block) {
}
void __block_literal_10(struct __block_literal_10 *dst, struct __block_literal_10 *src) {
- comp_ctor(&dst->foo, &src->foo);
+ FOO_ctor(&dst->foo, &src->foo);
}
void __block_dispose_10(struct __block_literal_10 *src) {
- comp_dtor(&src->foo);
+ FOO_dtor(&src->foo);
}
static struct __block_descriptor_10 {
@@ -594,9 +598,33 @@ and the code would be:
}
-C++ objects stored in __block storage start out on the stack in a block_byref data structure as do other variables. Such objects (if not const objects) must support a regular copy constructor. The block_byref data structure will have copy and destroy helper routines synthesized by the compiler. The copy helper will have code created to perform the copy constructor based on the initial stack block_byref data structure, and will also set the (1<<26) bit in addition to the (1<<25) bit. The destroy helper will have code to do the destructor on the object stored within the supplied block_byref heap data structure.
+C++ objects stored in __block storage start out on the stack in a block_byref data structure as do other variables. Such objects (if not const objects) must support a regular copy constructor. The block_byref data structure will have copy and destroy helper routines synthesized by the compiler. The copy helper will have code created to perform the copy constructor based on the initial stack block_byref data structure, and will also set the (1<<26) bit in addition to the (1<<25) bit. The destroy helper will have code to do the destructor on the object stored within the supplied block_byref heap data structure. For example,
+
+ __block FOO blockStorageFoo;
+
+requires the normal constructor for the embedded blockStorageFoo object
+
+ FOO_ctor(& _block_byref_blockStorageFoo->blockStorageFoo);
+
+and at scope termination the destructor:
+
+ FOO_dtor(& _block_byref_blockStorageFoo->blockStorageFoo);
+
+Note that the forwarding indirection is NOT used.
+
+The compiler would need to generate (if used from a block literal) the following copy/dispose helpers:
+
+void _block_byref_obj_keep(struct _block_byref_blockStorageFoo *dst, struct _block_byref_blockStorageFoo *src) {
+ FOO_ctor(&dst->blockStorageFoo, &src->blockStorageFoo);
+}
+
+void _block_byref_obj_dispose(struct _block_byref_blockStorageFoo *src) {
+ FOO_dtor(&src->blockStorageFoo);
+}
+
+for the appropriately named constructor and destructor for the class/struct FOO.
-To support member variable and function access the compiler will synthesize a const pointer to a block version of the this pointer.
+To support member variable and function access the compiler will synthesize a const pointer to a block version of the "this" pointer.
5.0 Runtime Helper Functions
@@ -640,31 +668,3 @@ void _Block_object_assign(void *destAddr, const void *object, const int flags);
*/
void _Block_object_dispose(const void *object, const int flags);
-The following functions have been used and will continue to be supported until new compiler support is complete.
-
-// Obsolete functions.
-// Copy helper callback for copying a block imported into a Block
-// Called by copy_helper helper functions synthesized by the compiler.
-// The address in the destination block of an imported Block is provided as the first argument
-// and the value of the existing imported Block is the second.
-// Use: _Block_object_assign(dest, src, BLOCK_FIELD_IS_BLOCK {| BLOCK_FIELD_IS_WEAK});
-void _Block_copy_assign(struct Block_basic **dest, const struct Block_basic *src, const int flags);
-
-// Destroy helper callback for releasing Blocks imported into a Block
-// Called by dispose_helper helper functions synthesized by the compiler.
-// The value of the imported Block variable is passed back.
-// Use: _Block_object_dispose(src, BLOCK_FIELD_IS_BLOCK {| BLOCK_FIELD_IS_WEAK});
-void _Block_destroy(const struct Block_basic *src, const int flags);
-
-// Byref data block copy helper callback
-// Called by block copy helpers when copying __block structures
-// Use: _Block_object_assign(dest, src, BLOCK_FIELD_IS_BYREF {| BLOCK_FIELD_IS_WEAK});
-void _Block_byref_assign_copy(struct Block_byref **destp, struct Block_byref *src);
-
-// Byref data block release helper callback
-// Called by block release helpers when releasing a Block
-// Called at escape points in scope where __block variables live (under non-GC-only conditions)
-// Use: _Block_object_dispose(src, BLOCK_FIELD_IS_BYREF {| BLOCK_FIELD_IS_WEAK});
-void §(struct Block_byref *shared_struct);
-
-
OpenPOWER on IntegriCloud