]> granicus.if.org Git - clang/commitdiff
rev existing doc to account for recent ABI changes
authorBlaine Garst <blaine@apple.com>
Tue, 16 Mar 2010 21:21:07 +0000 (21:21 +0000)
committerBlaine Garst <blaine@apple.com>
Tue, 16 Mar 2010 21:21:07 +0000 (21:21 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@98676 91177308-0d34-0410-b5e6-96231b3b80d8

docs/BlockImplementation.txt

index c420455979cf3a35419a3eb0a45c1c21cbc479e2..4017c2ded19404cdf997e1a06f3b239a0698f3fa 100644 (file)
@@ -30,10 +30,17 @@ THE SOFTWARE.
 2008/10/30 - revise new layout to have invoke function in same place
 2008/10/30 - add __weak support
 
+2010/3/16  - rev for stret return, signature field
+
 This document describes the Apple ABI implementation specification of Blocks.
 
+The first shipping version of this ABI is found in Mac OS X 10.6, and shall be referred to as 10.6.ABI. Proposals have been made to enhance the blocks compiler and runtime, and these changes would form a new ABI called post-10.6.ABI if these changes were ever shipped in a product, which is purely speculative.
+
+Since the Apple ABI references symbols from other elements of the system, any attempt to use this ABI on systems prior to SnowLeopard is undefined.
+
 1. High Level
 
+The ABI of blocks consist of their layout and the runtime functions required by the compiler.
 A Block consists of a structure of the following form:
 
 struct Block_literal_1 {
@@ -43,23 +50,37 @@ struct Block_literal_1 {
     void (*invoke)(void *, ...);
     struct Block_descriptor_1 {
        unsigned long int reserved;     // NULL
-       unsigned long int size;  // sizeof(struct Block_literal_1)
+       unsigned long int size;         // sizeof(struct Block_literal_1)
        // optional helper functions
-       void (*copy_helper)(void *dst, void *src);
-       void (*dispose_helper)(void *src); 
+       void (*copy_helper)(void *dst, void *src);     // IFF (1<<25)
+       void (*dispose_helper)(void *src);             // IFF (1<<25)
+        // required post 10.6.ABI
+        const char *signature;                         // IFF (1<<30)
     } *descriptor;
     // imported variables
 };
 
-The following flags bits are used by the compiler:
+The following flags bits are in use thusly for a possible post.10.6.ABI:
 
 enum {
     BLOCK_HAS_COPY_DISPOSE =  (1 << 25),
     BLOCK_HAS_CTOR =          (1 << 26), // helpers have C++ code
     BLOCK_IS_GLOBAL =         (1 << 28),
-    BLOCK_HAS_DESCRIPTOR =    (1 << 29), // interim until complete world build is accomplished
+    BLOCK_HAS_STRET =         (1 << 29),
+    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.
+
+switch (flags & (3<<29)) {
+  case (0<<29):  <unused>    , error
+  case (1<<29):      10.6.ABI, no signature field available
+  case (2<<29): post-10.6.ABI, regular calling convention, presence of signature field
+  case (3<<29): post-10.6.ABI, street calling convention, presence of signature field,
+}
+
+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.
 
 When a Block literal expression is evaluated the stack based structure is initialized as follows:
@@ -72,6 +93,7 @@ When a Block literal expression is evaluated the stack based structure is initia
 2a) the isa field is set to the address of the external _NSConcreteStackBlock, which is a block of uninitialized memory supplied in libSystem, or _NSConcreteGlobalBlock if this is a static or file level block literal.
 2) The flags field is set to zero unless there are variables imported into the block that need helper functions for program level Block_copy() and Block_release() operations, in which case the (1<<25) flags bit is set.
 
+
 As an example, the Block literal expression
    ^ { printf("hello world\n"); }
 would cause to be created on a 32-bit system: