libclosure-67

This commit is contained in:
Lubos Dolezel 2017-01-28 18:22:47 +01:00
commit 728c70f617
131 changed files with 16116 additions and 0 deletions

64
Block.h Normal file
View File

@ -0,0 +1,64 @@
/*
* Block.h
*
* Copyright (c) 2008-2010 Apple Inc. All rights reserved.
*
* @APPLE_LLVM_LICENSE_HEADER@
*
*/
#ifndef _Block_H_
#define _Block_H_
#if !defined(BLOCK_EXPORT)
# if defined(__cplusplus)
# define BLOCK_EXPORT extern "C"
# else
# define BLOCK_EXPORT extern
# endif
#endif
#include <Availability.h>
#include <TargetConditionals.h>
#if __cplusplus
extern "C" {
#endif
// Create a heap based copy of a Block or simply add a reference to an existing one.
// This must be paired with Block_release to recover memory, even when running
// under Objective-C Garbage Collection.
BLOCK_EXPORT void *_Block_copy(const void *aBlock)
__OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2);
// Lose the reference, and if heap based and last reference, recover the memory
BLOCK_EXPORT void _Block_release(const void *aBlock)
__OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2);
// Used by the compiler. Do not call this function yourself.
BLOCK_EXPORT void _Block_object_assign(void *, const void *, const int)
__OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2);
// Used by the compiler. Do not call this function yourself.
BLOCK_EXPORT void _Block_object_dispose(const void *, const int)
__OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2);
// Used by the compiler. Do not use these variables yourself.
BLOCK_EXPORT void * _NSConcreteGlobalBlock[32]
__OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2);
BLOCK_EXPORT void * _NSConcreteStackBlock[32]
__OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2);
#if __cplusplus
}
#endif
// Type correct macros
#define Block_copy(...) ((__typeof(__VA_ARGS__))_Block_copy((const void *)(__VA_ARGS__)))
#define Block_release(...) _Block_release((const void *)(__VA_ARGS__))
#endif

623
BlockImplementation.txt Normal file
View File

@ -0,0 +1,623 @@
Block Implementation Specification
Copyright 2008-2009 Apple, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
0. History
2008/7/14 - created
2008/8/21 - revised, C++
2008/9/24 - add NULL isa field to __block storage
2008/10/1 - revise block layout to use a static descriptor structure
2008/10/6 - revise block layout to use an unsigned long int flags
2008/10/28 - specify use of _Block_object_assign/dispose for all "Object" types in helper functions
2008/10/30 - revise new layout to have invoke function in same place
2008/10/30 - add __weak support
This document describes the Apple ABI implementation specification of Blocks.
1. High Level
A Block consists of a structure of the following form:
struct Block_literal_1 {
void *isa; // initialized to &_NSConcreteStackBlock or &_NSConcreteGlobalBlock
int flags;
int reserved;
void (*invoke)(void *, ...);
struct Block_descriptor_1 {
unsigned long int reserved; // NULL
unsigned long int size; // sizeof(struct Block_literal_1)
// optional helper functions
void (*copy_helper)(void *dst, void *src);
void (*dispose_helper)(void *src);
} *descriptor;
// imported variables
};
The following flags bits are used by the compiler:
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 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:
1) static descriptor structure is declared and initialized as follows:
1a) the invoke function pointer is set to a function that takes the Block structure as its first argument and the rest of the arguments (if any) to the Block and executes the Block compound statement.
1b) the size field is set to the size of the following Block literal structure.
1c) the copy_helper and dispose_helper function pointers are set to respective helper functions if they are required by the Block literal
2) a stack (or global) Block literal data structure is created and initialized as follows:
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:
struct __block_literal_1 {
void *isa;
int flags;
int reserved;
void (*invoke)(struct __block_literal_1 *);
struct __block_descriptor_1 *descriptor;
};
void __block_invoke_1(struct __block_literal_1 *_block) {
printf("hello world\n");
}
static struct __block_descriptor_1 {
unsigned long int reserved;
unsigned long int Block_size;
} __block_descriptor_1 = { 0, sizeof(struct __block_literal_1), __block_invoke_1 };
and where the block literal appeared
struct __block_literal_1 _block_literal = {
&_NSConcreteStackBlock,
(1<<29), <uninitialized>,
__block_invoke_1,
&__block_descriptor_1
};
Blocks import other Block references, const copies of other variables, and variables marked __block. In Objective-C variables may additionally be objects.
When a Block literal expression used as the initial value of a global or static local variable it is initialized as follows:
struct __block_literal_1 __block_literal_1 = {
&_NSConcreteGlobalBlock,
(1<<28)|(1<<29), <uninitialized>,
__block_invoke_1,
&__block_descriptor_1
};
that is, a different address is provided as the first value and a particular (1<<28) bit is set in the flags field, and otherwise it is the same as for stack based Block literals. This is an optimization that can be used for any Block literal that imports no const or __block storage variables.
2. Imported Variables
Variables of "auto" storage class are imported as const copies. Variables of "__block" storage class are imported as a pointer to an enclosing data structure. Global variables are simply referenced and not considered as imported.
2.1 Imported const copy variables
Automatic storage variables not marked with __block are imported as const copies.
The simplest example is that of importing a variable of type int.
int x = 10;
void (^vv)(void) = ^{ printf("x is %d\n", x); }
x = 11;
vv();
would be compiled
struct __block_literal_2 {
void *isa;
int flags;
int reserved;
void (*invoke)(struct __block_literal_2 *);
struct __block_descriptor_2 *descriptor;
const int x;
};
void __block_invoke_2(struct __block_literal_2 *_block) {
printf("x is %d\n", _block->x);
}
static struct __block_descriptor_2 {
unsigned long int reserved;
unsigned long int Block_size;
} __block_descriptor_2 = { 0, sizeof(struct __block_literal_2) };
and
struct __block_literal_2 __block_literal_2 = {
&_NSConcreteStackBlock,
(1<<29), <uninitialized>,
__block_invoke_2,
&__block_descriptor_2,
x
};
In summary, scalars, structures, unions, and function pointers are generally imported as const copies with no need for helper functions.
2.2 Imported const copy of Block reference
The first case where copy and dispose helper functions are required is for the case of when a block itself is imported. In this case both a copy_helper function and a dispose_helper function are needed. The copy_helper function is passed both the existing stack based pointer and the pointer to the new heap version and should call back into the runtime to actually do the copy operation on the imported fields within the block. The runtime functions are all described in Section 5.0 Runtime Helper Functions.
An example:
void (^existingBlock)(void) = ...;
void (^vv)(void) = ^{ existingBlock(); }
vv();
struct __block_literal_3 {
...; // existing block
};
struct __block_literal_4 {
void *isa;
int flags;
int reserved;
void (*invoke)(struct __block_literal_4 *);
struct __block_literal_3 *const existingBlock;
};
void __block_invoke_4(struct __block_literal_2 *_block) {
__block->existingBlock->invoke(__block->existingBlock);
}
void __block_copy_4(struct __block_literal_4 *dst, struct __block_literal_4 *src) {
//_Block_copy_assign(&dst->existingBlock, src->existingBlock, 0);
_Block_object_assign(&dst->existingBlock, src->existingBlock, BLOCK_FIELD_IS_BLOCK);
}
void __block_dispose_4(struct __block_literal_4 *src) {
// was _Block_destroy
_Block_object_dispose(src->existingBlock, BLOCK_FIELD_IS_BLOCK);
}
static struct __block_descriptor_4 {
unsigned long int reserved;
unsigned long int Block_size;
void (*copy_helper)(struct __block_literal_4 *dst, struct __block_literal_4 *src);
void (*dispose_helper)(struct __block_literal_4 *);
} __block_descriptor_4 = {
0,
sizeof(struct __block_literal_4),
__block_copy_4,
__block_dispose_4,
};
and where it is used
struct __block_literal_4 _block_literal = {
&_NSConcreteStackBlock,
(1<<25)|(1<<29), <uninitialized>
__block_invoke_4,
& __block_descriptor_4,
existingBlock,
};
2.2.1 Importing __attribute__((NSObject)) variables.
GCC introduces __attribute__((NSObject)) on structure pointers to mean "this is an object". This is useful because many low level data structures are declared as opaque structure pointers, e.g. CFStringRef, CFArrayRef, etc. When used from C, however, these are still really objects and are the second case where that requires copy and dispose helper functions to be generated. The copy helper functions generated by the compiler should use the _Block_object_assign runtime helper function and in the dispose helper the _Block_object_dispose runtime helper function should be called.
For example, block xyzzy in the following
struct Opaque *__attribute__((NSObject)) objectPointer = ...;
...
void (^xyzzy)(void) = ^{ CFPrint(objectPointer); };
would have helper functions
void __block_copy_xyzzy(struct __block_literal_5 *dst, struct __block_literal_5 *src) {
_Block_object_assign(&dst->objectPointer, src-> objectPointer, BLOCK_FIELD_IS_OBJECT);
}
void __block_dispose_xyzzy(struct __block_literal_5 *src) {
_Block_object_dispose(src->objectPointer, BLOCK_FIELD_IS_OBJECT);
}
generated.
2.3 Imported __block marked variables.
2.3.1 Layout of __block marked variables
The compiler must embed variables that are marked __block in a specialized structure of the form:
struct _block_byref_xxxx {
void *isa;
struct Block_byref *forwarding;
int flags; //refcount;
int size;
typeof(marked_variable) marked_variable;
};
Variables of certain types require helper functions for when Block_copy() and Block_release() are performed upon a referencing Block. At the "C" level only variables that are of type Block or ones that have __attribute__((NSObject)) marked require helper functions. In Objective-C objects require helper functions and in C++ stack based objects require helper functions. Variables that require helper functions use the form:
struct _block_byref_xxxx {
void *isa;
struct _block_byref_xxxx *forwarding;
int flags; //refcount;
int size;
// helper functions called via Block_copy() and Block_release()
void (*byref_keep)(void *dst, void *src);
void (*byref_dispose)(void *);
typeof(marked_variable) marked_variable;
};
The structure is initialized such that
a) the forwarding pointer is set to the beginning of its enclosing structure,
b) the size field is initialized to the total size of the enclosing structure,
c) the flags field is set to either 0 if no helper functions are needed or (1<<25) if they are,
d) the helper functions are initialized (if present)
e) the variable itself is set to its initial value.
f) the isa field is set to NULL
2.3.2 Access to __block variables from within its lexical scope.
In order to "move" the variable to the heap upon a copy_helper operation the compiler must rewrite access to such a variable to be indirect through the structures forwarding pointer. For example:
int __block i = 10;
i = 11;
would be rewritten to be:
struct _block_byref_i {
void *isa;
struct _block_byref_i *forwarding;
int flags; //refcount;
int size;
int captured_i;
} i = { NULL, &i, 0, sizeof(struct _block_byref_i), 10 };
({ int tmp = 11; i.forwarding->captured_i = tmp; });
The use of the tmp intermediary is necessary to avoid cases where the expression might cause the __block variable to be moved to the heap and the forwarding pointer updated after it was loaded. Expressions not including Blocks referencing the __block variable may be optimized to avoid the temporary.
In the case of a Block reference variable being marked __block the helper code generated must use the _Block_object_assign and _Block_object_dispose routines supplied by the runtime to make the copies. For example:
__block void (voidBlock)(void) = blockA;
voidBlock = blockB;
would translate into
struct _block_byref_voidBlock {
void *isa;
struct _block_byref_voidBlock *forwarding;
int flags; //refcount;
int size;
void (*byref_keep)(struct _block_byref_voidBlock *dst, struct _block_byref_voidBlock *src);
void (*byref_dispose)(struct _block_byref_voidBlock *);
void (^captured_voidBlock)(void);
};
void _block_byref_keep_helper(struct _block_byref_voidBlock *dst, struct _block_byref_voidBlock *src) {
//_Block_copy_assign(&dst->captured_voidBlock, src->captured_voidBlock, 0);
_Block_object_assign(&dst->captured_voidBlock, src->captured_voidBlock, BLOCK_FIELD_IS_BLOCK | BLOCK_BYREF_CALLER);
}
void _block_byref_dispose_helper(struct _block_byref_voidBlock *param) {
//_Block_destroy(param->captured_voidBlock, 0);
_Block_object_dispose(param->captured_voidBlock, BLOCK_FIELD_IS_BLOCK | BLOCK_BYREF_CALLER)}
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 )};
voidBlock.forwarding->captured_voidBlock = blockB;
2.3.3 Importing __block variables into Blocks
A Block that uses a __block variable in its compound statement body must import the variable and emit copy_helper and dispose_helper helper functions that, in turn, call back into the runtime to actually copy or release the byref data block using the functions _Block_object_assign and _Block_object_dispose.
For example:
int __block i = 2;
functioncall(^{ i = 10; });
would translate to
struct _block_byref_i {
void *isa;
struct _block_byref_voidBlock *forwarding;
int flags; //refcount;
int size;
void (*byref_keep)(struct _block_byref_i *dst, struct _block_byref_i *src);
void (*byref_dispose)(struct _block_byref_i *);
int captured_i;
};
struct __block_literal_5 {
void *isa;
int flags;
int reserved;
void (*invoke)(struct __block_literal_5 *);
struct __block_descriptor_5 *descriptor;
struct _block_byref_i *i_holder;
};
void __block_invoke_5(struct __block_literal_5 *_block) {
_block->forwarding->captured_i = 10;
}
void __block_copy_5(struct __block_literal_5 *dst, struct __block_literal_5 *src) {
//_Block_byref_assign_copy(&dst->captured_i, src->captured_i);
_Block_object_assign(&dst->captured_i, src->captured_i, BLOCK_FIELD_IS_BYREF | BLOCK_BYREF_CALLER);
}
void __block_dispose_5(struct __block_literal_5 *src) {
//_Block_byref_release(src->captured_i);
_Block_object_dispose(src->captured_i, BLOCK_FIELD_IS_BYREF | BLOCK_BYREF_CALLER);
}
static struct __block_descriptor_5 {
unsigned long int reserved;
unsigned long int Block_size;
void (*copy_helper)(struct __block_literal_5 *dst, struct __block_literal_5 *src);
void (*dispose_helper)(struct __block_literal_5 *);
} __block_descriptor_5 = { 0, sizeof(struct __block_literal_5) __block_copy_5, __block_dispose_5 };
and
struct _block_byref_i i = {( .forwarding=&i, .flags=0, .size=sizeof(struct _block_byref_i) )};
struct __block_literal_5 _block_literal = {
&_NSConcreteStackBlock,
(1<<25)|(1<<29), <uninitialized>,
__block_invoke_5,
&__block_descriptor_5,
2,
};
2.3.4 Importing __attribute__((NSObject)) __block variables
A __block variable that is also marked __attribute__((NSObject)) should have byref_keep and byref_dispose helper functions that use _Block_object_assign and _Block_object_dispose.
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. The call should be:
_Block_object_dispose(&_block_byref_xxx, BLOCK_FIELD_IS_BYREF);
2.3.6 Nesting
Blocks may contain Block literal expressions. Any variables used within inner blocks are imported into all enclosing Block scopes even if the variables are not used. This includes const imports as well as __block variables.
3. Objective C Extensions to Blocks
3.1 Importing Objects
Objects should be treated as __attribute__((NSObject)) variables; all copy_helper, dispose_helper, byref_keep, and byref_dispose helper functions should use _Block_object_assign and _Block_object_dispose. There should be no code generated that uses -retain or -release methods.
3.2 Blocks as Objects
The compiler will treat Blocks as objects when synthesizing property setters and getters, will characterize them as objects when generating garbage collection strong and weak layout information in the same manner as objects, and will issue strong and weak write-barrier assignments in the same manner as objects.
3.3 __weak __block Support
Objective-C (and Objective-C++) support the __weak attribute on __block variables. Under normal circumstances the compiler uses the Objective-C runtime helper support functions objc_assign_weak and objc_read_weak. Both should continue to be used for all reads and writes of __weak __block variables:
objc_read_weak(&block->byref_i->forwarding->i)
The __weak variable is stored in a _block_byref_xxxx structure and the Block has copy and dispose helpers for this structure that call:
_Block_object_assign(&dest->_block_byref_i, src-> _block_byref_i, BLOCK_FIELD_IS_WEAK | BLOCK_FIELD_IS_BYREF);
and
_Block_object_dispose(src->_block_byref_i, BLOCK_FIELD_IS_WEAK | BLOCK_FIELD_IS_BYREF);
In turn, the block_byref copy support helpers distinguish between whether the __block variable is a Block or not and should either call:
_Block_object_assign(&dest->_block_byref_i, src->_block_byref_i, BLOCK_FIELD_IS_WEAK | BLOCK_FIELD_IS_OBJECT | BLOCK_BYREF_CALLER);
for something declared as an object or
_Block_object_assign(&dest->_block_byref_i, src->_block_byref_i, BLOCK_FIELD_IS_WEAK | BLOCK_FIELD_IS_BLOCK | BLOCK_BYREF_CALLER);
for something declared as a Block.
A full example follows:
__block __weak id obj = <initialization expression>;
functioncall(^{ [obj somemessage]; });
would translate to
struct _block_byref_obj {
void *isa; // uninitialized
struct _block_byref_obj *forwarding;
int flags; //refcount;
int size;
void (*byref_keep)(struct _block_byref_i *dst, struct _block_byref_i *src);
void (*byref_dispose)(struct _block_byref_i *);
int captured_obj;
};
void _block_byref_obj_keep(struct _block_byref_voidBlock *dst, struct _block_byref_voidBlock *src) {
//_Block_copy_assign(&dst->captured_obj, src->captured_obj, 0);
_Block_object_assign(&dst->captured_obj, src->captured_obj, BLOCK_FIELD_IS_OBJECT | BLOCK_FIELD_IS_WEAK | BLOCK_BYREF_CALLER);
}
void _block_byref_obj_dispose(struct _block_byref_voidBlock *param) {
//_Block_destroy(param->captured_obj, 0);
_Block_object_dispose(param->captured_obj, BLOCK_FIELD_IS_OBJECT | BLOCK_FIELD_IS_WEAK | BLOCK_BYREF_CALLER);
};
for the block byref part and
struct __block_literal_5 {
void *isa;
int flags;
int reserved;
void (*invoke)(struct __block_literal_5 *);
struct __block_descriptor_5 *descriptor;
struct _block_byref_obj *byref_obj;
};
void __block_invoke_5(struct __block_literal_5 *_block) {
[objc_read_weak(&_block->byref_obj->forwarding->captured_obj) somemessage];
}
void __block_copy_5(struct __block_literal_5 *dst, struct __block_literal_5 *src) {
//_Block_byref_assign_copy(&dst->byref_obj, src->byref_obj);
_Block_object_assign(&dst->byref_obj, src->byref_obj, BLOCK_FIELD_IS_BYREF | BLOCK_FIELD_IS_WEAK);
}
void __block_dispose_5(struct __block_literal_5 *src) {
//_Block_byref_release(src->byref_obj);
_Block_object_dispose(src->byref_obj, BLOCK_FIELD_IS_BYREF | BLOCK_FIELD_IS_WEAK);
}
static struct __block_descriptor_5 {
unsigned long int reserved;
unsigned long int Block_size;
void (*copy_helper)(struct __block_literal_5 *dst, struct __block_literal_5 *src);
void (*dispose_helper)(struct __block_literal_5 *);
} __block_descriptor_5 = { 0, sizeof(struct __block_literal_5), __block_copy_5, __block_dispose_5 };
and within the compound statement:
struct _block_byref_obj obj = {( .forwarding=&obj, .flags=(1<<25), .size=sizeof(struct _block_byref_obj),
.byref_keep=_block_byref_obj_keep, .byref_dispose=_block_byref_obj_dispose,
.captured_obj = <initialization expression> )};
struct __block_literal_5 _block_literal = {
&_NSConcreteStackBlock,
(1<<25)|(1<<29), <uninitialized>,
__block_invoke_5,
&__block_descriptor_5,
&obj, // a reference to the on-stack structure containing "captured_obj"
};
functioncall(_block_literal->invoke(&_block_literal));
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.
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:
{
FOO foo;
void (^block)(void) = ^{ printf("%d\n", foo.value()); };
}
The compiler would synthesize
struct __block_literal_10 {
void *isa;
int flags;
int reserved;
void (*invoke)(struct __block_literal_10 *);
struct __block_descriptor_10 *descriptor;
const FOO foo;
};
void __block_invoke_10(struct __block_literal_10 *_block) {
printf("%d\n", _block->foo.value());
}
void __block_literal_10(struct __block_literal_10 *dst, struct __block_literal_10 *src) {
comp_ctor(&dst->foo, &src->foo);
}
void __block_dispose_10(struct __block_literal_10 *src) {
comp_dtor(&src->foo);
}
static struct __block_descriptor_10 {
unsigned long int reserved;
unsigned long int Block_size;
void (*copy_helper)(struct __block_literal_10 *dst, struct __block_literal_10 *src);
void (*dispose_helper)(struct __block_literal_10 *);
} __block_descriptor_10 = { 0, sizeof(struct __block_literal_10), __block_copy_10, __block_dispose_10 };
and the code would be:
{
FOO foo;
comp_ctor(&foo); // default constructor
struct __block_literal_10 _block_literal = {
&_NSConcreteStackBlock,
(1<<25)|(1<<26)|(1<<29), <uninitialized>,
__block_invoke_10,
&__block_descriptor_10,
};
comp_ctor(&_block_literal->foo, &foo); // const copy into stack version
struct __block_literal_10 &block = &_block_literal; // assign literal to block variable
block->invoke(block); // invoke block
comp_dtor(&_block_literal->foo); // destroy stack version of const block copy
comp_dtor(&foo); // destroy original version
}
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.
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
The runtime helper functions are described in /usr/local/include/Block_private.h. To summarize their use, a block requires copy/dispose helpers if it imports any block variables, __block storage variables, __attribute__((NSObject)) variables, or C++ const copied objects with constructor/destructors. The (1<<26) bit is set and functions are generated.
The block copy helper function should, for each of the variables of the type mentioned above, call
_Block_object_assign(&dst->target, src->target, BLOCK_FIELD_<appropo>);
in the copy helper and
_Block_object_dispose(->target, BLOCK_FIELD_<appropo>);
in the dispose helper where
<appropo> is
enum {
BLOCK_FIELD_IS_OBJECT = 3, // id, NSObject, __attribute__((NSObject)), block, ...
BLOCK_FIELD_IS_BLOCK = 7, // a block variable
BLOCK_FIELD_IS_BYREF = 8, // the on stack structure holding the __block variable
BLOCK_FIELD_IS_WEAK = 16, // declared __weak
BLOCK_BYREF_CALLER = 128, // called from byref copy/dispose helpers
};
and of course the CTORs/DTORs for const copied C++ objects.
The block_byref data structure similarly requires copy/dispose helpers for block variables, __attribute__((NSObject)) variables, or C++ const copied objects with constructor/destructors, and again the (1<<26) bit is set and functions are generated in the same manner.
Under ObjC we allow __weak as an attribute on __block variables, and this causes the addition of BLOCK_FIELD_IS_WEAK orred onto the BLOCK_FIELD_IS_BYREF flag when copying the block_byref structure in the block copy helper, and onto the BLOCK_FIELD_<appropo> field within the block_byref copy/dispose helper calls.
The prototypes, and summary, of the helper functions are
/* Certain field types require runtime assistance when being copied to the heap. The following function is used
to copy fields of types: blocks, pointers to byref structures, and objects (including __attribute__((NSObject)) pointers.
BLOCK_FIELD_IS_WEAK is orthogonal to the other choices which are mutually exclusive.
Only in a Block copy helper will one see BLOCK_FIELD_IS_BYREF.
*/
void _Block_object_assign(void *destAddr, const void *object, const int flags);
/* Similarly a compiler generated dispose helper needs to call back for each field of the byref data structure.
(Currently the implementation only packs one field into the byref structure but in principle there could be more).
The same flags used in the copy helper should be used for each call generated to this function:
*/
void _Block_object_dispose(const void *object, const int flags);

394
BlockSpec.rtf Normal file
View File

@ -0,0 +1,394 @@
{\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf430
{\fonttbl\f0\fswiss\fcharset0 Helvetica;\f1\fnil\fcharset0 Monaco;}
{\colortbl;\red255\green255\blue255;\red0\green0\blue0;}
\margl1440\margr1440\margb1800\margt1800\vieww14920\viewh16280\viewkind0
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural
\f0\fs52 \cf0 Language Specification for Blocks\
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural
\fs24 \cf0 \
2008/2/25 \'97 created\
2008/7/28 \'97 revised,
\f1\fs20 __block
\f0\fs24 syntax\
2008/8/13 \'97 revised, Block globals\
2008/8/21 \'97 revised, C++ elaboration\
2008/11/1 \'97 revised,
\f1\fs20 __weak
\f0\fs24 support\
2009/1/12 \'97 revised, explicit return types\
2009/2/10 \'97 revised, __block objects need retain\
\
\pard\pardeftab720\ql\qnatural
\cf0 Copyright 2008-2009 Apple, Inc.\'a0Permission is hereby granted, free of charge, to any person obtaining a copy\'a0of this software and associated documentation files (the "Software"), to deal\'a0in the Software without restriction, including without limitation the rights\'a0to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\'a0copies of the Software, and to permit persons to whom the Software is\'a0furnished to do so, subject to the following conditions:\
\
The above copyright notice and this permission notice shall be included in\'a0all copies or substantial portions of the Software.\
\
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\'a0\'a0IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\'a0\'a0FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\'a0\'a0AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\'a0\'a0LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\'a0OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\'a0THE SOFTWARE.\
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural
\cf0 \
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural
\b\fs28 \cf0 The Block Type\
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural
\b0\fs24 \cf0 \
A new
\i derived type
\i0 is introduced to C and, by extension, Objective-C, C++, and Objective-C++. Like function types, the Block type is a pair consisting of a result value type and a list of parameter types very similar to a function type. Blocks are intended to be used much like functions with the key distinction being that in addition to executable code they also contain various variable bindings to automatic (stack) or managed (heap) memory.\
\
The abstract declarator
\f1\fs20 int (^)(char, float)
\f0\fs24 describes a reference to a Block that, when invoked, takes two parameters, the first of type
\f1\fs20 char
\f0\fs24 and the second of type
\f1\fs20 float
\f0\fs24 , and returns a value of type
\f1\fs20 int
\f0\fs24 . The Block referenced is of opaque data that may reside in automatic (stack) memory, global memory, or heap memory.\
\
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural
\b\fs28 \cf0 \
Block Variable Declarations\
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural
\b0\fs24 \cf0 \
A variable with Block type is declared using function pointer style notation substituting
\f1\fs20 ^
\f0\fs24 for
\f1\fs20 *
\f0\fs24 . The following are valid Block variable declarations:\
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural
\f1\fs20 \cf0 void (^blockReturningVoidWithVoidArgument)(void);\
int (^blockReturningIntWithIntAndCharArguments)(int, char);\
void (^arrayOfTenBlocksReturningVoidWithIntArgument[10])(int);\
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural
\f0\fs24 \cf0 \
Variadic
\f1\fs20 ...
\f0\fs24 arguments are supported. [variadic.c] A Block that takes no arguments must specify void in the argument list [voidarg.c]. An empty parameter list does not represent, as K&R provide, an unspecified argument list. Note: both gcc and clang support K&R style as a convenience.\
\
A Block reference may be cast to a pointer of arbitrary type and vice versa. [cast.c] A Block reference may not be dereferenced via the pointer dereference operator
\f1\fs20 *
\f0\fs24 , and thus a Block's size may not be computed at compile time. [sizeof.c]\
\
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural
\b\fs28 \cf0 \
Block Literal Expressions\
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural
\b0\fs24 \cf0 \
A Block literal expression produces a reference to a Block. It is introduced by the use of the
\f1\fs20 ^
\f0\fs24 token as a unary operator. \
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural
\f1\fs20 \cf0 Block_literal_expression ::= ^ block_decl compound_statement_body\
block_decl ::= \
block_decl ::= parameter_list\
block_decl ::= type_expression\
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural
\f0\fs24 \cf0 \
...where type expression is extended to allow
\f1\fs20 ^
\f0\fs24 as a Block reference (pointer) where
\f1\fs20 *
\f0\fs24 is allowed as a function reference (pointer).\
\
The following Block literal:\
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural
\f1\fs20 \cf0 ^ void (void) \{ printf("hello world\\n"); \}\
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural
\f0\fs24 \cf0 \
...produces a reference to a Block with no arguments with no return value.\
\
The return type is optional and is inferred from the return statements. If the return statements return a value, they all must return a value of the same type. If there is no value returned the inferred type of the Block is
\f1\fs20 void
\f0\fs24 ; otherwise it is the type of the return statement value.\
\
If the return type is omitted and the argument list is
\f1\fs20 ( void )
\f0\fs24 , the
\f1\fs20 ( void )
\f0\fs24 argument list may also be omitted.\
\
So:\
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural
\f1\fs20 \cf0 ^ ( void ) \{ printf("hello world\\n"); \}\
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural
\f0\fs24 \cf0 \
...and:\
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural
\f1\fs20 \cf0 ^ \{ printf("hello world\\n"); \}\
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural
\f0\fs24 \cf0 \
...are exactly equivalent constructs for the same expression.\
\
The
\f1\fs20 type_expression
\f0\fs24 extends C expression parsing to accommodate Block reference declarations as it accommodates function pointer declarations.\
\
Given:\
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural
\f1\fs20 \cf0 typedef int (*pointerToFunctionThatReturnsIntWithCharArg)(char);\
pointerToFunctionThatReturnsIntWithCharArg functionPointer;\
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural
\f0\fs24 \cf0 \
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural
\f1\fs20 \cf0 ^ pointerToFunctionThatReturnsIntWithCharArg (float x) \{ return functionPointer; \}\
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural
\f0\fs24 \cf0 \
...and:
\f1\fs20 \
^ int ((*)(float x))(char) \{ return functionPointer; \}\
\f0\fs24 \
...are equivalent expressions, as is:\
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural
\f1\fs20 \cf0 \
^(float x) \{ return functionPointer; \}\
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural
\f0\fs24 \cf0 \
[returnfunctionptr.c]\
\
The compound statement body establishes a new lexical scope within that of its parent. Variables used within the scope of the compound statement are bound to the Block in the normal manner with the exception of those in automatic (stack) storage. Thus one may access functions and global variables as one would expect, as well as static local variables. [testme]\
\
Local
\i automatic
\i0 (stack) variables referenced within the compound statement of a Block are imported and captured by the Block as const copies. The capture (binding) is performed at the time of the Block literal expression evaluation.\
\
The lifetime of variables declared in a Block is that of a function; each activation frame contains a new copy of variables declared within the local scope of the Block. Such variable declarations should be allowed anywhere [testme] rather than only when C99 parsing is requested, including
\f1\fs20 \cf2 for
\f0\fs24 \cf0 statements. [testme]\
\
Block literal expressions may occur within Block literal expressions (nest) and all variables captured by any nested blocks are implicitly also captured in the scopes of their enclosing Blocks.\
\
A Block literal expression may be used as the initialization value for Block variables at global or local static scope.\
\
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural
\b\fs28 \cf0 \
The Invoke Operator\
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural
\b0\fs24 \cf0 \
Blocks are invoked using function call syntax with a list of expression parameters of types corresponding to the declaration and returning a result type also according to the declaration. Given:\
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural
\f1\fs20 \cf0 int (^x)(char);\
void (^z)(void);\
int (^(*y))(char) = &x;\
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural
\f0\fs24 \cf0 \
...the following are all legal Block invocations:\
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural
\f1\fs20 \cf0 x('a');\
(*y)('a');\
(true ? x : *y)('a')\
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural
\f0\fs24 \cf0 \
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural
\b\fs28 \cf0 \
The Copy and Release Operations\
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural
\b0\fs24 \cf0 \
The compiler and runtime provide copy and release operations for Block references that create and, in matched use, release allocated storage for referenced Blocks.\
\
The copy operation
\f1\fs20 Block_copy()
\f0\fs24 is styled as a function that takes an arbitrary Block reference and returns a Block reference of the same type. The release operation,
\f1\fs20 Block_release()
\f0\fs24 , is styled as a function that takes an arbitrary Block reference and, if dynamically matched to a Block copy operation, allows recovery of the referenced allocated memory.\
\
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural
\fs28 \cf0 \
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural
\b \cf0 The
\f1\b0 __block
\f0\b Storage Qualifier\
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural
\b0\fs24 \cf0 \
In addition to the new Block type we also introduce a new storage qualifier,
\f1\fs20 __block
\f0\fs24 , for local variables. [testme: a __block declaration within a block literal] The
\f1\fs20 __block
\f0\fs24 storage qualifier is mutually exclusive to the existing local storage qualifiers
\f1\fs20 auto
\f0\fs24 ,
\f1\fs20 register
\f0\fs24 , and
\f1\fs20 static
\f0\fs24 .[testme] Variables qualified by __block act as if they were in allocated storage and this storage is automatically recovered after last use of said variable. An implementation may choose an optimization where the storage is initially automatic and only "moved" to allocated (heap) storage upon a Block_copy of a referencing Block. Such variables may be mutated as normal variables are.\
\
In the case where a __block variable is a Block one must assume that the __block variable resides in allocated storage and as such is assumed to reference a Block that is also in allocated storage (that it is the result of a Block_copy operation). Despite this there is no provision to do a Block_copy or a Block_release if an implementation provides initial automatic storage for Blocks. This is due to the inherent race condition of potentially several threads trying to update the shared variable and the need for synchronization around disposing of older values and copying new ones. Such synchronization is beyond the scope of this language specification.\
\
\
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural
\b\fs28 \cf0 Control Flow\
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural
\b0 \cf0 \
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural
\fs24 \cf0 The compound statement of a Block is treated much like a function body with respect to control flow in that
\f1\fs20 goto
\f0\fs24 ,
\f1\fs20 break
\f0\fs24 , and
\f1\fs20 continue
\f0\fs24 do not escape the Block. Exceptions are treated "normally" in that when thrown they pop stack frames until a catch clause is found.\
\
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural
\b\fs28 \cf0 \
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural
\fs32 \cf0 Objective-C Extensions
\b0\fs36 \
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural
\fs24 \cf0 \
Objective-C extends the definition of a Block reference type to be that also of
\f1\fs20 id
\f0\fs24 . A variable or expression of Block type may be messaged or used as a parameter wherever an
\f1\fs20 id
\f0\fs24 may be. The converse is also true. Block references may thus appear as properties and are subject to the
\f1\fs20 assign
\f0\fs24 ,
\f1\fs20 retain
\f0\fs24 , and
\f1\fs20 copy
\f0\fs24 attribute logic that is reserved for objects.\
\
All Blocks are constructed to be Objective-C objects regardless of whether the Objective-C runtime is operational in the program or not. Blocks using automatic (stack) memory are objects and may be messaged, although they may not be assigned into
\f1\fs20 __weak
\f0\fs24 locations if garbage collection is enabled.\
\
Within a Block literal expression within a method definition references to instance variables are also imported into the lexical scope of the compound statement. These variables are implicitly qualified as references from
\f1\fs20 self
\f0\fs24 , and so
\f1\fs20 self
\f0\fs24 is imported as a const copy. The net effect is that instance variables can be mutated.\
\
The
\f1\fs20 Block_copy
\f0\fs24 operator retains all objects held in variables of automatic storage referenced within the Block expression (or form strong references if running under garbage collection). Object variables of
\f1\fs20 __block
\f0\fs24 storage type are assumed to hold normal pointers with no provision for retain and release messages.\
\
Foundation defines (and supplies)
\f1\fs20 -copy
\f0\fs24 and
\f1\fs20 -release
\f0\fs24 methods for Blocks.\
\
In the Objective-C and Objective-C++ languages, we allow the
\f1\fs20 __weak
\f0\fs24 specifier for
\f1\fs20 __block
\f0\fs24 variables of
\f1\fs20 object
\f0\fs24 type. If garbage collection is not enabled, this qualifier causes these variables to be kept without retain messages being sent. This knowingly leads to dangling pointers if the Block (or a copy) outlives the lifetime of this object.\
\
In garbage collected environments, the
\f1\fs20 __weak
\f0\fs24 variable is set to
\f1\fs20 nil
\f0\fs24 when the object it references is collected, as long as the
\f1\fs20 __block
\f0\fs24 variable resides in the heap (either by default or via
\f1\fs20 Block_copy()
\f0\fs24 ). The initial Apple implementation does in fact start
\f1\fs20 __block
\f0\fs24 variables on the stack and migrate them to the heap only as a result of a
\f1\fs20 Block_copy()
\f0\fs24 operation.\
\
It is a runtime error to attempt to assign a reference to a stack-based Block into any storage marked
\f1\fs20 __weak
\f0\fs24 , including
\f1\fs20 __weak __block
\f0\fs24 variables.\
\
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural
\b\fs28 \cf0 \
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural
\fs32 \cf0 C++ Extensions\
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural
\b0\fs24 \cf0 \
Block literal expressions within functions are extended to allow const use of C++ objects, pointers, or references held in automatic storage.\
\
For example, given class
\f1\fs20 Foo
\f0\fs24 with member function
\f1\fs20 fighter(void)
\f0\fs24 :\
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural
\f1\fs20 \cf0 Foo foo;\
Foo &fooRef = foo;\
Foo *fooPtr = &foo;\
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural
\f0\fs24 \cf0 \
...a Block that used
\f1\fs20 foo
\f0\fs24 would import the variables as const variations:\
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural
\f1\fs20 \cf0 const Foo block_foo = foo; // const copy constructor\
const Foo &block_fooRef = fooRef;\
const Foo *block_fooPtr = fooPtr;\
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural\pardirnatural
\f0\fs24 \cf0 \
Stack-local objects are copied into a Block via a copy const constructor. If no such constructor exists, it is considered an error to reference such objects from within the Block compound statements. A destructor is run as control leaves the compound statement that contains the Block literal expression.\
\
If a Block originates on the stack, a const copy constructor of the stack-based Block const copy is performed when a
\f1\fs20 Block_copy
\f0\fs24 operation is called; when the last
\f1\fs20 Block_release
\f0\fs24 (or subsequently GC) occurs, a destructor is run on the heap copy.\
\
Variables declared as residing in
\f1\fs20 __block
\f0\fs24 storage may be initially allocated in the heap or may first appear on the stack and be copied to the heap as a result of a
\f1\fs20 Block_copy()
\f0\fs24 operation. When copied from the stack, a normal copy constructor is used to initialize the heap-based version from the original stack version. The destructor for a const copied object is run at the normal end of scope. The destructor for any initial stack based version is also called at normal end of scope.\
\
Within a member function, access to member functions and variables is done via an implicit const copy of a
\f1\fs20 this
\f0\fs24 pointer.\
\
Member variables that are Blocks may not be overloaded by the types of their arguments.\
}

236
Block_private.h Normal file
View File

@ -0,0 +1,236 @@
/*
* Block_private.h
*
* SPI for Blocks
*
* Copyright (c) 2008-2010 Apple Inc. All rights reserved.
*
* @APPLE_LLVM_LICENSE_HEADER@
*
*/
#ifndef _BLOCK_PRIVATE_H_
#define _BLOCK_PRIVATE_H_
#include <Availability.h>
#include <AvailabilityMacros.h>
#include <TargetConditionals.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <Block.h>
#if __cplusplus
extern "C" {
#endif
// Values for Block_layout->flags to describe block objects
enum {
BLOCK_DEALLOCATING = (0x0001), // runtime
BLOCK_REFCOUNT_MASK = (0xfffe), // runtime
BLOCK_NEEDS_FREE = (1 << 24), // runtime
BLOCK_HAS_COPY_DISPOSE = (1 << 25), // compiler
BLOCK_HAS_CTOR = (1 << 26), // compiler: helpers have C++ code
BLOCK_IS_GC = (1 << 27), // runtime
BLOCK_IS_GLOBAL = (1 << 28), // compiler
BLOCK_USE_STRET = (1 << 29), // compiler: undefined if !BLOCK_HAS_SIGNATURE
BLOCK_HAS_SIGNATURE = (1 << 30), // compiler
BLOCK_HAS_EXTENDED_LAYOUT=(1 << 31) // compiler
};
#define BLOCK_DESCRIPTOR_1 1
struct Block_descriptor_1 {
uintptr_t reserved;
uintptr_t size;
};
#define BLOCK_DESCRIPTOR_2 1
struct Block_descriptor_2 {
// requires BLOCK_HAS_COPY_DISPOSE
void (*copy)(void *dst, const void *src);
void (*dispose)(const void *);
};
#define BLOCK_DESCRIPTOR_3 1
struct Block_descriptor_3 {
// requires BLOCK_HAS_SIGNATURE
const char *signature;
const char *layout; // contents depend on BLOCK_HAS_EXTENDED_LAYOUT
};
struct Block_layout {
void *isa;
volatile int32_t flags; // contains ref count
int32_t reserved;
void (*invoke)(void *, ...);
struct Block_descriptor_1 *descriptor;
// imported variables
};
// Values for Block_byref->flags to describe __block variables
enum {
// Byref refcount must use the same bits as Block_layout's refcount.
// BLOCK_DEALLOCATING = (0x0001), // runtime
// BLOCK_REFCOUNT_MASK = (0xfffe), // runtime
BLOCK_BYREF_LAYOUT_MASK = (0xf << 28), // compiler
BLOCK_BYREF_LAYOUT_EXTENDED = ( 1 << 28), // compiler
BLOCK_BYREF_LAYOUT_NON_OBJECT = ( 2 << 28), // compiler
BLOCK_BYREF_LAYOUT_STRONG = ( 3 << 28), // compiler
BLOCK_BYREF_LAYOUT_WEAK = ( 4 << 28), // compiler
BLOCK_BYREF_LAYOUT_UNRETAINED = ( 5 << 28), // compiler
BLOCK_BYREF_IS_GC = ( 1 << 27), // runtime
BLOCK_BYREF_HAS_COPY_DISPOSE = ( 1 << 25), // compiler
BLOCK_BYREF_NEEDS_FREE = ( 1 << 24), // runtime
};
struct Block_byref {
void *isa;
struct Block_byref *forwarding;
volatile int32_t flags; // contains ref count
uint32_t size;
};
struct Block_byref_2 {
// requires BLOCK_BYREF_HAS_COPY_DISPOSE
void (*byref_keep)(struct Block_byref *dst, struct Block_byref *src);
void (*byref_destroy)(struct Block_byref *);
};
struct Block_byref_3 {
// requires BLOCK_BYREF_LAYOUT_EXTENDED
const char *layout;
};
// Extended layout encoding.
// Values for Block_descriptor_3->layout with BLOCK_HAS_EXTENDED_LAYOUT
// and for Block_byref_3->layout with BLOCK_BYREF_LAYOUT_EXTENDED
// If the layout field is less than 0x1000, then it is a compact encoding
// of the form 0xXYZ: X strong pointers, then Y byref pointers,
// then Z weak pointers.
// If the layout field is 0x1000 or greater, it points to a
// string of layout bytes. Each byte is of the form 0xPN.
// Operator P is from the list below. Value N is a parameter for the operator.
// Byte 0x00 terminates the layout; remaining block data is non-pointer bytes.
enum {
BLOCK_LAYOUT_ESCAPE = 0, // N=0 halt, rest is non-pointer. N!=0 reserved.
BLOCK_LAYOUT_NON_OBJECT_BYTES = 1, // N bytes non-objects
BLOCK_LAYOUT_NON_OBJECT_WORDS = 2, // N words non-objects
BLOCK_LAYOUT_STRONG = 3, // N words strong pointers
BLOCK_LAYOUT_BYREF = 4, // N words byref pointers
BLOCK_LAYOUT_WEAK = 5, // N words weak pointers
BLOCK_LAYOUT_UNRETAINED = 6, // N words unretained pointers
BLOCK_LAYOUT_UNKNOWN_WORDS_7 = 7, // N words, reserved
BLOCK_LAYOUT_UNKNOWN_WORDS_8 = 8, // N words, reserved
BLOCK_LAYOUT_UNKNOWN_WORDS_9 = 9, // N words, reserved
BLOCK_LAYOUT_UNKNOWN_WORDS_A = 0xA, // N words, reserved
BLOCK_LAYOUT_UNUSED_B = 0xB, // unspecified, reserved
BLOCK_LAYOUT_UNUSED_C = 0xC, // unspecified, reserved
BLOCK_LAYOUT_UNUSED_D = 0xD, // unspecified, reserved
BLOCK_LAYOUT_UNUSED_E = 0xE, // unspecified, reserved
BLOCK_LAYOUT_UNUSED_F = 0xF, // unspecified, reserved
};
// Runtime support functions used by compiler when generating copy/dispose helpers
// Values for _Block_object_assign() and _Block_object_dispose() parameters
enum {
// see function implementation for a more complete description of these fields and combinations
BLOCK_FIELD_IS_OBJECT = 3, // id, NSObject, __attribute__((NSObject)), block, ...
BLOCK_FIELD_IS_BLOCK = 7, // a block variable
BLOCK_FIELD_IS_BYREF = 8, // the on stack structure holding the __block variable
BLOCK_FIELD_IS_WEAK = 16, // declared __weak, only used in byref copy helpers
BLOCK_BYREF_CALLER = 128, // called from __block (byref) copy/dispose support routines.
};
enum {
BLOCK_ALL_COPY_DISPOSE_FLAGS =
BLOCK_FIELD_IS_OBJECT | BLOCK_FIELD_IS_BLOCK | BLOCK_FIELD_IS_BYREF |
BLOCK_FIELD_IS_WEAK | BLOCK_BYREF_CALLER
};
// Other support functions
// runtime entry to get total size of a closure
BLOCK_EXPORT size_t Block_size(void *aBlock);
// indicates whether block was compiled with compiler that sets the ABI related metadata bits
BLOCK_EXPORT bool _Block_has_signature(void *aBlock)
__OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
// returns TRUE if return value of block is on the stack, FALSE otherwise
BLOCK_EXPORT bool _Block_use_stret(void *aBlock)
__OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
// Returns a string describing the block's parameter and return types.
// The encoding scheme is the same as Objective-C @encode.
// Returns NULL for blocks compiled with some compilers.
BLOCK_EXPORT const char * _Block_signature(void *aBlock)
__OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
// Returns a string describing the block's GC layout.
// This uses the GC skip/scan encoding.
// May return NULL.
BLOCK_EXPORT const char * _Block_layout(void *aBlock)
__OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
// Returns a string describing the block's layout.
// This uses the "extended layout" form described above.
// May return NULL.
BLOCK_EXPORT const char * _Block_extended_layout(void *aBlock)
__OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_7_0);
// Callable only from the ARR weak subsystem while in exclusion zone
BLOCK_EXPORT bool _Block_tryRetain(const void *aBlock)
__OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
// Callable only from the ARR weak subsystem while in exclusion zone
BLOCK_EXPORT bool _Block_isDeallocating(const void *aBlock)
__OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
// the raw data space for runtime classes for blocks
// class+meta used for stack, malloc, and collectable based blocks
BLOCK_EXPORT void * _NSConcreteMallocBlock[32]
__OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2);
BLOCK_EXPORT void * _NSConcreteAutoBlock[32]
__OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2);
BLOCK_EXPORT void * _NSConcreteFinalizingBlock[32]
__OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2);
BLOCK_EXPORT void * _NSConcreteWeakBlockVariable[32]
__OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2);
// declared in Block.h
// BLOCK_EXPORT void * _NSConcreteGlobalBlock[32];
// BLOCK_EXPORT void * _NSConcreteStackBlock[32];
struct Block_callbacks_RR {
size_t size; // size == sizeof(struct Block_callbacks_RR)
void (*retain)(const void *);
void (*release)(const void *);
void (*destructInstance)(const void *);
};
typedef struct Block_callbacks_RR Block_callbacks_RR;
BLOCK_EXPORT void _Block_use_RR2(const Block_callbacks_RR *callbacks);
#if __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,592 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 45;
objects = {
/* Begin PBXAggregateTarget section */
3F23D0731A4757F4008445C3 /* Blocks-simulator */ = {
isa = PBXAggregateTarget;
buildConfigurationList = 3F23D0741A4757F4008445C3 /* Build configuration list for PBXAggregateTarget "Blocks-simulator" */;
buildPhases = (
3F23D07A1A4758F9008445C3 /* Comment about this target */,
);
dependencies = (
3F23D0781A4757FF008445C3 /* PBXTargetDependency */,
);
name = "Blocks-simulator";
productName = "Blocks-simulator";
};
/* End PBXAggregateTarget section */
/* Begin PBXBuildFile section */
831D5AD6122788D500E4A1EC /* Block_private.h in Headers */ = {isa = PBXBuildFile; fileRef = E86E1EBF11543C0B0055083F /* Block_private.h */; settings = {ATTRIBUTES = (Private, ); }; };
831D5AD7122788D500E4A1EC /* Block.h in Headers */ = {isa = PBXBuildFile; fileRef = E86E1EC011543C0B0055083F /* Block.h */; settings = {ATTRIBUTES = (Public, ); }; };
831D5AD9122788D500E4A1EC /* data.c in Sources */ = {isa = PBXBuildFile; fileRef = E86E1EC111543C0B0055083F /* data.c */; };
831D5ADA122788D500E4A1EC /* runtime.c in Sources */ = {isa = PBXBuildFile; fileRef = E86E1EC211543C0B0055083F /* runtime.c */; };
96EF759B1507C27500581A2E /* data.c in Sources */ = {isa = PBXBuildFile; fileRef = E86E1EC111543C0B0055083F /* data.c */; };
96EF759C1507C27500581A2E /* runtime.c in Sources */ = {isa = PBXBuildFile; fileRef = E86E1EC211543C0B0055083F /* runtime.c */; };
E86E1EC311543C0B0055083F /* Block_private.h in Headers */ = {isa = PBXBuildFile; fileRef = E86E1EBF11543C0B0055083F /* Block_private.h */; settings = {ATTRIBUTES = (Private, ); }; };
E86E1EC411543C0B0055083F /* Block.h in Headers */ = {isa = PBXBuildFile; fileRef = E86E1EC011543C0B0055083F /* Block.h */; settings = {ATTRIBUTES = (Public, ); }; };
E86E1EC511543C0B0055083F /* data.c in Sources */ = {isa = PBXBuildFile; fileRef = E86E1EC111543C0B0055083F /* data.c */; };
E86E1EC611543C0B0055083F /* runtime.c in Sources */ = {isa = PBXBuildFile; fileRef = E86E1EC211543C0B0055083F /* runtime.c */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
3F23D0771A4757FF008445C3 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
proxyType = 1;
remoteGlobalIDString = D2AAC0C605546C1D00DB518D;
remoteInfo = Blocks;
};
96FA3B6715093BCF003EABC7 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
proxyType = 1;
remoteGlobalIDString = D2AAC0C605546C1D00DB518D;
remoteInfo = Blocks;
};
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
831D5ADF122788D500E4A1EC /* libclosure.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libclosure.a; sourceTree = BUILT_PRODUCTS_DIR; };
96EF75961507C1CE00581A2E /* libclosure.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libclosure.a; sourceTree = BUILT_PRODUCTS_DIR; };
D2AAC0C705546C1D00DB518D /* libsystem_blocks.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libsystem_blocks.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
E86E1EBF11543C0B0055083F /* Block_private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Block_private.h; sourceTree = "<group>"; };
E86E1EC011543C0B0055083F /* Block.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Block.h; sourceTree = "<group>"; };
E86E1EC111543C0B0055083F /* data.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = data.c; sourceTree = "<group>"; };
E86E1EC211543C0B0055083F /* runtime.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = runtime.c; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
831D5ADB122788D500E4A1EC /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
96EF75931507C1CE00581A2E /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
D2AAC0C505546C1D00DB518D /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
034768DFFF38A50411DB9C8B /* Products */ = {
isa = PBXGroup;
children = (
D2AAC0C705546C1D00DB518D /* libsystem_blocks.dylib */,
831D5ADF122788D500E4A1EC /* libclosure.a */,
96EF75961507C1CE00581A2E /* libclosure.a */,
);
name = Products;
sourceTree = "<group>";
};
0867D691FE84028FC02AAC07 /* Blocks */ = {
isa = PBXGroup;
children = (
08FB77AEFE84172EC02AAC07 /* Sources */,
32C88DFF0371C24200C91783 /* Headers */,
034768DFFF38A50411DB9C8B /* Products */,
);
name = Blocks;
sourceTree = "<group>";
};
08FB77AEFE84172EC02AAC07 /* Sources */ = {
isa = PBXGroup;
children = (
E86E1EC111543C0B0055083F /* data.c */,
E86E1EC211543C0B0055083F /* runtime.c */,
);
name = Sources;
sourceTree = "<group>";
};
32C88DFF0371C24200C91783 /* Headers */ = {
isa = PBXGroup;
children = (
E86E1EBF11543C0B0055083F /* Block_private.h */,
E86E1EC011543C0B0055083F /* Block.h */,
);
name = Headers;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
831D5AD5122788D500E4A1EC /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
831D5AD6122788D500E4A1EC /* Block_private.h in Headers */,
831D5AD7122788D500E4A1EC /* Block.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
96EF75941507C1CE00581A2E /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
D2AAC0C305546C1D00DB518D /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
E86E1EC311543C0B0055083F /* Block_private.h in Headers */,
E86E1EC411543C0B0055083F /* Block.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXHeadersBuildPhase section */
/* Begin PBXNativeTarget section */
831D5AD4122788D500E4A1EC /* Blocks-bundle */ = {
isa = PBXNativeTarget;
buildConfigurationList = 831D5ADC122788D500E4A1EC /* Build configuration list for PBXNativeTarget "Blocks-bundle" */;
buildPhases = (
831D5AD5122788D500E4A1EC /* Headers */,
831D5AD8122788D500E4A1EC /* Sources */,
831D5ADB122788D500E4A1EC /* Frameworks */,
);
buildRules = (
);
dependencies = (
);
name = "Blocks-bundle";
productName = "Blocks-simulator2";
productReference = 831D5ADF122788D500E4A1EC /* libclosure.a */;
productType = "com.apple.product-type.library.static";
};
96EF75951507C1CE00581A2E /* libclosure_eOS */ = {
isa = PBXNativeTarget;
buildConfigurationList = 96EF75991507C1CE00581A2E /* Build configuration list for PBXNativeTarget "libclosure_eOS" */;
buildPhases = (
96EF75921507C1CE00581A2E /* Sources */,
96EF75931507C1CE00581A2E /* Frameworks */,
96EF75941507C1CE00581A2E /* Headers */,
);
buildRules = (
);
dependencies = (
96FA3B6815093BCF003EABC7 /* PBXTargetDependency */,
);
name = libclosure_eOS;
productName = libclosure_eOS;
productReference = 96EF75961507C1CE00581A2E /* libclosure.a */;
productType = "com.apple.product-type.library.static";
};
D2AAC0C605546C1D00DB518D /* Blocks */ = {
isa = PBXNativeTarget;
buildConfigurationList = 1DEB917D08733D990010E9CD /* Build configuration list for PBXNativeTarget "Blocks" */;
buildPhases = (
D2AAC0C305546C1D00DB518D /* Headers */,
D2AAC0C405546C1D00DB518D /* Sources */,
D2AAC0C505546C1D00DB518D /* Frameworks */,
3F23D0791A47587A008445C3 /* Simulator Build Compat Symlink */,
);
buildRules = (
);
dependencies = (
);
name = Blocks;
productName = Blocks;
productReference = D2AAC0C705546C1D00DB518D /* libsystem_blocks.dylib */;
productType = "com.apple.product-type.library.dynamic";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
0867D690FE84028FC02AAC07 /* Project object */ = {
isa = PBXProject;
attributes = {
TargetAttributes = {
3F23D0731A4757F4008445C3 = {
CreatedOnToolsVersion = 6.3;
};
};
};
buildConfigurationList = 1DEB918108733D990010E9CD /* Build configuration list for PBXProject "Blocks" */;
compatibilityVersion = "Xcode 3.1";
developmentRegion = English;
hasScannedForEncodings = 1;
knownRegions = (
English,
Japanese,
French,
German,
);
mainGroup = 0867D691FE84028FC02AAC07 /* Blocks */;
productRefGroup = 034768DFFF38A50411DB9C8B /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
D2AAC0C605546C1D00DB518D /* Blocks */,
831D5AD4122788D500E4A1EC /* Blocks-bundle */,
96EF75951507C1CE00581A2E /* libclosure_eOS */,
3F23D0731A4757F4008445C3 /* Blocks-simulator */,
);
};
/* End PBXProject section */
/* Begin PBXShellScriptBuildPhase section */
3F23D0791A47587A008445C3 /* Simulator Build Compat Symlink */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 8;
files = (
);
inputPaths = (
);
name = "Simulator Build Compat Symlink";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 1;
shellPath = "/bin/bash -ex";
shellScript = "if [[ \"${PLATFORM_NAME}\" =~ \"simulator\" ]]; then\nln -s libsystem_blocks.dylib ${DSTROOT}${INSTALL_PATH}/libsystem_sim_blocks.dylib\nfi\n";
};
3F23D07A1A4758F9008445C3 /* Comment about this target */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 8;
files = (
);
inputPaths = (
);
name = "Comment about this target";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 1;
shellPath = /bin/sh;
shellScript = "# This target is only here for B&I compatibility. Cortex should be\n# updated to use the Blocks target and then this target can be\n# removed.\n\ntrue";
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
831D5AD8122788D500E4A1EC /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
831D5AD9122788D500E4A1EC /* data.c in Sources */,
831D5ADA122788D500E4A1EC /* runtime.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
96EF75921507C1CE00581A2E /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
96EF759B1507C27500581A2E /* data.c in Sources */,
96EF759C1507C27500581A2E /* runtime.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
D2AAC0C405546C1D00DB518D /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
E86E1EC511543C0B0055083F /* data.c in Sources */,
E86E1EC611543C0B0055083F /* runtime.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
3F23D0781A4757FF008445C3 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = D2AAC0C605546C1D00DB518D /* Blocks */;
targetProxy = 3F23D0771A4757FF008445C3 /* PBXContainerItemProxy */;
};
96FA3B6815093BCF003EABC7 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = D2AAC0C605546C1D00DB518D /* Blocks */;
targetProxy = 96FA3B6715093BCF003EABC7 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin XCBuildConfiguration section */
1DEB917E08733D990010E9CD /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
EXECUTABLE_PREFIX = lib;
HEADER_SEARCH_PATHS = (
"$(DSTROOT)/usr/include/**",
"$(DSTROOT)/usr/local/include/**",
"$(CONFIGURATION_BUILD_DIR)/usr/include/**",
"$(CONFIGURATION_BUILD_DIR)/usr/local/include/**",
);
INSTALL_PATH = /usr/lib/system;
OTHER_LDFLAGS = (
"$(OTHER_LDFLAGS)",
"-nostdlib",
"-L/usr/lib/system/",
"-lsystem_malloc",
"-lsystem_c",
"-ldyld",
"-Wl,-umbrella,System",
);
"OTHER_LDFLAGS[sdk=iphonesimulator*]" = (
"-lCrashReporterClient",
"-nostdlib",
"-L/usr/lib/system/",
"-lsystem_malloc",
"-lsystem_sim_c",
"-ldyld",
"-Wl,-umbrella,System",
);
PRODUCT_NAME = system_blocks;
PUBLIC_HEADERS_FOLDER_PATH = /usr/include;
};
name = Debug;
};
1DEB917F08733D990010E9CD /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
EXECUTABLE_PREFIX = lib;
HEADER_SEARCH_PATHS = (
"$(DSTROOT)/usr/include/**",
"$(DSTROOT)/usr/local/include/**",
"$(CONFIGURATION_BUILD_DIR)/usr/include/**",
"$(CONFIGURATION_BUILD_DIR)/usr/local/include/**",
);
INSTALL_PATH = /usr/lib/system;
OTHER_LDFLAGS = (
"$(OTHER_LDFLAGS)",
"-nostdlib",
"-L/usr/lib/system/",
"-lsystem_malloc",
"-lsystem_c",
"-ldyld",
"-Wl,-umbrella,System",
);
"OTHER_LDFLAGS[sdk=iphonesimulator*]" = (
"-lCrashReporterClient",
"-nostdlib",
"-L/usr/lib/system/",
"-lsystem_malloc",
"-lsystem_sim_c",
"-ldyld",
"-Wl,-umbrella,System",
);
PRODUCT_NAME = system_blocks;
PUBLIC_HEADERS_FOLDER_PATH = /usr/include;
};
name = Release;
};
1DEB918208733D990010E9CD /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
BUILD_VARIANTS = (
profile,
debug,
normal,
);
CLANG_WARN_IMPLICIT_SIGN_CONVERSION = YES;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = "$(RC_ProjectSourceVersion)";
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = "$(RC_ProjectSourceVersion)";
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_SHADOW = YES;
GCC_WARN_SIGN_COMPARE = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_LABEL = YES;
GCC_WARN_UNUSED_PARAMETER = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
OTHER_LDFLAGS = "-lCrashReporterClient";
PREBINDING = NO;
USER_HEADER_SEARCH_PATHS = "$(SRCROOT)";
USE_HEADERMAP = NO;
VERSIONING_SYSTEM = "apple-generic";
WARNING_CFLAGS = (
"-Wall",
"-Wextra",
);
};
name = Debug;
};
1DEB918308733D990010E9CD /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
BUILD_VARIANTS = (
profile,
debug,
normal,
);
CLANG_WARN_IMPLICIT_SIGN_CONVERSION = YES;
CURRENT_PROJECT_VERSION = "$(RC_ProjectSourceVersion)";
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = "$(RC_ProjectSourceVersion)";
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_MISSING_NEWLINE = YES;
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_SHADOW = YES;
GCC_WARN_SIGN_COMPARE = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_LABEL = YES;
GCC_WARN_UNUSED_PARAMETER = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
"OTHER_CFLAGS[arch=i386]" = "-momit-leaf-frame-pointer";
"OTHER_CFLAGS[arch=x86_64]" = "-momit-leaf-frame-pointer";
OTHER_LDFLAGS = "-lCrashReporterClient";
PREBINDING = NO;
USER_HEADER_SEARCH_PATHS = "$(SRCROOT)";
USE_HEADERMAP = NO;
VERSIONING_SYSTEM = "apple-generic";
WARNING_CFLAGS = (
"-Wall",
"-Wextra",
);
};
name = Release;
};
3F23D0751A4757F4008445C3 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Debug;
};
3F23D0761A4757F4008445C3 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Release;
};
831D5ADD122788D500E4A1EC /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
HEADER_SEARCH_PATHS = (
"$(DSTROOT)/usr/include/**",
"$(DSTROOT)/usr/local/include/**",
"$(CONFIGURATION_BUILD_DIR)/usr/include/**",
"$(CONFIGURATION_BUILD_DIR)/usr/local/include/**",
);
INSTALL_PATH = "$(INDIGO_INSTALL_PATH_PREFIX)/usr/local/lib/system";
PRODUCT_NAME = closure;
PUBLIC_HEADERS_FOLDER_PATH = /usr/include;
};
name = Debug;
};
831D5ADE122788D500E4A1EC /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
HEADER_SEARCH_PATHS = (
"$(DSTROOT)/usr/include/**",
"$(DSTROOT)/usr/local/include/**",
"$(CONFIGURATION_BUILD_DIR)/usr/include/**",
"$(CONFIGURATION_BUILD_DIR)/usr/local/include/**",
);
INSTALL_PATH = "$(INDIGO_INSTALL_PATH_PREFIX)/usr/local/lib/system";
PRODUCT_NAME = closure;
PUBLIC_HEADERS_FOLDER_PATH = /usr/include;
};
name = Release;
};
96EF75971507C1CE00581A2E /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
EXECUTABLE_PREFIX = "";
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
INSTALL_PATH = /usr/local/lib/eOS;
PRODUCT_NAME = libclosure;
};
name = Debug;
};
96EF75981507C1CE00581A2E /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
EXECUTABLE_PREFIX = "";
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
INSTALL_PATH = /usr/local/lib/eOS;
PRODUCT_NAME = libclosure;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
1DEB917D08733D990010E9CD /* Build configuration list for PBXNativeTarget "Blocks" */ = {
isa = XCConfigurationList;
buildConfigurations = (
1DEB917E08733D990010E9CD /* Debug */,
1DEB917F08733D990010E9CD /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
1DEB918108733D990010E9CD /* Build configuration list for PBXProject "Blocks" */ = {
isa = XCConfigurationList;
buildConfigurations = (
1DEB918208733D990010E9CD /* Debug */,
1DEB918308733D990010E9CD /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
3F23D0741A4757F4008445C3 /* Build configuration list for PBXAggregateTarget "Blocks-simulator" */ = {
isa = XCConfigurationList;
buildConfigurations = (
3F23D0751A4757F4008445C3 /* Debug */,
3F23D0761A4757F4008445C3 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
831D5ADC122788D500E4A1EC /* Build configuration list for PBXNativeTarget "Blocks-bundle" */ = {
isa = XCConfigurationList;
buildConfigurations = (
831D5ADD122788D500E4A1EC /* Debug */,
831D5ADE122788D500E4A1EC /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
96EF75991507C1CE00581A2E /* Build configuration list for PBXNativeTarget "libclosure_eOS" */ = {
isa = XCConfigurationList;
buildConfigurations = (
96EF75971507C1CE00581A2E /* Debug */,
96EF75981507C1CE00581A2E /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 0867D690FE84028FC02AAC07 /* Project object */;
}

View File

@ -0,0 +1,79 @@
.\"Modified from man(1) of FreeBSD, the NetBSD mdoc.template, and mdoc.samples.
.\"See Also:
.\"man mdoc.samples for a complete listing of options
.\"man mdoc for the short list of editing options
.\"/usr/share/misc/mdoc.template
.Dd 3/19/08 \" DATE
.Dt ArrayApplyBlock 1 \" Program name and manual section number
.Os Darwin
.Sh NAME \" Section Header - required - don't modify
.Nm ArrayApplyBlock,
.\" The following lines are read in generating the apropos(man -k) database. Use only key
.\" words here as the database is built based on the words here and in the .ND line.
.Nm Other_name_for_same_program(),
.Nm Yet another name for the same program.
.\" Use .Nm macro to designate other names for the documented program.
.Nd This line parsed for whatis database.
.Sh SYNOPSIS \" Section Header - required - don't modify
.Nm
.Op Fl abcd \" [-abcd]
.Op Fl a Ar path \" [-a path]
.Op Ar file \" [file]
.Op Ar \" [file ...]
.Ar arg0 \" Underlined argument - use .Ar anywhere to underline
arg2 ... \" Arguments
.Sh DESCRIPTION \" Section Header - required - don't modify
Use the .Nm macro to refer to your program throughout the man page like such:
.Nm
Underlining is accomplished with the .Ar macro like this:
.Ar underlined text .
.Pp \" Inserts a space
A list of items with descriptions:
.Bl -tag -width -indent \" Begins a tagged list
.It item a \" Each item preceded by .It macro
Description of item a
.It item b
Description of item b
.El \" Ends the list
.Pp
A list of flags and their descriptions:
.Bl -tag -width -indent \" Differs from above in tag removed
.It Fl a \"-a flag as a list item
Description of -a flag
.It Fl b
Description of -b flag
.El \" Ends the list
.Pp
.\" .Sh ENVIRONMENT \" May not be needed
.\" .Bl -tag -width "ENV_VAR_1" -indent \" ENV_VAR_1 is width of the string ENV_VAR_1
.\" .It Ev ENV_VAR_1
.\" Description of ENV_VAR_1
.\" .It Ev ENV_VAR_2
.\" Description of ENV_VAR_2
.\" .El
.Sh FILES \" File used or created by the topic of the man page
.Bl -tag -width "/Users/joeuser/Library/really_long_file_name" -compact
.It Pa /usr/share/file_name
FILE_1 description
.It Pa /Users/joeuser/Library/really_long_file_name
FILE_2 description
.El \" Ends the list
.\" .Sh DIAGNOSTICS \" May not be needed
.\" .Bl -diag
.\" .It Diagnostic Tag
.\" Diagnostic informtion here.
.\" .It Diagnostic Tag
.\" Diagnostic informtion here.
.\" .El
.Sh SEE ALSO
.\" List links in ascending order by section, alphabetically within a section.
.\" Please do not reference files that do not exist without filing a bug report
.Xr a 1 ,
.Xr b 1 ,
.Xr c 1 ,
.Xr a 2 ,
.Xr b 2 ,
.Xr a 3 ,
.Xr b 3
.\" .Sh BUGS \" Document known, unremedied bugs
.\" .Sh HISTORY \" Document history if command behaves in a unique manner

View File

@ -0,0 +1,37 @@
/*
* Copyright (c) 2010 Apple Inc. All rights reserved.
*
* @APPLE_LLVM_LICENSE_HEADER@
*/
#import <Foundation/Foundation.h>
#ifndef __BLOCKS__
#error compiler does not support blocks.
#endif
#if !NS_BLOCKS_AVAILABLE
#error Blocks don't appear to be available, according to the Foundation.
#endif
int main (int argc, const char * argv[]) {
NSArray *array = [NSArray arrayWithObjects: @"A", @"B", @"C", @"A", @"B", @"Z",@"G", @"are", @"Q", nil];
NSSet *filterSet = [NSSet setWithObjects: @"A", @"Z", @"Q", nil];
[array enumerateObjectsUsingBlock: ^(id anObject, NSUInteger idx, BOOL *stop) {
NSLog(@"%d: \t %@", idx, anObject);
if (idx == 4) {
NSLog(@"\tStopping Enumeration.");
*stop = YES;
}
}];
NSIndexSet *indexSet = [array indexesOfObjectsPassingTest: ^(id anObject, NSUInteger idx, BOOL *stop) {
return [filterSet containsObject: anObject];
}];
NSLog(@"Filtered: %@", [array objectsAtIndexes: indexSet]);
NSLog(@"Case Insensitive Sorted: %@", [array sortedArrayUsingComparator: ^(id a, id b) { return [a caseInsensitiveCompare: b]; }]);
return 0;
}

View File

@ -0,0 +1,91 @@
// !$*UTF8*$!
{
08FB7793FE84155DC02AAC07 /* Project object */ = {
activeArchitecture = ppc;
activeBuildConfigurationName = Release;
activeExecutable = E8DAD7D90D931DEE00B8524F /* ArrayApplyBlock */;
activeTarget = 8DD76F960486AA7600D96B5E /* ArrayApplyBlock */;
codeSenseManager = E8DAD80F0D93259600B8524F /* Code sense */;
executables = (
E8DAD7D90D931DEE00B8524F /* ArrayApplyBlock */,
);
perUserDictionary = {
PBXConfiguration.PBXFileTableDataSource3.PBXFileTableDataSource = {
PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID;
PBXFileTableDataSourceColumnWidthsKey = (
20,
243,
20,
48.16259765625,
43,
43,
20,
);
PBXFileTableDataSourceColumnsKey = (
PBXFileDataSource_FiletypeID,
PBXFileDataSource_Filename_ColumnID,
PBXFileDataSource_Built_ColumnID,
PBXFileDataSource_ObjectSize_ColumnID,
PBXFileDataSource_Errors_ColumnID,
PBXFileDataSource_Warnings_ColumnID,
PBXFileDataSource_Target_ColumnID,
);
};
PBXPerProjectTemplateStateSaveDate = 227751012;
PBXWorkspaceStateSaveDate = 227751012;
};
sourceControlManager = E8DAD80E0D93259600B8524F /* Source Control */;
userBuildSettings = {
};
};
08FB7796FE84155DC02AAC07 /* ArrayApplyBlock.m */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {942, 840}}";
sepNavSelRange = "{65, 173}";
sepNavVisRange = "{0, 864}";
sepNavWindowFrame = "{{774, 4}, {1001, 632}}";
};
};
8DD76F960486AA7600D96B5E /* ArrayApplyBlock */ = {
activeExec = 0;
executables = (
E8DAD7D90D931DEE00B8524F /* ArrayApplyBlock */,
);
};
E8DAD7D90D931DEE00B8524F /* ArrayApplyBlock */ = {
isa = PBXExecutable;
activeArgIndices = (
);
argumentStrings = (
);
autoAttachOnCrash = 1;
breakpointsEnabled = 0;
configStateDict = {
};
customDataFormattersEnabled = 1;
debuggerPlugin = GDBDebugging;
disassemblyDisplayState = 0;
dylibVariantSuffix = "";
enableDebugStr = 1;
environmentEntries = (
);
executableSystemSymbolLevel = 0;
executableUserSymbolLevel = 0;
libgmallocEnabled = 0;
name = ArrayApplyBlock;
sourceDirectories = (
);
};
E8DAD80E0D93259600B8524F /* Source Control */ = {
isa = PBXSourceControlManager;
fallbackIsa = XCSourceControlManager;
isSCMEnabled = 0;
scmConfiguration = {
};
};
E8DAD80F0D93259600B8524F /* Code sense */ = {
isa = PBXCodeSenseManager;
indexTemplatePath = "";
};
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,386 @@
// !$*UTF8*$!
{
08FB7793FE84155DC02AAC07 /* Project object */ = {
activeArchitecture = i386;
activeBuildConfigurationName = Debug;
activeExecutable = 77C954A20D918D250012F143 /* ArrayApplyBlock */;
activeTarget = 8DD76F960486AA7600D96B5E /* ArrayApplyBlock */;
codeSenseManager = 77C954B00D918D290012F143 /* Code sense */;
executables = (
77C954A20D918D250012F143 /* ArrayApplyBlock */,
);
perUserDictionary = {
PBXConfiguration.PBXFileTableDataSource3.PBXFileTableDataSource = {
PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID;
PBXFileTableDataSourceColumnWidthsKey = (
20,
445,
20,
48,
43,
43,
20,
);
PBXFileTableDataSourceColumnsKey = (
PBXFileDataSource_FiletypeID,
PBXFileDataSource_Filename_ColumnID,
PBXFileDataSource_Built_ColumnID,
PBXFileDataSource_ObjectSize_ColumnID,
PBXFileDataSource_Errors_ColumnID,
PBXFileDataSource_Warnings_ColumnID,
PBXFileDataSource_Target_ColumnID,
);
};
PBXConfiguration.PBXTargetDataSource.PBXTargetDataSource = {
PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID;
PBXFileTableDataSourceColumnWidthsKey = (
20,
203,
60,
20,
48.16259765625,
43,
43,
);
PBXFileTableDataSourceColumnsKey = (
PBXFileDataSource_FiletypeID,
PBXFileDataSource_Filename_ColumnID,
PBXTargetDataSource_PrimaryAttribute,
PBXFileDataSource_Built_ColumnID,
PBXFileDataSource_ObjectSize_ColumnID,
PBXFileDataSource_Errors_ColumnID,
PBXFileDataSource_Warnings_ColumnID,
);
};
PBXPerProjectTemplateStateSaveDate = 231111366;
PBXWorkspaceStateSaveDate = 231111366;
};
perUserProjectItems = {
77B8C5340DC28DFC004FC458 = 77B8C5340DC28DFC004FC458 /* PBXTextBookmark */;
77B8C5660DC297F0004FC458 = 77B8C5660DC297F0004FC458 /* PBXTextBookmark */;
77B8C5670DC297F0004FC458 = 77B8C5670DC297F0004FC458 /* PBXTextBookmark */;
77B8C5680DC297F0004FC458 = 77B8C5680DC297F0004FC458 /* PBXTextBookmark */;
77B8C56B0DC297F0004FC458 = 77B8C56B0DC297F0004FC458 /* PBXTextBookmark */;
77B8C56D0DC297F0004FC458 = 77B8C56D0DC297F0004FC458 /* PBXTextBookmark */;
77B8C5710DC297F0004FC458 = 77B8C5710DC297F0004FC458 /* PBXTextBookmark */;
77B8C5730DC297F0004FC458 = 77B8C5730DC297F0004FC458 /* PBXTextBookmark */;
77B8C5770DC297F0004FC458 = 77B8C5770DC297F0004FC458 /* PBXTextBookmark */;
77B8C5790DC297F0004FC458 = 77B8C5790DC297F0004FC458 /* PBXTextBookmark */;
77B8C5930DC65431004FC458 = 77B8C5930DC65431004FC458 /* PBXTextBookmark */;
77B8C5940DC65431004FC458 = 77B8C5940DC65431004FC458 /* PBXTextBookmark */;
77B8C5950DC65431004FC458 = 77B8C5950DC65431004FC458 /* PBXTextBookmark */;
77B8C5960DC65431004FC458 = 77B8C5960DC65431004FC458 /* PBXTextBookmark */;
77B8C5970DC65431004FC458 = 77B8C5970DC65431004FC458 /* PBXTextBookmark */;
77B8C5980DC65431004FC458 = 77B8C5980DC65431004FC458 /* PBXTextBookmark */;
77B8C59B0DC65431004FC458 = 77B8C59B0DC65431004FC458 /* PBXBookmark */;
77B8C59C0DC65431004FC458 = 77B8C59C0DC65431004FC458 /* PBXTextBookmark */;
77C954A80D918D290012F143 = 77C954A80D918D290012F143 /* PBXBookmark */;
77C954AE0D918D290012F143 = 77C954AE0D918D290012F143 /* PBXTextBookmark */;
77C954B80D918D660012F143 = 77C954B80D918D660012F143 /* PBXTextBookmark */;
};
sourceControlManager = 77C954AF0D918D290012F143 /* Source Control */;
userBuildSettings = {
};
};
08FB7796FE84155DC02AAC07 /* ArrayApplyBlock.m */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {1028, 825}}";
sepNavSelRange = "{1049, 0}";
sepNavVisRange = "{0, 1065}";
sepNavWindowFrame = "{{662, 63}, {1087, 961}}";
};
};
77B8C5340DC28DFC004FC458 /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 08FB7796FE84155DC02AAC07 /* ArrayApplyBlock.m */;
name = "ArrayApplyBlock.m: 1";
rLen = 0;
rLoc = 0;
rType = 0;
vrLen = 731;
vrLoc = 0;
};
77B8C5660DC297F0004FC458 /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 08FB7796FE84155DC02AAC07 /* ArrayApplyBlock.m */;
name = "ArrayApplyBlock.m: 1";
rLen = 0;
rLoc = 0;
rType = 0;
vrLen = 254;
vrLoc = 0;
};
77B8C5670DC297F0004FC458 /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 08FB7796FE84155DC02AAC07 /* ArrayApplyBlock.m */;
name = "ArrayApplyBlock.m: 1";
rLen = 0;
rLoc = 0;
rType = 0;
vrLen = 667;
vrLoc = 0;
};
77B8C5680DC297F0004FC458 /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 08FB7796FE84155DC02AAC07 /* ArrayApplyBlock.m */;
name = "ArrayApplyBlock.m: 9";
rLen = 0;
rLoc = 207;
rType = 0;
vrLen = 934;
vrLoc = 0;
};
77B8C56B0DC297F0004FC458 /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 77B8C56C0DC297F0004FC458 /* NSArray.h */;
rLen = 1;
rLoc = 12;
rType = 1;
};
77B8C56C0DC297F0004FC458 /* NSArray.h */ = {
isa = PBXFileReference;
lastKnownFileType = sourcecode.c.h;
name = NSArray.h;
path = /System/Library/Frameworks/Foundation.framework/Versions/C/Headers/NSArray.h;
sourceTree = "<absolute>";
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {1028, 1876}}";
sepNavSelRange = "{3775, 13}";
sepNavVisRange = "{978, 3537}";
};
};
77B8C56D0DC297F0004FC458 /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 77B8C56E0DC297F0004FC458 /* NSArray.h */;
name = "NSArray.h: 58";
rLen = 55;
rLoc = 2629;
rType = 0;
vrLen = 3572;
vrLoc = 712;
};
77B8C56E0DC297F0004FC458 /* NSArray.h */ = {
isa = PBXFileReference;
lastKnownFileType = sourcecode.c.h;
name = NSArray.h;
path = /System/Library/Frameworks/Foundation.framework/Versions/C/Headers/NSArray.h;
sourceTree = "<absolute>";
};
77B8C5710DC297F0004FC458 /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 77B8C5720DC297F0004FC458 /* NSPredicate.h */;
rLen = 0;
rLoc = 2147483647;
rType = 0;
};
77B8C5720DC297F0004FC458 /* NSPredicate.h */ = {
isa = PBXFileReference;
lastKnownFileType = sourcecode.c.h;
name = NSPredicate.h;
path = /System/Library/Frameworks/Foundation.framework/Versions/C/Headers/NSPredicate.h;
sourceTree = "<absolute>";
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {1028, 825}}";
sepNavSelRange = "{0, 0}";
sepNavVisRange = "{0, 2394}";
};
};
77B8C5730DC297F0004FC458 /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 77B8C5740DC297F0004FC458 /* NSPredicate.h */;
name = "NSPredicate.h: 1";
rLen = 0;
rLoc = 0;
rType = 0;
vrLen = 2394;
vrLoc = 0;
};
77B8C5740DC297F0004FC458 /* NSPredicate.h */ = {
isa = PBXFileReference;
lastKnownFileType = sourcecode.c.h;
name = NSPredicate.h;
path = /System/Library/Frameworks/Foundation.framework/Versions/C/Headers/NSPredicate.h;
sourceTree = "<absolute>";
};
77B8C5770DC297F0004FC458 /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 77B8C5780DC297F0004FC458 /* NSObjCRuntime.h */;
name = "NSObjCRuntime.h: 65";
rLen = 10;
rLoc = 1717;
rType = 0;
vrLen = 1959;
vrLoc = 963;
};
77B8C5780DC297F0004FC458 /* NSObjCRuntime.h */ = {
isa = PBXFileReference;
lastKnownFileType = sourcecode.c.h;
name = NSObjCRuntime.h;
path = /System/Library/Frameworks/Foundation.framework/Versions/C/Headers/NSObjCRuntime.h;
sourceTree = "<absolute>";
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {1028, 2884}}";
sepNavSelRange = "{5379, 12}";
sepNavVisRange = "{4194, 1647}";
};
};
77B8C5790DC297F0004FC458 /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 77B8C57A0DC297F0004FC458 /* NSObjCRuntime.h */;
name = "NSObjCRuntime.h: 163";
rLen = 12;
rLoc = 5379;
rType = 0;
vrLen = 1781;
vrLoc = 3876;
};
77B8C57A0DC297F0004FC458 /* NSObjCRuntime.h */ = {
isa = PBXFileReference;
lastKnownFileType = sourcecode.c.h;
name = NSObjCRuntime.h;
path = /System/Library/Frameworks/Foundation.framework/Versions/C/Headers/NSObjCRuntime.h;
sourceTree = "<absolute>";
};
77B8C5930DC65431004FC458 /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 08FB7796FE84155DC02AAC07 /* ArrayApplyBlock.m */;
name = "ArrayApplyBlock.m: 1";
rLen = 0;
rLoc = 0;
rType = 0;
vrLen = 738;
vrLoc = 0;
};
77B8C5940DC65431004FC458 /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 08FB7796FE84155DC02AAC07 /* ArrayApplyBlock.m */;
name = "ArrayApplyBlock.m: 30";
rLen = 0;
rLoc = 1049;
rType = 0;
vrLen = 1143;
vrLoc = 0;
};
77B8C5950DC65431004FC458 /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 77B8C56E0DC297F0004FC458 /* NSArray.h */;
rLen = 1;
rLoc = 12;
rType = 1;
};
77B8C5960DC65431004FC458 /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 77B8C56E0DC297F0004FC458 /* NSArray.h */;
name = "NSArray.h: 67";
rLen = 13;
rLoc = 3775;
rType = 0;
vrLen = 3495;
vrLoc = 1020;
};
77B8C5970DC65431004FC458 /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 77B8C5720DC297F0004FC458 /* NSPredicate.h */;
name = "NSPredicate.h: 1";
rLen = 0;
rLoc = 0;
rType = 0;
vrLen = 2394;
vrLoc = 0;
};
77B8C5980DC65431004FC458 /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 77B8C5740DC297F0004FC458 /* NSPredicate.h */;
name = "NSPredicate.h: 1";
rLen = 0;
rLoc = 0;
rType = 0;
vrLen = 2394;
vrLoc = 0;
};
77B8C59B0DC65431004FC458 /* PBXBookmark */ = {
isa = PBXBookmark;
fRef = 77B8C57A0DC297F0004FC458 /* NSObjCRuntime.h */;
};
77B8C59C0DC65431004FC458 /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 77B8C57A0DC297F0004FC458 /* NSObjCRuntime.h */;
name = "NSObjCRuntime.h: 163";
rLen = 12;
rLoc = 5379;
rType = 0;
vrLen = 1646;
vrLoc = 4195;
};
77C954A20D918D250012F143 /* ArrayApplyBlock */ = {
isa = PBXExecutable;
activeArgIndices = (
);
argumentStrings = (
);
autoAttachOnCrash = 1;
breakpointsEnabled = 0;
configStateDict = {
};
customDataFormattersEnabled = 1;
debuggerPlugin = GDBDebugging;
disassemblyDisplayState = 0;
dylibVariantSuffix = "";
enableDebugStr = 1;
environmentEntries = (
);
executableSystemSymbolLevel = 0;
executableUserSymbolLevel = 0;
libgmallocEnabled = 0;
name = ArrayApplyBlock;
savedGlobals = {
};
sourceDirectories = (
);
variableFormatDictionary = {
};
};
77C954A80D918D290012F143 /* PBXBookmark */ = {
isa = PBXBookmark;
fRef = 08FB7796FE84155DC02AAC07 /* ArrayApplyBlock.m */;
};
77C954AE0D918D290012F143 /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 08FB7796FE84155DC02AAC07 /* ArrayApplyBlock.m */;
name = "ArrayApplyBlock.m: 1";
rLen = 0;
rLoc = 0;
rType = 0;
vrLen = 234;
vrLoc = 0;
};
77C954AF0D918D290012F143 /* Source Control */ = {
isa = PBXSourceControlManager;
fallbackIsa = XCSourceControlManager;
isSCMEnabled = 0;
scmConfiguration = {
};
};
77C954B00D918D290012F143 /* Code sense */ = {
isa = PBXCodeSenseManager;
indexTemplatePath = "";
};
77C954B80D918D660012F143 /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 08FB7796FE84155DC02AAC07 /* ArrayApplyBlock.m */;
name = "ArrayApplyBlock.m: 1";
rLen = 0;
rLoc = 0;
rType = 0;
vrLen = 486;
vrLoc = 0;
};
8DD76F960486AA7600D96B5E /* ArrayApplyBlock */ = {
activeExec = 0;
executables = (
77C954A20D918D250012F143 /* ArrayApplyBlock */,
);
};
}

View File

@ -0,0 +1,239 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 44;
objects = {
/* Begin PBXBuildFile section */
8DD76F9A0486AA7600D96B5E /* ArrayApplyBlock.m in Sources */ = {isa = PBXBuildFile; fileRef = 08FB7796FE84155DC02AAC07 /* ArrayApplyBlock.m */; settings = {ATTRIBUTES = (); }; };
8DD76F9C0486AA7600D96B5E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 08FB779EFE84155DC02AAC07 /* Foundation.framework */; };
8DD76F9F0486AA7600D96B5E /* ArrayApplyBlock.1 in CopyFiles */ = {isa = PBXBuildFile; fileRef = C6859EA3029092ED04C91782 /* ArrayApplyBlock.1 */; };
/* End PBXBuildFile section */
/* Begin PBXBuildRule section */
77B8C5390DC28EC8004FC458 /* PBXBuildRule */ = {
isa = PBXBuildRule;
compilerSpec = com.apple.compilers.gcc.4_2;
fileType = sourcecode.c;
isEditable = 1;
outputFiles = (
);
};
77B8C53A0DC28EC8004FC458 /* PBXBuildRule */ = {
isa = PBXBuildRule;
compilerSpec = com.apple.compilers.gcc;
fileType = sourcecode.asm;
isEditable = 1;
outputFiles = (
);
};
/* End PBXBuildRule section */
/* Begin PBXCopyFilesBuildPhase section */
8DD76F9E0486AA7600D96B5E /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 8;
dstPath = /usr/share/man/man1/;
dstSubfolderSpec = 0;
files = (
8DD76F9F0486AA7600D96B5E /* ArrayApplyBlock.1 in CopyFiles */,
);
runOnlyForDeploymentPostprocessing = 1;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
08FB7796FE84155DC02AAC07 /* ArrayApplyBlock.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ArrayApplyBlock.m; sourceTree = "<group>"; };
08FB779EFE84155DC02AAC07 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; };
32A70AAB03705E1F00C91783 /* ArrayApplyBlock_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ArrayApplyBlock_Prefix.pch; sourceTree = "<group>"; };
8DD76FA10486AA7600D96B5E /* ArrayApplyBlock */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = ArrayApplyBlock; sourceTree = BUILT_PRODUCTS_DIR; };
C6859EA3029092ED04C91782 /* ArrayApplyBlock.1 */ = {isa = PBXFileReference; lastKnownFileType = text.man; path = ArrayApplyBlock.1; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
8DD76F9B0486AA7600D96B5E /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
8DD76F9C0486AA7600D96B5E /* Foundation.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
08FB7794FE84155DC02AAC07 /* ArrayApplyBlock */ = {
isa = PBXGroup;
children = (
08FB7795FE84155DC02AAC07 /* Source */,
C6859EA2029092E104C91782 /* Documentation */,
08FB779DFE84155DC02AAC07 /* External Frameworks and Libraries */,
1AB674ADFE9D54B511CA2CBB /* Products */,
);
name = ArrayApplyBlock;
sourceTree = "<group>";
};
08FB7795FE84155DC02AAC07 /* Source */ = {
isa = PBXGroup;
children = (
32A70AAB03705E1F00C91783 /* ArrayApplyBlock_Prefix.pch */,
08FB7796FE84155DC02AAC07 /* ArrayApplyBlock.m */,
);
name = Source;
sourceTree = "<group>";
};
08FB779DFE84155DC02AAC07 /* External Frameworks and Libraries */ = {
isa = PBXGroup;
children = (
08FB779EFE84155DC02AAC07 /* Foundation.framework */,
);
name = "External Frameworks and Libraries";
sourceTree = "<group>";
};
1AB674ADFE9D54B511CA2CBB /* Products */ = {
isa = PBXGroup;
children = (
8DD76FA10486AA7600D96B5E /* ArrayApplyBlock */,
);
name = Products;
sourceTree = "<group>";
};
C6859EA2029092E104C91782 /* Documentation */ = {
isa = PBXGroup;
children = (
C6859EA3029092ED04C91782 /* ArrayApplyBlock.1 */,
);
name = Documentation;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
8DD76F960486AA7600D96B5E /* ArrayApplyBlock */ = {
isa = PBXNativeTarget;
buildConfigurationList = 1DEB927408733DD40010E9CD /* Build configuration list for PBXNativeTarget "ArrayApplyBlock" */;
buildPhases = (
8DD76F990486AA7600D96B5E /* Sources */,
8DD76F9B0486AA7600D96B5E /* Frameworks */,
8DD76F9E0486AA7600D96B5E /* CopyFiles */,
);
buildRules = (
77B8C5390DC28EC8004FC458 /* PBXBuildRule */,
77B8C53A0DC28EC8004FC458 /* PBXBuildRule */,
);
dependencies = (
);
name = ArrayApplyBlock;
productInstallPath = "$(HOME)/bin";
productName = ArrayApplyBlock;
productReference = 8DD76FA10486AA7600D96B5E /* ArrayApplyBlock */;
productType = "com.apple.product-type.tool";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
08FB7793FE84155DC02AAC07 /* Project object */ = {
isa = PBXProject;
buildConfigurationList = 1DEB927808733DD40010E9CD /* Build configuration list for PBXProject "ArrayApplyBlock" */;
compatibilityVersion = "Xcode 3.0";
hasScannedForEncodings = 1;
mainGroup = 08FB7794FE84155DC02AAC07 /* ArrayApplyBlock */;
projectDirPath = "";
projectRoot = "";
targets = (
8DD76F960486AA7600D96B5E /* ArrayApplyBlock */,
);
};
/* End PBXProject section */
/* Begin PBXSourcesBuildPhase section */
8DD76F990486AA7600D96B5E /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
8DD76F9A0486AA7600D96B5E /* ArrayApplyBlock.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
1DEB927508733DD40010E9CD /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
COPY_PHASE_STRIP = NO;
GCC_DYNAMIC_NO_PIC = NO;
GCC_ENABLE_FIX_AND_CONTINUE = YES;
GCC_MODEL_TUNING = G5;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = ArrayApplyBlock_Prefix.pch;
INSTALL_PATH = /usr/local/bin;
PRODUCT_NAME = ArrayApplyBlock;
ZERO_LINK = YES;
};
name = Debug;
};
1DEB927608733DD40010E9CD /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
GCC_MODEL_TUNING = G5;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = ArrayApplyBlock_Prefix.pch;
INSTALL_PATH = /usr/local/bin;
PRODUCT_NAME = ArrayApplyBlock;
};
name = Release;
};
1DEB927908733DD40010E9CD /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(NATIVE_ARCH)";
GCC_ENABLE_OBJC_GC = required;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = "";
PREBINDING = NO;
};
name = Debug;
};
1DEB927A08733DD40010E9CD /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(NATIVE_ARCH)";
GCC_ENABLE_OBJC_GC = required;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = "";
PREBINDING = NO;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
1DEB927408733DD40010E9CD /* Build configuration list for PBXNativeTarget "ArrayApplyBlock" */ = {
isa = XCConfigurationList;
buildConfigurations = (
1DEB927508733DD40010E9CD /* Debug */,
1DEB927608733DD40010E9CD /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
1DEB927808733DD40010E9CD /* Build configuration list for PBXProject "ArrayApplyBlock" */ = {
isa = XCConfigurationList;
buildConfigurations = (
1DEB927908733DD40010E9CD /* Debug */,
1DEB927A08733DD40010E9CD /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
}

View File

@ -0,0 +1,7 @@
//
// Prefix header for all source files of the 'ArrayApplyBlock' target in the 'ArrayApplyBlock' project.
//
#ifdef __OBJC__
#import <Foundation/Foundation.h>
#endif

View File

@ -0,0 +1,79 @@
.\"Modified from man(1) of FreeBSD, the NetBSD mdoc.template, and mdoc.samples.
.\"See Also:
.\"man mdoc.samples for a complete listing of options
.\"man mdoc for the short list of editing options
.\"/usr/share/misc/mdoc.template
.Dd 5/12/08 \" DATE
.Dt Sort 1 \" Program name and manual section number
.Os Darwin
.Sh NAME \" Section Header - required - don't modify
.Nm Sort,
.\" The following lines are read in generating the apropos(man -k) database. Use only key
.\" words here as the database is built based on the words here and in the .ND line.
.Nm Other_name_for_same_program(),
.Nm Yet another name for the same program.
.\" Use .Nm macro to designate other names for the documented program.
.Nd This line parsed for whatis database.
.Sh SYNOPSIS \" Section Header - required - don't modify
.Nm
.Op Fl abcd \" [-abcd]
.Op Fl a Ar path \" [-a path]
.Op Ar file \" [file]
.Op Ar \" [file ...]
.Ar arg0 \" Underlined argument - use .Ar anywhere to underline
arg2 ... \" Arguments
.Sh DESCRIPTION \" Section Header - required - don't modify
Use the .Nm macro to refer to your program throughout the man page like such:
.Nm
Underlining is accomplished with the .Ar macro like this:
.Ar underlined text .
.Pp \" Inserts a space
A list of items with descriptions:
.Bl -tag -width -indent \" Begins a tagged list
.It item a \" Each item preceded by .It macro
Description of item a
.It item b
Description of item b
.El \" Ends the list
.Pp
A list of flags and their descriptions:
.Bl -tag -width -indent \" Differs from above in tag removed
.It Fl a \"-a flag as a list item
Description of -a flag
.It Fl b
Description of -b flag
.El \" Ends the list
.Pp
.\" .Sh ENVIRONMENT \" May not be needed
.\" .Bl -tag -width "ENV_VAR_1" -indent \" ENV_VAR_1 is width of the string ENV_VAR_1
.\" .It Ev ENV_VAR_1
.\" Description of ENV_VAR_1
.\" .It Ev ENV_VAR_2
.\" Description of ENV_VAR_2
.\" .El
.Sh FILES \" File used or created by the topic of the man page
.Bl -tag -width "/Users/joeuser/Library/really_long_file_name" -compact
.It Pa /usr/share/file_name
FILE_1 description
.It Pa /Users/joeuser/Library/really_long_file_name
FILE_2 description
.El \" Ends the list
.\" .Sh DIAGNOSTICS \" May not be needed
.\" .Bl -diag
.\" .It Diagnostic Tag
.\" Diagnostic informtion here.
.\" .It Diagnostic Tag
.\" Diagnostic informtion here.
.\" .El
.Sh SEE ALSO
.\" List links in ascending order by section, alphabetically within a section.
.\" Please do not reference files that do not exist without filing a bug report
.Xr a 1 ,
.Xr b 1 ,
.Xr c 1 ,
.Xr a 2 ,
.Xr b 2 ,
.Xr a 3 ,
.Xr b 3
.\" .Sh BUGS \" Document known, unremedied bugs
.\" .Sh HISTORY \" Document history if command behaves in a unique manner

View File

@ -0,0 +1,42 @@
/*
* Copyright (c) 2010 Apple Inc. All rights reserved.
*
* @APPLE_LLVM_LICENSE_HEADER@
*/
#import <Foundation/Foundation.h>
#ifndef __BLOCKS__
#error compiler does not support blocks.
#endif
#if !NS_BLOCKS_AVAILABLE
#error Blocks don't appear to be available, according to the Foundation.
#endif
NSInteger sortStuff(id a, id b, void *inReverse) {
int reverse = (int) inReverse; // oops
int result = [(NSString *)a compare: b];
return reverse ? -result : result;
}
int main (int argc, const char * argv[]) {
NSArray *stuff = [NSArray arrayWithObjects: @"SQUARED OFF", @"EIGHT CORNERS", @"90-DEGREE ANGLES", @"FLAT TOP", @"STARES STRAIGHT AHEAD", @"STOCK PARTS", nil];
int inReverse = 1;
NSLog(@"reverse func: %@", [stuff sortedArrayUsingFunction:sortStuff context: &inReverse]);
NSLog(@"reverse block: %@", [stuff sortedArrayUsingComparator: ^(id a, id b) {
int result = [a compare: b];
return inReverse ? -result : result;
}]);
inReverse = 0;
NSLog(@"forward func: %@", [stuff sortedArrayUsingFunction:sortStuff context: &inReverse]);
NSLog(@"forward block: %@", [stuff sortedArrayUsingComparator: ^(id a, id b) {
int result = [a compare: b];
return inReverse ? -result : result;
}]);
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,231 @@
// !$*UTF8*$!
{
08FB7793FE84155DC02AAC07 /* Project object */ = {
activeBuildConfigurationName = Debug;
activeExecutable = 77D9907C0DD8E15D004FBB86 /* Sort */;
activeTarget = 8DD76F960486AA7600D96B5E /* Sort */;
codeSenseManager = 77D990840DD8E17C004FBB86 /* Code sense */;
executables = (
77D9907C0DD8E15D004FBB86 /* Sort */,
);
perUserDictionary = {
PBXConfiguration.PBXFileTableDataSource3.PBXFileTableDataSource = {
PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID;
PBXFileTableDataSourceColumnWidthsKey = (
20,
341,
20,
48.16259765625,
43,
43,
20,
);
PBXFileTableDataSourceColumnsKey = (
PBXFileDataSource_FiletypeID,
PBXFileDataSource_Filename_ColumnID,
PBXFileDataSource_Built_ColumnID,
PBXFileDataSource_ObjectSize_ColumnID,
PBXFileDataSource_Errors_ColumnID,
PBXFileDataSource_Warnings_ColumnID,
PBXFileDataSource_Target_ColumnID,
);
};
PBXConfiguration.PBXTargetDataSource.PBXTargetDataSource = {
PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID;
PBXFileTableDataSourceColumnWidthsKey = (
20,
301,
60,
20,
48.16259765625,
43,
43,
);
PBXFileTableDataSourceColumnsKey = (
PBXFileDataSource_FiletypeID,
PBXFileDataSource_Filename_ColumnID,
PBXTargetDataSource_PrimaryAttribute,
PBXFileDataSource_Built_ColumnID,
PBXFileDataSource_ObjectSize_ColumnID,
PBXFileDataSource_Errors_ColumnID,
PBXFileDataSource_Warnings_ColumnID,
);
};
PBXPerProjectTemplateStateSaveDate = 232317277;
PBXWorkspaceStateSaveDate = 232317277;
};
perUserProjectItems = {
77D990970DD8E506004FBB86 /* PBXTextBookmark */ = 77D990970DD8E506004FBB86 /* PBXTextBookmark */;
77D990980DD8E506004FBB86 /* PBXTextBookmark */ = 77D990980DD8E506004FBB86 /* PBXTextBookmark */;
77D9909B0DD8E506004FBB86 /* PBXTextBookmark */ = 77D9909B0DD8E506004FBB86 /* PBXTextBookmark */;
77D9909D0DD8E506004FBB86 /* PBXTextBookmark */ = 77D9909D0DD8E506004FBB86 /* PBXTextBookmark */;
77D990A10DD8E506004FBB86 /* PBXTextBookmark */ = 77D990A10DD8E506004FBB86 /* PBXTextBookmark */;
77D990A30DD8E506004FBB86 /* PBXTextBookmark */ = 77D990A30DD8E506004FBB86 /* PBXTextBookmark */;
77D990A70DD8E506004FBB86 /* PBXTextBookmark */ = 77D990A70DD8E506004FBB86 /* PBXTextBookmark */;
77D990A90DD8E506004FBB86 /* PBXTextBookmark */ = 77D990A90DD8E506004FBB86 /* PBXTextBookmark */;
};
sourceControlManager = 77D990830DD8E17C004FBB86 /* Source Control */;
userBuildSettings = {
};
};
08FB7796FE84155DC02AAC07 /* Sort.m */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {1028, 848}}";
sepNavSelRange = "{142, 0}";
sepNavVisRange = "{0, 948}";
};
};
77D9907C0DD8E15D004FBB86 /* Sort */ = {
isa = PBXExecutable;
activeArgIndices = (
);
argumentStrings = (
);
autoAttachOnCrash = 1;
breakpointsEnabled = 0;
configStateDict = {
};
customDataFormattersEnabled = 1;
debuggerPlugin = GDBDebugging;
disassemblyDisplayState = 0;
dylibVariantSuffix = "";
enableDebugStr = 1;
environmentEntries = (
);
executableSystemSymbolLevel = 0;
executableUserSymbolLevel = 0;
libgmallocEnabled = 0;
name = Sort;
sourceDirectories = (
);
};
77D990830DD8E17C004FBB86 /* Source Control */ = {
isa = PBXSourceControlManager;
fallbackIsa = XCSourceControlManager;
isSCMEnabled = 0;
scmConfiguration = {
};
};
77D990840DD8E17C004FBB86 /* Code sense */ = {
isa = PBXCodeSenseManager;
indexTemplatePath = "";
};
77D990970DD8E506004FBB86 /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 08FB7796FE84155DC02AAC07 /* Sort.m */;
name = "Sort.m: 1";
rLen = 0;
rLoc = 389;
rType = 0;
vrLen = 234;
vrLoc = 0;
};
77D990980DD8E506004FBB86 /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 08FB7796FE84155DC02AAC07 /* Sort.m */;
name = "Sort.m: 8";
rLen = 0;
rLoc = 34;
rType = 0;
vrLen = 948;
vrLoc = 0;
};
77D9909B0DD8E506004FBB86 /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 77D9909C0DD8E506004FBB86 /* NSObjCRuntime.h */;
rLen = 0;
rLoc = 2147483647;
rType = 0;
};
77D9909C0DD8E506004FBB86 /* NSObjCRuntime.h */ = {
isa = PBXFileReference;
lastKnownFileType = sourcecode.c.h;
name = NSObjCRuntime.h;
path = /System/Library/Frameworks/Foundation.framework/Versions/C/Headers/NSObjCRuntime.h;
sourceTree = "<absolute>";
};
77D9909D0DD8E506004FBB86 /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 77D9909E0DD8E506004FBB86 /* NSObjCRuntime.h */;
name = "NSObjCRuntime.h: 65";
rLen = 10;
rLoc = 1717;
rType = 0;
vrLen = 1959;
vrLoc = 963;
};
77D9909E0DD8E506004FBB86 /* NSObjCRuntime.h */ = {
isa = PBXFileReference;
name = NSObjCRuntime.h;
path = /System/Library/Frameworks/Foundation.framework/Versions/C/Headers/NSObjCRuntime.h;
sourceTree = "<absolute>";
};
77D990A10DD8E506004FBB86 /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 77D990A20DD8E506004FBB86 /* NSArray.h */;
rLen = 0;
rLoc = 2147483647;
rType = 0;
};
77D990A20DD8E506004FBB86 /* NSArray.h */ = {
isa = PBXFileReference;
lastKnownFileType = sourcecode.c.h;
name = NSArray.h;
path = /System/Library/Frameworks/Foundation.framework/Versions/C/Headers/NSArray.h;
sourceTree = "<absolute>";
};
77D990A30DD8E506004FBB86 /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 77D990A40DD8E506004FBB86 /* NSArray.h */;
name = "NSArray.h: 53";
rLen = 24;
rLoc = 2075;
rType = 0;
vrLen = 3636;
vrLoc = 648;
};
77D990A40DD8E506004FBB86 /* NSArray.h */ = {
isa = PBXFileReference;
name = NSArray.h;
path = /System/Library/Frameworks/Foundation.framework/Versions/C/Headers/NSArray.h;
sourceTree = "<absolute>";
};
77D990A70DD8E506004FBB86 /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 77D990A80DD8E506004FBB86 /* NSString.h */;
rLen = 1;
rLoc = 101;
rType = 1;
};
77D990A80DD8E506004FBB86 /* NSString.h */ = {
isa = PBXFileReference;
lastKnownFileType = sourcecode.c.h;
name = NSString.h;
path = /Developer/SDKs/MacOSX10.5.sdk/System/Library/Frameworks/Foundation.framework/Versions/C/Headers/NSString.h;
sourceTree = "<absolute>";
};
77D990A90DD8E506004FBB86 /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 77D990AA0DD8E506004FBB86 /* NSString.h */;
name = "NSString.h: 102";
rLen = 18;
rLoc = 4634;
rType = 0;
vrLen = 3110;
vrLoc = 2957;
};
77D990AA0DD8E506004FBB86 /* NSString.h */ = {
isa = PBXFileReference;
name = NSString.h;
path = /Developer/SDKs/MacOSX10.5.sdk/System/Library/Frameworks/Foundation.framework/Versions/C/Headers/NSString.h;
sourceTree = "<absolute>";
};
8DD76F960486AA7600D96B5E /* Sort */ = {
activeExec = 0;
executables = (
77D9907C0DD8E15D004FBB86 /* Sort */,
);
};
}

View File

@ -0,0 +1,221 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 45;
objects = {
/* Begin PBXBuildFile section */
8DD76F9A0486AA7600D96B5E /* Sort.m in Sources */ = {isa = PBXBuildFile; fileRef = 08FB7796FE84155DC02AAC07 /* Sort.m */; settings = {ATTRIBUTES = (); }; };
8DD76F9C0486AA7600D96B5E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 08FB779EFE84155DC02AAC07 /* Foundation.framework */; };
8DD76F9F0486AA7600D96B5E /* Sort.1 in CopyFiles */ = {isa = PBXBuildFile; fileRef = C6859EA3029092ED04C91782 /* Sort.1 */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
8DD76F9E0486AA7600D96B5E /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 8;
dstPath = /usr/share/man/man1/;
dstSubfolderSpec = 0;
files = (
8DD76F9F0486AA7600D96B5E /* Sort.1 in CopyFiles */,
);
runOnlyForDeploymentPostprocessing = 1;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
08FB7796FE84155DC02AAC07 /* Sort.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Sort.m; sourceTree = "<group>"; };
08FB779EFE84155DC02AAC07 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; };
32A70AAB03705E1F00C91783 /* Sort_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Sort_Prefix.pch; sourceTree = "<group>"; };
8DD76FA10486AA7600D96B5E /* Sort */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = Sort; sourceTree = BUILT_PRODUCTS_DIR; };
C6859EA3029092ED04C91782 /* Sort.1 */ = {isa = PBXFileReference; lastKnownFileType = text.man; path = Sort.1; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
8DD76F9B0486AA7600D96B5E /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
8DD76F9C0486AA7600D96B5E /* Foundation.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
08FB7794FE84155DC02AAC07 /* Sort */ = {
isa = PBXGroup;
children = (
08FB7795FE84155DC02AAC07 /* Source */,
C6859EA2029092E104C91782 /* Documentation */,
08FB779DFE84155DC02AAC07 /* External Frameworks and Libraries */,
1AB674ADFE9D54B511CA2CBB /* Products */,
);
name = Sort;
sourceTree = "<group>";
};
08FB7795FE84155DC02AAC07 /* Source */ = {
isa = PBXGroup;
children = (
32A70AAB03705E1F00C91783 /* Sort_Prefix.pch */,
08FB7796FE84155DC02AAC07 /* Sort.m */,
);
name = Source;
sourceTree = "<group>";
};
08FB779DFE84155DC02AAC07 /* External Frameworks and Libraries */ = {
isa = PBXGroup;
children = (
08FB779EFE84155DC02AAC07 /* Foundation.framework */,
);
name = "External Frameworks and Libraries";
sourceTree = "<group>";
};
1AB674ADFE9D54B511CA2CBB /* Products */ = {
isa = PBXGroup;
children = (
8DD76FA10486AA7600D96B5E /* Sort */,
);
name = Products;
sourceTree = "<group>";
};
C6859EA2029092E104C91782 /* Documentation */ = {
isa = PBXGroup;
children = (
C6859EA3029092ED04C91782 /* Sort.1 */,
);
name = Documentation;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
8DD76F960486AA7600D96B5E /* Sort */ = {
isa = PBXNativeTarget;
buildConfigurationList = 1DEB927408733DD40010E9CD /* Build configuration list for PBXNativeTarget "Sort" */;
buildPhases = (
8DD76F990486AA7600D96B5E /* Sources */,
8DD76F9B0486AA7600D96B5E /* Frameworks */,
8DD76F9E0486AA7600D96B5E /* CopyFiles */,
);
buildRules = (
);
dependencies = (
);
name = Sort;
productInstallPath = "$(HOME)/bin";
productName = Sort;
productReference = 8DD76FA10486AA7600D96B5E /* Sort */;
productType = "com.apple.product-type.tool";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
08FB7793FE84155DC02AAC07 /* Project object */ = {
isa = PBXProject;
buildConfigurationList = 1DEB927808733DD40010E9CD /* Build configuration list for PBXProject "Sort" */;
compatibilityVersion = "Xcode 3.1";
hasScannedForEncodings = 1;
mainGroup = 08FB7794FE84155DC02AAC07 /* Sort */;
projectDirPath = "";
projectRoot = "";
targets = (
8DD76F960486AA7600D96B5E /* Sort */,
);
};
/* End PBXProject section */
/* Begin PBXSourcesBuildPhase section */
8DD76F990486AA7600D96B5E /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
8DD76F9A0486AA7600D96B5E /* Sort.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
1DEB927508733DD40010E9CD /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
COPY_PHASE_STRIP = NO;
GCC_DYNAMIC_NO_PIC = NO;
GCC_ENABLE_FIX_AND_CONTINUE = YES;
GCC_MODEL_TUNING = G5;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = Sort_Prefix.pch;
INSTALL_PATH = /usr/local/bin;
PRODUCT_NAME = Sort;
};
name = Debug;
};
1DEB927608733DD40010E9CD /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
GCC_MODEL_TUNING = G5;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = Sort_Prefix.pch;
INSTALL_PATH = /usr/local/bin;
PRODUCT_NAME = Sort;
};
name = Release;
};
1DEB927908733DD40010E9CD /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
GCC_ENABLE_OBJC_GC = required;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_VERSION = "";
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
ONLY_ACTIVE_ARCH = YES;
PREBINDING = NO;
};
name = Debug;
};
1DEB927A08733DD40010E9CD /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
GCC_ENABLE_OBJC_GC = required;
GCC_VERSION = "";
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
PREBINDING = NO;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
1DEB927408733DD40010E9CD /* Build configuration list for PBXNativeTarget "Sort" */ = {
isa = XCConfigurationList;
buildConfigurations = (
1DEB927508733DD40010E9CD /* Debug */,
1DEB927608733DD40010E9CD /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
1DEB927808733DD40010E9CD /* Build configuration list for PBXProject "Sort" */ = {
isa = XCConfigurationList;
buildConfigurations = (
1DEB927908733DD40010E9CD /* Debug */,
1DEB927A08733DD40010E9CD /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
}

View File

@ -0,0 +1,7 @@
//
// Prefix header for all source files of the 'Sort' target in the 'Sort' project.
//
#ifdef __OBJC__
#import <Foundation/Foundation.h>
#endif

View File

@ -0,0 +1,79 @@
.\"Modified from man(1) of FreeBSD, the NetBSD mdoc.template, and mdoc.samples.
.\"See Also:
.\"man mdoc.samples for a complete listing of options
.\"man mdoc for the short list of editing options
.\"/usr/share/misc/mdoc.template
.Dd 4/8/08 \" DATE
.Dt BasicByRef 1 \" Program name and manual section number
.Os Darwin
.Sh NAME \" Section Header - required - don't modify
.Nm BasicByRef,
.\" The following lines are read in generating the apropos(man -k) database. Use only key
.\" words here as the database is built based on the words here and in the .ND line.
.Nm Other_name_for_same_program(),
.Nm Yet another name for the same program.
.\" Use .Nm macro to designate other names for the documented program.
.Nd This line parsed for whatis database.
.Sh SYNOPSIS \" Section Header - required - don't modify
.Nm
.Op Fl abcd \" [-abcd]
.Op Fl a Ar path \" [-a path]
.Op Ar file \" [file]
.Op Ar \" [file ...]
.Ar arg0 \" Underlined argument - use .Ar anywhere to underline
arg2 ... \" Arguments
.Sh DESCRIPTION \" Section Header - required - don't modify
Use the .Nm macro to refer to your program throughout the man page like such:
.Nm
Underlining is accomplished with the .Ar macro like this:
.Ar underlined text .
.Pp \" Inserts a space
A list of items with descriptions:
.Bl -tag -width -indent \" Begins a tagged list
.It item a \" Each item preceded by .It macro
Description of item a
.It item b
Description of item b
.El \" Ends the list
.Pp
A list of flags and their descriptions:
.Bl -tag -width -indent \" Differs from above in tag removed
.It Fl a \"-a flag as a list item
Description of -a flag
.It Fl b
Description of -b flag
.El \" Ends the list
.Pp
.\" .Sh ENVIRONMENT \" May not be needed
.\" .Bl -tag -width "ENV_VAR_1" -indent \" ENV_VAR_1 is width of the string ENV_VAR_1
.\" .It Ev ENV_VAR_1
.\" Description of ENV_VAR_1
.\" .It Ev ENV_VAR_2
.\" Description of ENV_VAR_2
.\" .El
.Sh FILES \" File used or created by the topic of the man page
.Bl -tag -width "/Users/joeuser/Library/really_long_file_name" -compact
.It Pa /usr/share/file_name
FILE_1 description
.It Pa /Users/joeuser/Library/really_long_file_name
FILE_2 description
.El \" Ends the list
.\" .Sh DIAGNOSTICS \" May not be needed
.\" .Bl -diag
.\" .It Diagnostic Tag
.\" Diagnostic informtion here.
.\" .It Diagnostic Tag
.\" Diagnostic informtion here.
.\" .El
.Sh SEE ALSO
.\" List links in ascending order by section, alphabetically within a section.
.\" Please do not reference files that do not exist without filing a bug report
.Xr a 1 ,
.Xr b 1 ,
.Xr c 1 ,
.Xr a 2 ,
.Xr b 2 ,
.Xr a 3 ,
.Xr b 3
.\" .Sh BUGS \" Document known, unremedied bugs
.\" .Sh HISTORY \" Document history if command behaves in a unique manner

View File

@ -0,0 +1,57 @@
/*
* Copyright (c) 2010 Apple Inc. All rights reserved.
*
* @APPLE_LLVM_LICENSE_HEADER@
*/
#import <Foundation/Foundation.h>
static int globalCount = 0;
@interface Foo : NSObject {
int ivarCount;
}
- (void) incrementCount;
@end
@implementation Foo
- (void) incrementCount
{
int oldValue = ivarCount;
void (^incrementBlock)() = ^(){ivarCount++;};
incrementBlock();
if( (oldValue+1) != ivarCount )
NSLog(@"Hey, man. ivar was not incremented as expected. %d %d", oldValue, ivarCount);
}
@end
int main (int argc, const char * argv[]) {
int localCount = 0;
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
[[[[Foo alloc] init] autorelease] incrementCount];
void (^incrementLocal)() = ^(){
|localCount| // comment this out for an exciting compilation error on the next line (that is correct)
localCount++;
};
incrementLocal();
if( localCount != 1 )
NSLog(@"Hey, man. localCount was not incremented as expected. %d", localCount);
void (^incrementGlobal)() = ^() {
|globalCount| // this should not be necessary
globalCount++;
};
incrementGlobal();
if( globalCount != 1 )
NSLog(@"Hey, man. globalCount was not incremented as expected. %d", globalCount);
[pool drain];
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,145 @@
// !$*UTF8*$!
{
08FB7793FE84155DC02AAC07 /* Project object */ = {
activeArchitecture = ppc;
activeBuildConfigurationName = Debug;
activeExecutable = 77925DB40DABECC2004B971B /* BasicByRef */;
activeTarget = 8DD76F960486AA7600D96B5E /* BasicByRef */;
codeSenseManager = 77925DBE0DABECC8004B971B /* Code sense */;
executables = (
77925DB40DABECC2004B971B /* BasicByRef */,
);
perUserDictionary = {
PBXConfiguration.PBXFileTableDataSource3.PBXFileTableDataSource = {
PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID;
PBXFileTableDataSourceColumnWidthsKey = (
20,
586,
20,
48,
43,
43,
20,
);
PBXFileTableDataSourceColumnsKey = (
PBXFileDataSource_FiletypeID,
PBXFileDataSource_Filename_ColumnID,
PBXFileDataSource_Built_ColumnID,
PBXFileDataSource_ObjectSize_ColumnID,
PBXFileDataSource_Errors_ColumnID,
PBXFileDataSource_Warnings_ColumnID,
PBXFileDataSource_Target_ColumnID,
);
};
PBXConfiguration.PBXTargetDataSource.PBXTargetDataSource = {
PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID;
PBXFileTableDataSourceColumnWidthsKey = (
20,
546,
60,
20,
48.16259765625,
43,
43,
);
PBXFileTableDataSourceColumnsKey = (
PBXFileDataSource_FiletypeID,
PBXFileDataSource_Filename_ColumnID,
PBXTargetDataSource_PrimaryAttribute,
PBXFileDataSource_Built_ColumnID,
PBXFileDataSource_ObjectSize_ColumnID,
PBXFileDataSource_Errors_ColumnID,
PBXFileDataSource_Warnings_ColumnID,
);
};
PBXPerProjectTemplateStateSaveDate = 229649840;
PBXWorkspaceStateSaveDate = 229649840;
};
perUserProjectItems = {
77C0DD720DABF23F000C759A = 77C0DD720DABF23F000C759A /* PBXTextBookmark */;
77C0DD7C0DABF275000C759A = 77C0DD7C0DABF275000C759A /* PBXTextBookmark */;
77C0DD960DABF56C000C759A = 77C0DD960DABF56C000C759A /* PBXTextBookmark */;
};
sourceControlManager = 77925DBD0DABECC8004B971B /* Source Control */;
userBuildSettings = {
};
};
08FB7796FE84155DC02AAC07 /* BasicByRef.m */ = {
uiCtxt = {
sepNavIntBoundsRect = "{{0, 0}, {1028, 848}}";
sepNavSelRange = "{1226, 0}";
sepNavVisRange = "{0, 1261}";
};
};
77925DB40DABECC2004B971B /* BasicByRef */ = {
isa = PBXExecutable;
activeArgIndices = (
);
argumentStrings = (
);
autoAttachOnCrash = 1;
breakpointsEnabled = 0;
configStateDict = {
};
customDataFormattersEnabled = 1;
debuggerPlugin = GDBDebugging;
disassemblyDisplayState = 0;
dylibVariantSuffix = "";
enableDebugStr = 1;
environmentEntries = (
);
executableSystemSymbolLevel = 0;
executableUserSymbolLevel = 0;
libgmallocEnabled = 0;
name = BasicByRef;
sourceDirectories = (
);
};
77925DBD0DABECC8004B971B /* Source Control */ = {
isa = PBXSourceControlManager;
fallbackIsa = XCSourceControlManager;
isSCMEnabled = 0;
scmConfiguration = {
};
};
77925DBE0DABECC8004B971B /* Code sense */ = {
isa = PBXCodeSenseManager;
indexTemplatePath = "";
};
77C0DD720DABF23F000C759A /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
comments = "error: 'incrementBlock' undeclared (first use in this function)";
fRef = 08FB7796FE84155DC02AAC07 /* BasicByRef.m */;
rLen = 1;
rLoc = 16;
rType = 1;
};
77C0DD7C0DABF275000C759A /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 08FB7796FE84155DC02AAC07 /* BasicByRef.m */;
name = "BasicByRef.m: 17";
rLen = 205;
rLoc = 227;
rType = 0;
vrLen = 458;
vrLoc = 0;
};
77C0DD960DABF56C000C759A /* PBXTextBookmark */ = {
isa = PBXTextBookmark;
fRef = 08FB7796FE84155DC02AAC07 /* BasicByRef.m */;
name = "BasicByRef.m: 48";
rLen = 0;
rLoc = 1226;
rType = 0;
vrLen = 1261;
vrLoc = 0;
};
8DD76F960486AA7600D96B5E /* BasicByRef */ = {
activeExec = 0;
executables = (
77925DB40DABECC2004B971B /* BasicByRef */,
);
};
}

View File

@ -0,0 +1,228 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 44;
objects = {
/* Begin PBXBuildFile section */
8DD76F9A0486AA7600D96B5E /* BasicByRef.m in Sources */ = {isa = PBXBuildFile; fileRef = 08FB7796FE84155DC02AAC07 /* BasicByRef.m */; settings = {ATTRIBUTES = (); }; };
8DD76F9C0486AA7600D96B5E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 08FB779EFE84155DC02AAC07 /* Foundation.framework */; };
8DD76F9F0486AA7600D96B5E /* BasicByRef.1 in CopyFiles */ = {isa = PBXBuildFile; fileRef = C6859EA3029092ED04C91782 /* BasicByRef.1 */; };
/* End PBXBuildFile section */
/* Begin PBXBuildRule section */
77925DCF0DABEED1004B971B /* PBXBuildRule */ = {
isa = PBXBuildRule;
compilerSpec = com.apple.compilers.gcc.4_2;
fileType = sourcecode.c;
isEditable = 1;
outputFiles = (
);
};
/* End PBXBuildRule section */
/* Begin PBXCopyFilesBuildPhase section */
8DD76F9E0486AA7600D96B5E /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 8;
dstPath = /usr/share/man/man1/;
dstSubfolderSpec = 0;
files = (
8DD76F9F0486AA7600D96B5E /* BasicByRef.1 in CopyFiles */,
);
runOnlyForDeploymentPostprocessing = 1;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
08FB7796FE84155DC02AAC07 /* BasicByRef.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BasicByRef.m; sourceTree = "<group>"; };
08FB779EFE84155DC02AAC07 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; };
32A70AAB03705E1F00C91783 /* BasicByRef_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BasicByRef_Prefix.pch; sourceTree = "<group>"; };
8DD76FA10486AA7600D96B5E /* BasicByRef */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = BasicByRef; sourceTree = BUILT_PRODUCTS_DIR; };
C6859EA3029092ED04C91782 /* BasicByRef.1 */ = {isa = PBXFileReference; lastKnownFileType = text.man; path = BasicByRef.1; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
8DD76F9B0486AA7600D96B5E /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
8DD76F9C0486AA7600D96B5E /* Foundation.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
08FB7794FE84155DC02AAC07 /* BasicByRef */ = {
isa = PBXGroup;
children = (
08FB7795FE84155DC02AAC07 /* Source */,
C6859EA2029092E104C91782 /* Documentation */,
08FB779DFE84155DC02AAC07 /* External Frameworks and Libraries */,
1AB674ADFE9D54B511CA2CBB /* Products */,
);
name = BasicByRef;
sourceTree = "<group>";
};
08FB7795FE84155DC02AAC07 /* Source */ = {
isa = PBXGroup;
children = (
32A70AAB03705E1F00C91783 /* BasicByRef_Prefix.pch */,
08FB7796FE84155DC02AAC07 /* BasicByRef.m */,
);
name = Source;
sourceTree = "<group>";
};
08FB779DFE84155DC02AAC07 /* External Frameworks and Libraries */ = {
isa = PBXGroup;
children = (
08FB779EFE84155DC02AAC07 /* Foundation.framework */,
);
name = "External Frameworks and Libraries";
sourceTree = "<group>";
};
1AB674ADFE9D54B511CA2CBB /* Products */ = {
isa = PBXGroup;
children = (
8DD76FA10486AA7600D96B5E /* BasicByRef */,
);
name = Products;
sourceTree = "<group>";
};
C6859EA2029092E104C91782 /* Documentation */ = {
isa = PBXGroup;
children = (
C6859EA3029092ED04C91782 /* BasicByRef.1 */,
);
name = Documentation;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
8DD76F960486AA7600D96B5E /* BasicByRef */ = {
isa = PBXNativeTarget;
buildConfigurationList = 1DEB927408733DD40010E9CD /* Build configuration list for PBXNativeTarget "BasicByRef" */;
buildPhases = (
8DD76F990486AA7600D96B5E /* Sources */,
8DD76F9B0486AA7600D96B5E /* Frameworks */,
8DD76F9E0486AA7600D96B5E /* CopyFiles */,
);
buildRules = (
77925DCF0DABEED1004B971B /* PBXBuildRule */,
);
dependencies = (
);
name = BasicByRef;
productInstallPath = "$(HOME)/bin";
productName = BasicByRef;
productReference = 8DD76FA10486AA7600D96B5E /* BasicByRef */;
productType = "com.apple.product-type.tool";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
08FB7793FE84155DC02AAC07 /* Project object */ = {
isa = PBXProject;
buildConfigurationList = 1DEB927808733DD40010E9CD /* Build configuration list for PBXProject "BasicByRef" */;
compatibilityVersion = "Xcode 3.0";
hasScannedForEncodings = 1;
mainGroup = 08FB7794FE84155DC02AAC07 /* BasicByRef */;
projectDirPath = "";
projectRoot = "";
targets = (
8DD76F960486AA7600D96B5E /* BasicByRef */,
);
};
/* End PBXProject section */
/* Begin PBXSourcesBuildPhase section */
8DD76F990486AA7600D96B5E /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
8DD76F9A0486AA7600D96B5E /* BasicByRef.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
1DEB927508733DD40010E9CD /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
COPY_PHASE_STRIP = NO;
GCC_DYNAMIC_NO_PIC = NO;
GCC_ENABLE_FIX_AND_CONTINUE = YES;
GCC_MODEL_TUNING = G5;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = BasicByRef_Prefix.pch;
INSTALL_PATH = /usr/local/bin;
PRODUCT_NAME = BasicByRef;
ZERO_LINK = YES;
};
name = Debug;
};
1DEB927608733DD40010E9CD /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
GCC_MODEL_TUNING = G5;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = BasicByRef_Prefix.pch;
INSTALL_PATH = /usr/local/bin;
PRODUCT_NAME = BasicByRef;
};
name = Release;
};
1DEB927908733DD40010E9CD /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
PREBINDING = NO;
};
name = Debug;
};
1DEB927A08733DD40010E9CD /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = (
ppc,
i386,
);
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
PREBINDING = NO;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
1DEB927408733DD40010E9CD /* Build configuration list for PBXNativeTarget "BasicByRef" */ = {
isa = XCConfigurationList;
buildConfigurations = (
1DEB927508733DD40010E9CD /* Debug */,
1DEB927608733DD40010E9CD /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
1DEB927808733DD40010E9CD /* Build configuration list for PBXProject "BasicByRef" */ = {
isa = XCConfigurationList;
buildConfigurations = (
1DEB927908733DD40010E9CD /* Debug */,
1DEB927A08733DD40010E9CD /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
}

View File

@ -0,0 +1,7 @@
//
// Prefix header for all source files of the 'BasicByRef' target in the 'BasicByRef' project.
//
#ifdef __OBJC__
#import <Foundation/Foundation.h>
#endif

20
RewriterBlockTest/BlockTest.sln Executable file
View File

@ -0,0 +1,20 @@

Microsoft Visual Studio Solution File, Format Version 9.00
# Visual C++ Express 2005
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BlockTest", "BlockTest\BlockTest.vcproj", "{DA281F69-15D4-4DB7-A606-E8AC845F4E72}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{DA281F69-15D4-4DB7-A606-E8AC845F4E72}.Debug|Win32.ActiveCfg = Debug|Win32
{DA281F69-15D4-4DB7-A606-E8AC845F4E72}.Debug|Win32.Build.0 = Debug|Win32
{DA281F69-15D4-4DB7-A606-E8AC845F4E72}.Release|Win32.ActiveCfg = Release|Win32
{DA281F69-15D4-4DB7-A606-E8AC845F4E72}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,19 @@
/*
* Copyright (c) 2010 Apple Inc. All rights reserved.
*
* @APPLE_LLVM_LICENSE_HEADER@
*/
// BlockTest.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
extern int main(int argc, _TCHAR *argv[]);
int _tmain(int argc, _TCHAR* argv[])
{
main(argc, argv);
return 0;
}

View File

@ -0,0 +1,216 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="BlockTest"
ProjectGUID="{DA281F69-15D4-4DB7-A606-E8AC845F4E72}"
RootNamespace="BlockTest"
Keyword="Win32Proj"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="&quot;$(SRCROOT)\AppleInternal\include&quot;;&quot;$(DSTROOT)\AppleInternal\include&quot;"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="kernel32.lib $(NoInherit)"
LinkIncremental="2"
GenerateDebugInformation="true"
SubSystem="1"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
RuntimeLibrary="2"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="kernel32.lib $(NoInherit)"
LinkIncremental="1"
GenerateDebugInformation="true"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=".\BlockTest.cpp"
>
</File>
<File
RelativePath="..\simpleblock.cpp"
>
</File>
<File
RelativePath=".\stdafx.cpp"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath=".\stdafx.h"
>
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
>
</Filter>
<File
RelativePath=".\ReadMe.txt"
>
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -0,0 +1,14 @@
/*
* Copyright (c) 2010 Apple Inc. All rights reserved.
*
* @APPLE_LLVM_LICENSE_HEADER@
*/
// stdafx.cpp : source file that includes just the standard includes
// BlockTest.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"
// TODO: reference any additional headers you need in STDAFX.H
// and not in this file

View File

@ -0,0 +1,23 @@
/*
* Copyright (c) 2010 Apple Inc. All rights reserved.
*
* @APPLE_LLVM_LICENSE_HEADER@
*/
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#pragma once
#ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later.
#define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows.
#endif
#include <stdio.h>
#include <tchar.h>
// TODO: reference additional headers your program requires here

View File

@ -0,0 +1,15 @@
This is a basic test of blocks on windows.
To use:
- modify the simpleblock.c file accordingly (or make a new one)
- run the clang command line as specified in that source file
- open the Visual Studio project
- open the resulting .cpp file and uncomment various commented out bits
- attempt to compile and run
Assumes that AppleInternal has been populated and the libclosure project has been built.

31
RewriterBlockTest/simpleblock.c Executable file
View File

@ -0,0 +1,31 @@
/*
* Copyright (c) 2010 Apple Inc. All rights reserved.
*
* @APPLE_LLVM_LICENSE_HEADER@
*/
// ..\clang -rewrite-objc -fms-extensions simpleblock.c
// #include <iostream>
// using namespace std;
// #include "Block.h"
int main(int argc, char **argv) {
void(^aBlock)(int x);
void(^bBlock)(int x);
aBlock = ^(int x) {
// cout << "Hello, " << x << endl;
};
aBlock(42);
bBlock = (void *)Block_copy(aBlock);
bBlock(46);
Block_release(bBlock);
return 0;
}

135
RewriterBlockTest/simpleblock.cpp Executable file
View File

@ -0,0 +1,135 @@
/*
* Copyright (c) 2010 Apple Inc. All rights reserved.
*
* @APPLE_LLVM_LICENSE_HEADER@
*/
struct objc_selector; struct objc_class;
#ifndef OBJC_SUPER
struct objc_super { struct objc_object *object; struct objc_object *superClass; objc_super(struct objc_object *o, struct objc_object *s) : object(o), superClass(s) {} };
#define OBJC_SUPER
#endif
#ifndef _REWRITER_typedef_Protocol
typedef struct objc_object Protocol;
#define _REWRITER_typedef_Protocol
#endif
#define __OBJC_RW_EXTERN extern "C" __declspec(dllimport)
__OBJC_RW_EXTERN struct objc_object *objc_msgSend(struct objc_object *, struct objc_selector *, ...);
__OBJC_RW_EXTERN struct objc_object *objc_msgSendSuper(struct objc_super *, struct objc_selector *, ...);
__OBJC_RW_EXTERN struct objc_object *objc_msgSend_stret(struct objc_object *, struct objc_selector *, ...);
__OBJC_RW_EXTERN struct objc_object *objc_msgSendSuper_stret(struct objc_super *, struct objc_selector *, ...);
__OBJC_RW_EXTERN double objc_msgSend_fpret(struct objc_object *, struct objc_selector *, ...);
__OBJC_RW_EXTERN struct objc_object *objc_getClass(const char *);
__OBJC_RW_EXTERN struct objc_object *objc_getMetaClass(const char *);
__OBJC_RW_EXTERN void objc_exception_throw(struct objc_object *);
__OBJC_RW_EXTERN void objc_exception_try_enter(void *);
__OBJC_RW_EXTERN void objc_exception_try_exit(void *);
__OBJC_RW_EXTERN struct objc_object *objc_exception_extract(void *);
__OBJC_RW_EXTERN int objc_exception_match(struct objc_class *, struct objc_object *);
__OBJC_RW_EXTERN void objc_sync_enter(struct objc_object *);
__OBJC_RW_EXTERN void objc_sync_exit(struct objc_object *);
__OBJC_RW_EXTERN Protocol *objc_getProtocol(const char *);
#ifndef __FASTENUMERATIONSTATE
struct __objcFastEnumerationState {
unsigned long state;
void **itemsPtr;
unsigned long *mutationsPtr;
unsigned long extra[5];
};
__OBJC_RW_EXTERN void objc_enumerationMutation(struct objc_object *);
#define __FASTENUMERATIONSTATE
#endif
#ifndef __NSCONSTANTSTRINGIMPL
struct __NSConstantStringImpl {
int *isa;
int flags;
char *str;
long length;
};
#ifdef CF_EXPORT_CONSTANT_STRING
extern "C" __declspec(dllexport) int __CFConstantStringClassReference[];
#else
__OBJC_RW_EXTERN int __CFConstantStringClassReference[];
#endif
#define __NSCONSTANTSTRINGIMPL
#endif
#ifndef BLOCK_IMPL
#define BLOCK_IMPL
struct __block_impl {
void *isa;
int Flags;
int Size;
void *FuncPtr;
};
enum {
BLOCK_HAS_COPY_DISPOSE = (1<<25),
BLOCK_IS_GLOBAL = (1<<28)
};
// Runtime copy/destroy helper functions
__OBJC_RW_EXTERN void _Block_copy_assign(void *, void *);
__OBJC_RW_EXTERN void _Block_byref_assign_copy(void *, void *);
__OBJC_RW_EXTERN void _Block_destroy(void *);
__OBJC_RW_EXTERN void _Block_byref_release(void *);
__OBJC_RW_EXTERN void *_NSConcreteGlobalBlock;
__OBJC_RW_EXTERN void *_NSConcreteStackBlock;
#endif
#undef __OBJC_RW_EXTERN
#define __attribute__(X)
// ..\clang -rewrite-objc -fms-extensions simpleblock.c
#include <iostream>
using namespace std;
#include "Block.h"
struct __main_block_impl_0 {
struct __block_impl impl;
__main_block_impl_0(void *fp, int flags=0) {
impl.isa = 0/*&_NSConcreteStackBlock*/;
impl.Size = sizeof(__main_block_impl_0);
impl.Flags = flags;
impl.FuncPtr = fp;
}
};
static void __main_block_func_0(struct __main_block_impl_0 *__cself, int x) {
cout << "Hello, " << x << endl;
}
int main(int argc, char **argv) {
void(*aBlock)(int x);
void(*bBlock)(int x);
aBlock = (void (*)(int))&__main_block_impl_0((void *)__main_block_func_0);
((void (*)(struct __block_impl *, int))((struct __block_impl *)aBlock)->FuncPtr)((struct __block_impl *)aBlock, 42);
bBlock = (void *)Block_copy(aBlock);
((void (*)(struct __block_impl *, int))((struct __block_impl *)bBlock)->FuncPtr)((struct __block_impl *)bBlock, 46);
Block_release(bBlock);
return 0;
}

24
data.c Normal file
View File

@ -0,0 +1,24 @@
/*
* data.c
* libclosure
*
* Copyright (c) 2008-2010 Apple Inc. All rights reserved.
*
* @APPLE_LLVM_LICENSE_HEADER@
*
*/
/********************
NSBlock support
We allocate space and export a symbol to be used as the Class for the on-stack and malloc'ed copies until ObjC arrives on the scene. These data areas are set up by Foundation to link in as real classes post facto.
We keep these in a separate file so that we can include the runtime code in test subprojects but not include the data so that compiled code that sees the data in libSystem doesn't get confused by a second copy. Somehow these don't get unified in a common block.
**********************/
void * _NSConcreteStackBlock[32] = { 0 };
void * _NSConcreteMallocBlock[32] = { 0 };
void * _NSConcreteAutoBlock[32] = { 0 };
void * _NSConcreteFinalizingBlock[32] = { 0 };
void * _NSConcreteGlobalBlock[32] = { 0 };
void * _NSConcreteWeakBlockVariable[32] = { 0 };

View File

@ -0,0 +1,148 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 45;
objects = {
/* Begin PBXFileReference section */
18D15B250E01B54B0048DAED /* escape.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = escape.m; sourceTree = "<group>"; };
18D15B260E01BC860048DAED /* makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; path = makefile; sourceTree = "<group>"; };
18D15B3F0E01C2690048DAED /* common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = common.h; sourceTree = "<group>"; };
18D15B430E01C4F50048DAED /* escape2.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = escape2.m; sourceTree = "<group>"; };
18D15B460E01C6C70048DAED /* escape3.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = escape3.m; sourceTree = "<group>"; };
18D15B4D0E01CB2C0048DAED /* escape4.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = escape4.m; sourceTree = "<group>"; };
18D15B500E01D0380048DAED /* common.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = common.m; sourceTree = "<group>"; };
BC1A63BE0E54F29B00951881 /* escape5.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = escape5.m; sourceTree = "<group>"; };
BC1A63C00E54F3A700951881 /* escape6.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = escape6.m; sourceTree = "<group>"; };
BC1A63DF0E54F6CE00951881 /* escape7.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = escape7.m; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXGroup section */
08FB7794FE84155DC02AAC07 /* btest */ = {
isa = PBXGroup;
children = (
BC1A63DF0E54F6CE00951881 /* escape7.m */,
BC1A63C00E54F3A700951881 /* escape6.m */,
18D15B4D0E01CB2C0048DAED /* escape4.m */,
BC1A63BE0E54F29B00951881 /* escape5.m */,
18D15B460E01C6C70048DAED /* escape3.m */,
18D15B260E01BC860048DAED /* makefile */,
18D15B250E01B54B0048DAED /* escape.m */,
18D15B430E01C4F50048DAED /* escape2.m */,
18D15B3F0E01C2690048DAED /* common.h */,
18D15B500E01D0380048DAED /* common.m */,
);
name = btest;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXLegacyTarget section */
D28A88AD04BDD90700651E21 /* btest */ = {
isa = PBXLegacyTarget;
buildArgumentsString = "$(ACTION)";
buildConfigurationList = 1DEB918F08733D9F0010E9CD /* Build configuration list for PBXLegacyTarget "btest" */;
buildPhases = (
);
buildToolPath = /usr/bin/make;
dependencies = (
);
name = btest;
passBuildSettingsInEnvironment = 1;
productName = btest;
};
/* End PBXLegacyTarget section */
/* Begin PBXProject section */
08FB7793FE84155DC02AAC07 /* Project object */ = {
isa = PBXProject;
buildConfigurationList = 1DEB919308733D9F0010E9CD /* Build configuration list for PBXProject "btest" */;
compatibilityVersion = "Xcode 3.1";
hasScannedForEncodings = 1;
mainGroup = 08FB7794FE84155DC02AAC07 /* btest */;
projectDirPath = "";
projectRoot = "";
projectRoots = (
"",
);
targets = (
D28A88AD04BDD90700651E21 /* btest */,
);
};
/* End PBXProject section */
/* Begin XCBuildConfiguration section */
1DEB919008733D9F0010E9CD /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
COPY_PHASE_STRIP = NO;
DEBUGGING_SYMBOLS = YES;
GCC_DYNAMIC_NO_PIC = NO;
GCC_ENABLE_FIX_AND_CONTINUE = YES;
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
OTHER_CFLAGS = "";
OTHER_LDFLAGS = "";
PRODUCT_NAME = btest;
};
name = Debug;
};
1DEB919108733D9F0010E9CD /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
COPY_PHASE_STRIP = YES;
GCC_ENABLE_FIX_AND_CONTINUE = NO;
OTHER_CFLAGS = "";
OTHER_LDFLAGS = "";
PRODUCT_NAME = btest;
};
name = Release;
};
1DEB919408733D9F0010E9CD /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
ONLY_ACTIVE_ARCH = YES;
PREBINDING = NO;
};
name = Debug;
};
1DEB919508733D9F0010E9CD /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_BIT)";
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
PREBINDING = NO;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
1DEB918F08733D9F0010E9CD /* Build configuration list for PBXLegacyTarget "btest" */ = {
isa = XCConfigurationList;
buildConfigurations = (
1DEB919008733D9F0010E9CD /* Debug */,
1DEB919108733D9F0010E9CD /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
1DEB919308733D9F0010E9CD /* Build configuration list for PBXProject "btest" */ = {
isa = XCConfigurationList;
buildConfigurations = (
1DEB919408733D9F0010E9CD /* Debug */,
1DEB919508733D9F0010E9CD /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
}

23
escapeTests/common.h Executable file
View File

@ -0,0 +1,23 @@
/*
* Copyright (c) 2010 Apple Inc. All rights reserved.
*
* @APPLE_LLVM_LICENSE_HEADER@
*/
#import <Foundation/Foundation.h>
#import <Block.h>
#define HASBYREF 1
#if HASBYREF
#define BYREF __block
#else
#define BYREF
#endif
typedef void (^vv)(void);
// do we have a non-gc escaping compiler?
#define FARIBORZ 1
extern void lastUse(int param);

32
escapeTests/common.m Executable file
View File

@ -0,0 +1,32 @@
/*
* Copyright (c) 2010 Apple Inc. All rights reserved.
*
* @APPLE_LLVM_LICENSE_HEADER@
*/
#import "common.h"
int useCounter = 0;
void lastUse(int param) {
++useCounter;
}
int bcounter = 0;
#if FARIBORZ
void _Block_byref_release(void *byrefblock) {
++bcounter;
}
#endif
int main(int argc, char *argv[]) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
test();
if (bcounter != useCounter) {
printf("%s: byref block not released %d times: %d\n", argv[0], useCounter, bcounter);
return 1;
}
printf("%s: ok\n", argv[0]);
[pool drain];
return 0;
}

26
escapeTests/escape.m Executable file
View File

@ -0,0 +1,26 @@
/*
* Copyright (c) 2010 Apple Inc. All rights reserved.
*
* @APPLE_LLVM_LICENSE_HEADER@
*/
//
// escape.m
// btest
//
// Created by Apple on 6/12/08.
// Copyright 2008 Apple. All rights reserved.
//
#import "common.h"
void test(void) {
__block int i = 0;
vv block = ^{ ++i; };
vv blockCopy = Block_copy(block);
lastUse(i);
Block_release(blockCopy);
lastUse(i);
}

37
escapeTests/escape2.m Executable file
View File

@ -0,0 +1,37 @@
/*
* Copyright (c) 2010 Apple Inc. All rights reserved.
*
* @APPLE_LLVM_LICENSE_HEADER@
*/
//
// escape2.m
// btest
//
// Created by Apple on 6/12/08.
// Copyright 2008 __MyCompanyName__. All rights reserved.
//
#import "common.h"
void test(void) {
// validate that escaping a context is enough
if (getpid() % 2) {
BYREF int i = 0;
vv block = ^{ ++i; };
vv blockCopy = Block_copy(block);
lastUse(i);
Block_release(blockCopy);
lastUse(i);
}
else {
BYREF int j = 0;
vv block = ^{ j += 2; };
vv blockCopy = Block_copy(block);
lastUse(j);
Block_release(blockCopy);
lastUse(j);
}
}

29
escapeTests/escape3.m Executable file
View File

@ -0,0 +1,29 @@
/*
* Copyright (c) 2010 Apple Inc. All rights reserved.
*
* @APPLE_LLVM_LICENSE_HEADER@
*/
//
// escape2.m
// btest
//
// Created by Apple on 6/12/08.
// Copyright 2008 __MyCompanyName__. All rights reserved.
//
#import "common.h"
void test(void) {
// validate that escaping a context is enough
for (int counter = 0; counter < 10; ++counter) {
BYREF int i = 0;
vv block = ^{ ++i; };
if (i < 9) {
lastUse(i);
continue; // leave scope early
}
lastUse(i);
}
}

34
escapeTests/escape4.m Executable file
View File

@ -0,0 +1,34 @@
/*
* Copyright (c) 2010 Apple Inc. All rights reserved.
*
* @APPLE_LLVM_LICENSE_HEADER@
*/
//
// escape2.m
// btest
//
// Created by Apple on 6/12/08.
// Copyright 2008 __MyCompanyName__. All rights reserved.
//
#import "common.h"
void test(void) {
// validate that escaping a context is enough
int counter = 0;
while (counter < 10) {
BYREF int i = 0;
vv block = ^{ ++i; };
if (counter > 5) {
lastUse(i);
break;
}
++counter;
lastUse(i);
}
}

33
escapeTests/escape5.m Normal file
View File

@ -0,0 +1,33 @@
/*
* Copyright (c) 2010 Apple Inc. All rights reserved.
*
* @APPLE_LLVM_LICENSE_HEADER@
*/
//
// escape5.m
// btest
//
// Created by Apple on 6/12/08.
// Copyright 2008 __MyCompanyName__. All rights reserved.
//
#import "common.h"
void willThrow() {
@throw [NSException exceptionWithName:@"funny" reason:@"nothing" userInfo:nil];
}
void test(void) {
BYREF int i = 0;
@try {
willThrow();
}
@catch(...) {
}
lastUse(i);
}

41
escapeTests/escape6.m Normal file
View File

@ -0,0 +1,41 @@
/*
* Copyright (c) 2010 Apple Inc. All rights reserved.
*
* @APPLE_LLVM_LICENSE_HEADER@
*/
//
// escape5.m
// btest
//
// Created by Apple on 6/12/08.
// Copyright 2008 __MyCompanyName__. All rights reserved.
//
#import "common.h"
void willThrow() {
@throw [NSException exceptionWithName:@"funny" reason:@"nothing" userInfo:nil];
}
void innocent() {
__block int i;
@try {
lastUse(i);
willThrow();
}
@finally {
}
}
void test(void) {
@try {
innocent();
}
@catch(...) {
}
}

37
escapeTests/escape7.m Normal file
View File

@ -0,0 +1,37 @@
/*
* Copyright (c) 2010 Apple Inc. All rights reserved.
*
* @APPLE_LLVM_LICENSE_HEADER@
*/
//
// escape5.m
// btest
//
// Created by Apple on 6/12/08.
// Copyright 2008 __MyCompanyName__. All rights reserved.
//
#import "common.h"
void willThrow() {
@throw [NSException exceptionWithName:@"funny" reason:@"nothing" userInfo:nil];
}
void innocent() {
__block int i;
lastUse(i);
willThrow();
}
void test(void) {
@try {
innocent();
}
@catch(...) {
}
}

29
escapeTests/makefile Executable file
View File

@ -0,0 +1,29 @@
.SUFFIXES: .gc32 .32
GCC=/usr/bin/gcc
SRC = escape.m escape2.m escape3.m escape4.m escape5.m escape6.m
first: all
ALL = $(SRC:.m=.32)
$(ALL): common.o
.m.gc32:
$(GCC) $< -g -std=gnu99 -fobjc-gc-only -o $@ common.o -framework Foundation
.m.32:
$(GCC) $< -g -std=gnu99 -o $@ common.o -framework Foundation
all: $(ALL)
./escape.32
./escape2.32
./escape3.32
./escape4.32
./escape5.32
./escape6.32
clean:
rm -fr *.o $(ALL) *.dSYM
common.o: common.m
$(GCC) -std=gnu99 -fobjc-gc -g -c common.m

View File

@ -0,0 +1,20 @@

Microsoft Visual Studio Solution File, Format Version 9.00
# Visual C++ Express 2005
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libclosure-vs2005", "libclosure-vs2005.vcproj", "{421DE8BE-B071-4B94-AA47-86B4F45E1F97}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{421DE8BE-B071-4B94-AA47-86B4F45E1F97}.Debug|Win32.ActiveCfg = Debug|Win32
{421DE8BE-B071-4B94-AA47-86B4F45E1F97}.Debug|Win32.Build.0 = Debug|Win32
{421DE8BE-B071-4B94-AA47-86B4F45E1F97}.Release|Win32.ActiveCfg = Release|Win32
{421DE8BE-B071-4B94-AA47-86B4F45E1F97}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,196 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="libclosure"
ProjectGUID="{421DE8BE-B071-4B94-AA47-86B4F45E1F97}"
RootNamespace="libclosure"
Keyword="Win32Proj"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
Description="Install"
CommandLine="xcopy /Y &quot;$(ProjectDir)\..\Block.h&quot; &quot;%DSTROOT%\AppleInternal\include\&quot;&#x0D;&#x0A;xcopy /Y &quot;$(ProjectDir)\..\Block_private.h&quot; &quot;%DSTROOT%\AppleInternal\include\&quot;&#x0D;&#x0A;"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="&quot;$(SRCROOT)\AppleInternal\include&quot;;&quot;$(DSTROOT)\AppleInternal\include&quot;"
PreprocessorDefinitions="WIN32;_DEBUG;_LIB;BUILDING_BLOCK"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
OutputFile="$(OutDir)\$(ProjectName)_debug.lib"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
Description="Install"
CommandLine="xcopy /Y &quot;$(OutDir)\$(ProjectName)_debug.lib&quot; &quot;%DSTROOT%\AppleInternal\lib\&quot;"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
IntermediateDirectory="$(ConfigurationName)"
ConfigurationType="4"
CharacterSet="1"
WholeProgramOptimization="1"
>
<Tool
Name="VCPreBuildEventTool"
Description="Install"
CommandLine="xcopy /Y &quot;$(ProjectDir)\..\Block.h&quot; &quot;%DSTROOT%\AppleInternal\include\&quot;&#x0D;&#x0A;xcopy /Y &quot;$(ProjectDir)\..\Block_private.h&quot; &quot;%DSTROOT%\AppleInternal\include\&quot;&#x0D;&#x0A;"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="&quot;$(SRCROOT)\AppleInternal\include&quot;;&quot;$(DSTROOT)\AppleInternal\include&quot;"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;BUILDING_BLOCK"
RuntimeLibrary="2"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
Description="Install"
CommandLine="xcopy /Y &quot;$(OutDir)\$(ProjectName).lib&quot; &quot;%DSTROOT%\AppleInternal\lib\&quot;"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath="..\data.c"
>
</File>
<File
RelativePath="..\runtime.c"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath="..\Block.h"
>
</File>
<File
RelativePath="..\Block_private.h"
>
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
>
</Filter>
<File
RelativePath=".\ReadMe.txt"
>
</File>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -0,0 +1,84 @@
/*
* Copyright (c) 2010 Apple Inc. All rights reserved.
*
* @APPLE_LLVM_LICENSE_HEADER@
*/
//
// __blockObjectAssign.m
// testObjects
//
// Created by Blaine Garst on 2/5/09.
// Copyright 2009 Apple. All rights reserved.
//
// TEST_CFLAGS -framework Foundation
// tests whether assigning to a __block id variable works in a reasonable way
#import <Foundation/Foundation.h>
#import <stdio.h>
#import <Block.h>
#import "test.h"
@interface TestObject : NSObject {
int version;
}
- (void)hi;
@end
int AllocationCounter = 0;
int DellocationCounter = 0;
@implementation TestObject
- (id)init {
version = AllocationCounter++;
return self;
}
- (void)hi {
//printf("hi from %p, #%d\n", self, version);
}
- (void)dealloc {
//printf("dealloc %p, #%d called\n", self, version);
++DellocationCounter;
[super dealloc];
}
@end
void testFunction(bool doExecute, bool doCopy) {
__block id a = [[TestObject alloc] init];
//printf("testing - will execute? %d\n", doExecute);
void (^changeA)(void) = ^{
[a hi];
[a release];
a = [[TestObject alloc] init];
[a hi];
};
if (doCopy) changeA = [changeA copy];
if (doExecute) changeA();
if (doCopy) [changeA release];
[a release];
//printf("done with explict releasing, implicit to follow\n");
}
int main() {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
testFunction(false, true);
testFunction(true, true);
testFunction(false, false);
testFunction(true, true);
[pool drain];
if (DellocationCounter != AllocationCounter) {
fail("only recovered %d of %d objects", DellocationCounter, AllocationCounter);
}
succeed(__FILE__);
}

View File

@ -0,0 +1,23 @@
/*
* Copyright (c) 2010 Apple Inc. All rights reserved.
*
* @APPLE_LLVM_LICENSE_HEADER@
*/
// TEST_CONFIG
#include <stdio.h>
#include "test.h"
int main() {
static int numberOfSquesals = 5;
^{ numberOfSquesals = 6; }();
if (numberOfSquesals != 6) {
fail("did not update static local, rdar://6177162");
}
succeed(__FILE__);
}

View File

@ -0,0 +1,56 @@
/*
* Copyright (c) 2010 Apple Inc. All rights reserved.
*
* @APPLE_LLVM_LICENSE_HEADER@
*/
/* block_layout.m
Created by Patrick Beard on 3 Sep 2010
*/
// TEST_CFLAGS -framework Foundation
#import <Foundation/Foundation.h>
#import <Block.h>
#import <Block_private.h>
#import <dispatch/dispatch.h>
#import <assert.h>
#import "test.h"
int main (int argc, char const* argv[]) {
NSAutoreleasePool *pool = [NSAutoreleasePool new];
NSObject *o = [NSObject new];
NSString *s = [NSString stringWithFormat:@"argc = %d, argv = %p", argc, argv];
dispatch_block_t block = ^{
NSLog(@"o = %@", o);
NSLog(@"s = %@", s);
};
const char *layout = _Block_extended_layout(block);
testprintf("layout %p\n", layout);
assert (layout == (void*)0x200);
const char *gclayout = _Block_layout(block);
testprintf("GC layout %p\n", gclayout);
assert (gclayout == NULL);
block = [block copy];
layout = _Block_extended_layout(block);
testprintf("layout %p\n", layout);
assert (layout == (void*)0x200);
gclayout = _Block_layout(block);
testprintf("GC layout %p\n", gclayout);
assert (gclayout == NULL);
block();
[block release];
[pool drain];
succeed(__FILE__);
}

39
objectTests/blockimport.c Normal file
View File

@ -0,0 +1,39 @@
/*
* Copyright (c) 2010 Apple Inc. All rights reserved.
*
* @APPLE_LLVM_LICENSE_HEADER@
*/
/*
* blockimport.c
* testObjects
*
* Created by Blaine Garst on 10/13/08.
// Copyright 2008 Apple, Inc. All rights reserved.
*
*/
// rdar://6289344
// TEST_CONFIG
#include <stdio.h>
#include <Block.h>
#include <Block_private.h>
#include "test.h"
int main() {
int i = 1;
int (^intblock)(void) = ^{ return i*10; };
void (^vv)(void) = ^{
testprintf("intblock returns %d\n", intblock());
};
// printf("Block dump %s\n", _Block_dump(vv));
void (^vvcopy)(void) = Block_copy(vv);
Block_release(vvcopy);
succeed(__FILE__);
}

35
objectTests/byrefaccess.c Normal file
View File

@ -0,0 +1,35 @@
/*
* Copyright (c) 2010 Apple Inc. All rights reserved.
*
* @APPLE_LLVM_LICENSE_HEADER@
*/
//
// byrefaccess.m
// test that byref access to locals is accurate
// testObjects
//
// Created by Blaine Garst on 5/13/08.
// Copyright 2008 __MyCompanyName__. All rights reserved.
//
// TEST_CONFIG
#include <stdio.h>
#include "test.h"
void callVoidVoid(void (^closure)(void)) {
closure();
}
int main() {
__block int i = 10;
callVoidVoid(^{ ++i; });
if (i != 11) {
fail("didn't update i");
return 1;
}
succeed(__FILE__);
}

43
objectTests/byrefcopy.c Normal file
View File

@ -0,0 +1,43 @@
/*
* Copyright (c) 2010 Apple Inc. All rights reserved.
*
* @APPLE_LLVM_LICENSE_HEADER@
*/
//
// byrefcopy.m
// testObjects
//
// Created by Blaine Garst on 5/13/08.
// Copyright 2008 __MyCompanyName__. All rights reserved.
//
// TEST_CONFIG
#include <stdio.h>
#include <Block.h>
#include <Block_private.h>
#include "test.h"
void callVoidVoid(void (^closure)(void)) {
closure();
}
int main() {
int __block i = 10;
void (^block)(void) = ^{ ++i; };
//printf("original (old style) is %s\n", _Block_dump_old(block));
//printf("original (new style) is %s\n", _Block_dump(block));
void (^blockcopy)(void) __unused = Block_copy(block);
//printf("copy is %s\n", _Block_dump(blockcopy));
// use a copy & see that it updates i
callVoidVoid(block);
if (i != 11) {
fail("didn't update i");
return 1;
}
succeed(__FILE__);
}

View File

@ -0,0 +1,45 @@
/*
* Copyright (c) 2010 Apple Inc. All rights reserved.
*
* @APPLE_LLVM_LICENSE_HEADER@
*/
// TEST_CONFIG
// rdar://6255170
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <Block.h>
#include <Block_private.h>
#include <assert.h>
#include "test.h"
int main()
{
__block int var = 0;
int shouldbe = 0;
void (^b)(void) = ^{ var++; /*printf("var is at %p with value %d\n", &var, var);*/ };
__typeof(b) _b;
//printf("before copy...\n");
b(); ++shouldbe;
size_t i;
for (i = 0; i < 10; i++) {
_b = Block_copy(b); // make a new copy each time
assert(_b);
++shouldbe;
_b(); // should still update the stack
Block_release(_b);
}
//printf("after...\n");
b(); ++shouldbe;
if (var != shouldbe) {
fail("var is %d but should be %d", var, shouldbe);
}
succeed(__FILE__);
}

93
objectTests/byrefcopyid.m Normal file
View File

@ -0,0 +1,93 @@
/*
* Copyright (c) 2010 Apple Inc. All rights reserved.
*
* @APPLE_LLVM_LICENSE_HEADER@
*/
//
// byrefcopyid.m
// testObjects
//
// Created by Blaine Garst on 5/13/08.
// Copyright 2008 __MyCompanyName__. All rights reserved.
//
// Tests copying of blocks with byref ints and an id
// TEST_CFLAGS -framework Foundation
#import <Foundation/Foundation.h>
#import <Block.h>
#import <Block_private.h>
#import "test.h"
int CalledRetain = 0;
int CalledRelease = 0;
int CalledSelf = 0;
int CalledDealloc = 0;
@interface DumbObject : NSObject {
}
@end
@implementation DumbObject
- (id)retain {
CalledRetain = 1;
return [super retain];
}
- (oneway void)release {
CalledRelease = 1;
[super release];
}
- (id)self {
CalledSelf = 1;
return self;
}
- (void)dealloc {
CalledDealloc = 1;
[super dealloc];
}
@end
void callVoidVoid(void (^closure)(void)) {
closure();
}
void (^dummy)(void);
id testRoutine(const char *whoami) {
__block id dumbo = [DumbObject new];
dummy = ^{
[dumbo self];
};
//doHack(dummy);
id copy = Block_copy(dummy);
callVoidVoid(copy);
if (CalledSelf == 0) {
fail("copy helper of byref id didn't call self", whoami);
}
return copy;
}
int main(int argc __unused, char *argv[]) {
id copy = testRoutine(argv[0]);
Block_release(copy);
if (CalledRetain != 0) {
fail("copy helper of byref retained the id");
}
if (CalledRelease != 0) {
fail("copy helper of byref id did release the id");
}
succeed(__FILE__);
}

View File

@ -0,0 +1,34 @@
/*
* Copyright (c) 2010 Apple Inc. All rights reserved.
*
* @APPLE_LLVM_LICENSE_HEADER@
*/
// TEST_CONFIG
#include <Block.h>
#include <stdio.h>
#include "test.h"
// rdar://6225809
// fixed in 5623
int main() {
__block int a = 42;
int* ap = &a; // just to keep the address on the stack.
void (^b)(void) = ^{
//a; // workaround, a should be implicitly imported
(void)Block_copy(^{
a = 2;
});
};
(void)Block_copy(b);
if(&a == ap) {
fail("__block heap storage should have been created at this point");
}
succeed(__FILE__);
}

View File

@ -0,0 +1,69 @@
/*
* Copyright (c) 2010 Apple Inc. All rights reserved.
*
* @APPLE_LLVM_LICENSE_HEADER@
*/
/*
* byrefcopyint.c
* testObjects
*
* Created by Blaine Garst on 12/1/08.
* Copyright 2008 __MyCompanyName__. All rights reserved.
*
*/
//
// byrefcopyid.m
// testObjects
//
// Created by Blaine Garst on 5/13/08.
// Copyright 2008 __MyCompanyName__. All rights reserved.
//
// TEST_CONFIG
// Tests copying of blocks with byref ints
// rdar://6414583
#include <stdio.h>
#include <string.h>
#include <Block.h>
#include <Block_private.h>
#include "test.h"
typedef void (^voidVoid)(void);
voidVoid dummy;
void callVoidVoid(voidVoid closure) {
closure();
}
voidVoid testRoutine(const char *whoami) {
__block size_t dumbo = strlen(whoami);
dummy = ^{
//printf("incring dumbo from %d\n", dumbo);
++dumbo;
};
voidVoid copy = Block_copy(dummy);
return copy;
}
int main(int argc __unused, char *argv[]) {
voidVoid array[100];
for (int i = 0; i < 100; ++i) {
array[i] = testRoutine(argv[0]);
array[i]();
}
for (int i = 0; i < 100; ++i) {
Block_release(array[i]);
}
succeed(__FILE__);
}

View File

@ -0,0 +1,42 @@
/*
* Copyright (c) 2010 Apple Inc. All rights reserved.
*
* @APPLE_LLVM_LICENSE_HEADER@
*/
//
// byrefcopystack.m
// testObjects
//
// Created by Blaine Garst on 5/13/08.
// Copyright 2008 __MyCompanyName__. All rights reserved.
//
// TEST_CONFIG
// rdar://6255170
#include <stdio.h>
#include <Block.h>
#include "test.h"
void (^bumpi)(void);
int (^geti)(void);
void setClosures() {
int __block i = 10;
bumpi = Block_copy(^{ ++i; });
geti = Block_copy(^{ return i; });
}
int main() {
setClosures();
bumpi();
int i = geti();
if (i != 11) {
fail("didn't update i");
}
succeed(__FILE__);
}

74
objectTests/byrefgc.m Normal file
View File

@ -0,0 +1,74 @@
/*
* Copyright (c) 2010 Apple Inc. All rights reserved.
*
* @APPLE_LLVM_LICENSE_HEADER@
*/
//
// byrefgc.m
// testObjects
//
// Created by Blaine Garst on 5/16/08.
// Copyright 2008 __MyCompanyName__. All rights reserved.
//
// TEST_CFLAGS -framework Foundation
#import <stdio.h>
#import <Block.h>
#import "test.h"
#import "testroot.i"
int GotHi = 0;
int VersionCounter = 0;
@interface TestObject : TestRoot {
int version;
}
- (void) hi;
@end
@implementation TestObject
- (id)init {
version = VersionCounter++;
return self;
}
- (void) hi {
GotHi++;
}
@end
void (^get_block(void))(void) {
__block TestObject * to = [[TestObject alloc] init];
return [^{ [to hi]; to = [[TestObject alloc] init]; } copy];
}
int main() {
void (^voidvoid)(void) = get_block();
voidvoid();
voidvoid();
voidvoid();
voidvoid();
voidvoid();
voidvoid();
RELEASE_VAR(voidvoid);
testprintf("alloc %d dealloc %d\n", TestRootAlloc, TestRootDealloc);
#if __has_feature(objc_arc)
// one TestObject still alive in get_block's __block variable
testassert(TestRootAlloc == TestRootDealloc + 1);
#else
// __block variables are unretained so they all leaked
testassert(TestRootAlloc == 7);
testassert(TestRootDealloc == 0);
#endif
succeed(__FILE__);
}

55
objectTests/byrefstruct.c Normal file
View File

@ -0,0 +1,55 @@
/*
* Copyright (c) 2010 Apple Inc. All rights reserved.
*
* @APPLE_LLVM_LICENSE_HEADER@
*/
// -*- mode:C; c-basic-offset:4; tab-width:4; intent-tabs-mode:nil; -*-
// TEST_CONFIG
#import <stdio.h>
#import <stdlib.h>
#import <string.h>
#import "test.h"
typedef struct {
unsigned long ps[30];
int qs[30];
} BobTheStruct;
int main () {
__block BobTheStruct fiddly;
BobTheStruct copy;
void (^incrementFiddly)() = ^{
int i;
for(i=0; i<30; i++) {
fiddly.ps[i]++;
fiddly.qs[i]++;
}
};
memset(&fiddly, 0xA5, sizeof(fiddly));
memset(&copy, 0x2A, sizeof(copy));
int i;
for(i=0; i<30; i++) {
fiddly.ps[i] = i * i * i;
fiddly.qs[i] = -i * i * i;
}
copy = fiddly;
incrementFiddly();
if ( &copy == &fiddly ) {
fail("struct wasn't copied");
}
for(i=0; i<30; i++) {
//printf("[%d]: fiddly.ps: %lu, copy.ps: %lu, fiddly.qs: %d, copy.qs: %d\n", i, fiddly.ps[i], copy.ps[i], fiddly.qs[i], copy.qs[i]);
if ( (fiddly.ps[i] != copy.ps[i] + 1) || (fiddly.qs[i] != copy.qs[i] + 1) ) {
fail("struct contents were not incremented");
}
}
succeed(__FILE__);
}

24
objectTests/c99.c Normal file
View File

@ -0,0 +1,24 @@
/*
* Copyright (c) 2010 Apple Inc. All rights reserved.
*
* @APPLE_LLVM_LICENSE_HEADER@
*/
// TEST_CONFIG LANGUAGE=c,objc
// TEST_CFLAGS -std=c99 -fblocks
//
// c99.m
//
// rdar://problem/6399225
#import <stdio.h>
#import <stdlib.h>
#import "test.h"
int main() {
void (^blockA)(void) = ^ { ; };
blockA();
succeed(__FILE__);
}

41
objectTests/constassign.c Normal file
View File

@ -0,0 +1,41 @@
/*
* Copyright (c) 2010 Apple Inc. All rights reserved.
*
* @APPLE_LLVM_LICENSE_HEADER@
*/
//
// constassign.c
//
// Created by Blaine Garst on 3/21/08.
// Copyright 2008 __MyCompanyName__. All rights reserved.
// TEST_CONFIG RUN=0
/*
TEST_BUILD_OUTPUT
.*constassign.c:38:12: error: cannot assign to variable 'blockA' with const-qualified type 'void \(\^const\)\((void)?\)'
.*constassign.c:37:18: note: .*
.*constassign.c:39:10: error: cannot assign to variable 'fptr' with const-qualified type 'void \(\*const\)\((void)?\)'
.*constassign.c:36:18: note: .*
END
*/
// shouldn't be able to assign to a const pointer
// CONFIG error: assignment of read-only
#import <stdio.h>
#import "test.h"
void foo(void) { printf("I'm in foo\n"); }
void bar(void) { printf("I'm in bar\n"); }
int main() {
void (*const fptr)(void) = foo;
void (^const blockA)(void) = ^ { printf("hello\n"); };
blockA = ^ { printf("world\n"); } ;
fptr = bar;
fail("should not compile");
}

View File

@ -0,0 +1,87 @@
/*
* Copyright (c) 2010 Apple Inc. All rights reserved.
*
* @APPLE_LLVM_LICENSE_HEADER@
*/
#include <stdio.h>
#include <Block.h>
#include "test.h"
// TEST_CONFIG
// rdar://6243400,rdar://6289367
int constructors = 0;
int destructors = 0;
#define CONST const
class TestObject
{
public:
TestObject(CONST TestObject& inObj);
TestObject();
~TestObject();
TestObject& operator=(CONST TestObject& inObj);
int version() CONST { return _version; }
private:
mutable int _version;
};
TestObject::TestObject(CONST TestObject& inObj)
{
++constructors;
_version = inObj._version;
//printf("%p (%d) -- TestObject(const TestObject&) called\n", this, _version);
}
TestObject::TestObject()
{
_version = ++constructors;
//printf("%p (%d) -- TestObject() called\n", this, _version);
}
TestObject::~TestObject()
{
//printf("%p -- ~TestObject() called\n", this);
++destructors;
}
TestObject& TestObject::operator=(CONST TestObject& inObj)
{
//printf("%p -- operator= called\n", this);
_version = inObj._version;
return *this;
}
void testRoutine() {
TestObject one;
void (^b)(void) __unused = ^{ printf("my const copy of one is %d\n", one.version()); };
}
int main() {
testRoutine();
if (constructors == 0) {
fail("No copy constructors!!!");
}
if (constructors != destructors) {
fail("%d constructors but only %d destructors", constructors, destructors);
return 1;
}
succeed(__FILE__);
}

39
objectTests/copynull.c Normal file
View File

@ -0,0 +1,39 @@
/*
* Copyright (c) 2010 Apple Inc. All rights reserved.
*
* @APPLE_LLVM_LICENSE_HEADER@
*/
/*
* copynull.c
* testObjects
*
* Created by Blaine Garst on 10/15/08.
* Copyright 2008 __MyCompanyName__. All rights reserved.
*
*/
// TEST_CONFIG
// rdar://6295848
#import <stdio.h>
#import <Block.h>
#import <Block_private.h>
#import "test.h"
int main() {
void (^block)(void) = (void (^)(void))0;
void (^blockcopy)(void) = Block_copy(block);
if (blockcopy != (void (^)(void))0) {
fail("whoops, somehow we copied NULL!");
}
// make sure we can also
Block_release(blockcopy);
// and more secretly
//_Block_destroy(blockcopy);
succeed(__FILE__);
}

View File

@ -0,0 +1,58 @@
/*
* Copyright (c) 2010 Apple Inc. All rights reserved.
*
* @APPLE_LLVM_LICENSE_HEADER@
*/
//
// copyproperty.m
// bocktest
//
// Created by Blaine Garst on 3/21/08.
// Copyright 2008 __MyCompanyName__. All rights reserved.
//
// TEST_CFLAGS -framework Foundation
#import <Foundation/Foundation.h>
#import <stdio.h>
#import "test.h"
@interface TestObject : NSObject {
long (^getInt)(void);
}
@property(copy) long (^getInt)(void);
@end
@implementation TestObject
@synthesize getInt;
@end
@interface CountingObject : NSObject
@end
int Retained = 0;
@implementation CountingObject
- (id) retain {
Retained = 1;
return [super retain];
}
@end
int main() {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
TestObject *to = [[TestObject alloc] init];
CountingObject *co = [[CountingObject alloc] init];
long (^localBlock)(void) = ^{ return 10L + (long)[co self]; };
to.getInt = localBlock;
if (localBlock == to.getInt) {
fail("block property not copied!!");
}
if (Retained == 0) {
fail("didn't copy block import");
}
[pool drain];
succeed(__FILE__);
}

41
objectTests/copytest.m Normal file
View File

@ -0,0 +1,41 @@
/*
* Copyright (c) 2010 Apple Inc. All rights reserved.
*
* @APPLE_LLVM_LICENSE_HEADER@
*/
//
// copytest.m
// bocktest
//
// Created by Blaine Garst on 3/21/08.
// Copyright 2008 __MyCompanyName__. All rights reserved.
//
// TEST_CFLAGS -framework Foundation
#import <Foundation/Foundation.h>
#import <Block_private.h>
#import "test.h"
int GlobalInt = 0;
void setGlobalInt(int value) { GlobalInt = value; }
int main(int argc __unused, char *argv[]) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
int y = 0;
// must use x+y to avoid optimization of using a global block
void (^callSetGlobalInt)(int x) = ^(int x) { setGlobalInt(x + y); };
// a block be able to be sent a message
void (^callSetGlobalIntCopy)(int) = [callSetGlobalInt copy];
if (callSetGlobalIntCopy == callSetGlobalInt) {
// testwarn("copy looks like: %s", _Block_dump(callSetGlobalIntCopy));
fail("copy is identical", argv[0]);
}
callSetGlobalIntCopy(10);
if (GlobalInt != 10) {
fail("copy did not set global int");
}
[pool drain];
succeed(__FILE__);
}

112
objectTests/counting.m Normal file
View File

@ -0,0 +1,112 @@
/*
* Copyright (c) 2010 Apple Inc. All rights reserved.
*
* @APPLE_LLVM_LICENSE_HEADER@
*/
//
// counting.m
// testObjects
//
// Created by Blaine Garst on 9/23/08.
// Copyright 2008 Apple. All rights reserved.
//
// rdar://6557292
// TEST_CFLAGS -framework Foundation
#import <Foundation/Foundation.h>
#import <Block.h>
#import <stdio.h>
#import <libkern/OSAtomic.h>
#import <pthread.h>
#import "test.h"
int allocated = 0;
int recovered = 0;
@interface TestObject : NSObject
@end
@implementation TestObject
- (id)init {
// printf("allocated...\n");
OSAtomicIncrement32(&allocated);
return self;
}
- (void)dealloc {
// printf("deallocated...\n");
OSAtomicIncrement32(&recovered);
[super dealloc];
}
@end
void recoverMemory(const char *caller) {
if (recovered != allocated) {
fail("after %s recovered %d vs allocated %d", caller, recovered, allocated);
}
}
// test that basic refcounting works
void *testsingle(void *arg __unused) {
TestObject *to = [TestObject new];
void (^b)(void) = [^{ printf("hi %p\n", to); } copy];
[b release];
[to release];
return NULL;
}
void *testlatch(void *arg __unused) {
TestObject *to = [TestObject new];
void (^b)(void) = [^{ printf("hi %p\n", to); } copy];
for (int i = 0; i < 0xfffff; ++i) {
(void)Block_copy(b);
}
for (int i = 0; i < 10; ++i) {
Block_release(b);
}
[b release];
[to release];
// lie - b should not be recovered because it has been over-retained
OSAtomicIncrement32(&recovered);
return NULL;
}
void *testmultiple(void *arg __unused) {
TestObject *to = [TestObject new];
void (^b)(void) = [^{ printf("hi %p\n", to); } copy];
#if 2
for (int i = 0; i < 10; ++i) {
(void)Block_copy(b);
}
for (int i = 0; i < 10; ++i) {
Block_release(b);
}
#endif
[b release];
[to release];
return NULL;
}
int main() {
pthread_t th;
pthread_create(&th, NULL, testsingle, NULL);
pthread_join(th, NULL);
pthread_create(&th, NULL, testsingle, NULL);
pthread_join(th, NULL);
pthread_create(&th, NULL, testsingle, NULL);
pthread_join(th, NULL);
pthread_create(&th, NULL, testsingle, NULL);
pthread_join(th, NULL);
recoverMemory("testsingle");
pthread_create(&th, NULL, testlatch, NULL);
pthread_join(th, NULL);
recoverMemory("testlatch");
pthread_create(&th, NULL, testmultiple, NULL);
pthread_join(th, NULL);
recoverMemory("testmultiple");
succeed(__FILE__);
}

View File

@ -0,0 +1,50 @@
/*
* Copyright (c) 2010 Apple Inc. All rights reserved.
*
* @APPLE_LLVM_LICENSE_HEADER@
*/
// TEST_CONFIG
// rdar://problem/6371811
#include <CoreFoundation/CoreFoundation.h>
#include <dispatch/dispatch.h>
#include <unistd.h>
#include <Block.h>
#include "test.h"
void EnqueueStuff(dispatch_queue_t q)
{
__block CFIndex counter;
// above call has a side effect: it works around:
// <rdar://problem/6225809> __block variables not implicitly imported into intermediate scopes
dispatch_async(q, ^{
counter = 0;
});
dispatch_async(q, ^{
//printf("outer block.\n");
counter++;
dispatch_async(q, ^{
//printf("inner block.\n");
counter--;
if(counter == 0) {
succeed(__FILE__);
}
});
if(counter == 0) {
fail("already done? inconceivable!");
}
});
}
int main () {
dispatch_queue_t q = dispatch_queue_create("queue", NULL);
EnqueueStuff(q);
dispatch_main();
fail("unreachable");
}

View File

@ -0,0 +1,33 @@
/*
* Copyright (c) 2010 Apple Inc. All rights reserved.
*
* @APPLE_LLVM_LICENSE_HEADER@
*/
#include <stdio.h>
#include <Block.h>
#include "test.h"
// TEST_CONFIG
void callsomething(const char *format __unused, int argument __unused) {
asm("");
}
void
dispatch_call_Block_with_release2(void *block)
{
void (^b)(void) = (void (^)(void))block;
b();
Block_release(b);
}
int main(int argc, char *argv[] __unused) {
void (^b1)(void) = ^{ callsomething("argc is %d\n", argc); };
void (^b2)(void) = ^{ callsomething("hellow world\n", 0); }; // global block now
dispatch_call_Block_with_release2(Block_copy(b1));
dispatch_call_Block_with_release2(Block_copy(b2));
succeed(__FILE__);
}

View File

@ -0,0 +1,41 @@
/*
* Copyright (c) 2010 Apple Inc. All rights reserved.
*
* @APPLE_LLVM_LICENSE_HEADER@
*/
#import <Foundation/Foundation.h>
#import "test.h"
// TEST_CFLAGS -framework Foundation
int main() {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSArray *empty = [NSArray new];
[empty enumerateObjectsUsingBlock: ^(id obj __unused, NSUInteger idx __unused, BOOL *stop __unused) {
fail("Block called when enumerating empty array");
}];
__block int callCount = 0;
NSArray *three = [NSArray arrayWithObjects:
@"One",
@"Two",
@"Three",
nil];
[three enumerateObjectsUsingBlock: ^(id obj, NSUInteger idx __unused, BOOL *stop) {
callCount++;
if ([@"Two" isEqual: obj]) {
*stop = YES;
} else if ([@"Three" isEqual: obj]) {
fail("Block called after stop was set");
}
}];
if (callCount != 2) {
fail("Block should have been called twice, actually counted %d", callCount);
}
[pool drain];
succeed(__FILE__);
}

21
objectTests/flagsisa.c Normal file
View File

@ -0,0 +1,21 @@
/*
* Copyright (c) 2010 Apple Inc. All rights reserved.
*
* @APPLE_LLVM_LICENSE_HEADER@
*/
// TEST_CONFIG
// rdar://6310599
#include <stdio.h>
#include "test.h"
int main()
{
__block int flags;
__block void *isa;
(void)^{ flags=1; isa = (void *)isa; };
succeed(__FILE__);
}

28
objectTests/forin.m Normal file
View File

@ -0,0 +1,28 @@
/*
* Copyright (c) 2010 Apple Inc. All rights reserved.
*
* @APPLE_LLVM_LICENSE_HEADER@
*/
// TEST_CFLAGS -framework Foundation
//
// rdar://8295106
// use block variable in for..in statement
#import <Foundation/Foundation.h>
#import "test.h"
int main() {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSMutableArray *array = [NSMutableArray array];
for (int i = 0; i < 200; ++i) {
[array addObject:[[^{ return i; } copy] autorelease]];
}
int i = 0;
for (int (^b)(void) in array) {
testassert(b() == i++);
}
[pool drain];
succeed(__FILE__);
}

View File

@ -0,0 +1,39 @@
/*
* Copyright (c) 2010 Apple Inc. All rights reserved.
*
* @APPLE_LLVM_LICENSE_HEADER@
*/
// TEST_CONFIG
#import <stdio.h>
#import <Block.h>
#import "test.h"
int global;
void (^gblock)(int) = ^(int x){ global = x; };
int main() {
gblock(1);
if (global != 1) {
fail("did not set global to 1");
}
void (^gblockcopy)(int) = Block_copy(gblock);
if (gblockcopy != gblock) {
fail("global copy %p not a no-op %p", (void *)gblockcopy, (void *)gblock);
}
Block_release(gblockcopy);
gblock(3);
if (global != 3) {
fail("did not set global to 3");
}
gblockcopy = Block_copy(gblock);
gblockcopy(5);
if (global != 5) {
fail("did not set global to 5");
}
succeed(__FILE__);
}

36
objectTests/goto.c Normal file
View File

@ -0,0 +1,36 @@
/*
* Copyright (c) 2010 Apple Inc. All rights reserved.
*
* @APPLE_LLVM_LICENSE_HEADER@
*/
/*
* goto.c
* testObjects
*
* Created by Blaine Garst on 10/17/08.
* Copyright 2008 __MyCompanyName__. All rights reserved.
*
*/
// TEST_CONFIG
// rdar://6289031
#include <stdio.h>
#include "test.h"
int main()
{
__block int val = 0;
^{ val = 1; }();
if (val == 0) {
goto out_bad; // error: local byref variable val is in the scope of this goto
}
succeed(__FILE__);
out_bad:
fail("val not updated!");
}

View File

@ -0,0 +1,73 @@
/*
* Copyright (c) 2010 Apple Inc. All rights reserved.
*
* @APPLE_LLVM_LICENSE_HEADER@
*/
//
// importedblockcopy.m
// testObjects
//
// Created by Blaine Garst on 10/16/08.
// Copyright 2008 Apple. All rights reserved.
//
// rdar://6297435
// TEST_CFLAGS -framework Foundation
#import <Foundation/Foundation.h>
#import "Block.h"
#import "test.h"
int Allocated = 0;
int Reclaimed = 0;
@interface TestObject : NSObject
@end
@implementation TestObject
- (void) dealloc {
++Reclaimed;
[super dealloc];
}
- (id)init {
self = [super init];
++Allocated;
return self;
}
@end
void theTest() {
// establish a block with an object reference
TestObject *to = [[TestObject alloc] init];
void (^inner)(void) = ^ {
[to self]; // something that will hold onto "to"
};
// establish another block that imports the first one...
void (^outer)(void) = ^ {
inner();
inner();
};
// now when we copy outer the compiler will _Block_copy_assign inner
void (^outerCopy)(void) = Block_copy(outer);
// but when released, at least under GC, it won't let go of inner (nor its import: "to")
Block_release(outerCopy);
[to release];
}
int main() {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
for (int i = 0; i < 200; ++i)
theTest();
[pool drain];
if ((Reclaimed+10) <= Allocated) {
fail("whoops, reclaimed only %d of %d allocated", Reclaimed, Allocated);
}
succeed(__FILE__);
}

33
objectTests/josh.cpp Normal file
View File

@ -0,0 +1,33 @@
/*
* Copyright (c) 2010 Apple Inc. All rights reserved.
*
* @APPLE_LLVM_LICENSE_HEADER@
*/
// TEST_CONFIG CC=clang
#include <stdio.h>
#include <stdlib.h>
#include "test.h"
struct MyStruct {
int something;
};
struct TestObject {
void test(void){
{
MyStruct first __unused; // works
}
void (^b)(void) __unused = ^{
MyStruct inner __unused; // fails to compile!
};
}
};
int main() {
succeed(__FILE__);
}

34
objectTests/k-and-r.c Normal file
View File

@ -0,0 +1,34 @@
/*
* Copyright (c) 2010 Apple Inc. All rights reserved.
*
* @APPLE_LLVM_LICENSE_HEADER@
*/
// TEST_CONFIG RUN=0
/*
TEST_BUILD_OUTPUT
.*k-and-r.c:26:11: error: incompatible block pointer types assigning to 'char \(\^\)\(\)' from 'char \(\^\)\(char\)'
OR
.*k-and-r.c:26:11: error: assigning to 'char \(\^\)\(\)' from incompatible type 'char \(\^\)\(char\)'
.*k-and-r.c:27:20: error: too many arguments to block call, expected 0, have 1
.*k-and-r.c:28:20: error: too many arguments to block call, expected 0, have 1
END
*/
#import <stdio.h>
#import <stdlib.h>
#import "test.h"
int main() {
char (^rot13)();
rot13 = ^(char c) { return (char)(((c - 'a' + 13) % 26) + 'a'); };
char n = rot13('a');
char c = rot13('p');
if ( n != 'n' || c != 'c' ) {
fail("rot13('a') returned %c, rot13('p') returns %c\n", n, c);
}
fail("should not compile");
}

View File

@ -0,0 +1,47 @@
/*
* Copyright (c) 2010 Apple Inc. All rights reserved.
*
* @APPLE_LLVM_LICENSE_HEADER@
*/
// TEST_CONFIG
#import <stdio.h>
#import <stdlib.h>
#import <string.h>
#import "test.h"
typedef struct {
unsigned long ps[30];
int qs[30];
} BobTheStruct;
int main () {
BobTheStruct inny;
BobTheStruct outty;
BobTheStruct (^copyStruct)(BobTheStruct);
int i;
memset(&inny, 0xA5, sizeof(inny));
memset(&outty, 0x2A, sizeof(outty));
for(i=0; i<30; i++) {
inny.ps[i] = i * i * i;
inny.qs[i] = -i * i * i;
}
copyStruct = ^(BobTheStruct aBigStruct){ return aBigStruct; }; // pass-by-value intrinsically copies the argument
outty = copyStruct(inny);
if ( &inny == &outty ) {
fail("struct wasn't copied");
}
for(i=0; i<30; i++) {
if ( (inny.ps[i] != outty.ps[i]) || (inny.qs[i] != outty.qs[i]) ) {
fail("struct contents did not match.");
}
}
succeed(__FILE__);
}

View File

@ -0,0 +1,41 @@
/*
* Copyright (c) 2010 Apple Inc. All rights reserved.
*
* @APPLE_LLVM_LICENSE_HEADER@
*/
/*
* localisglobal.c
* testObjects
*
* Created by Blaine Garst on 9/29/08.
* Copyright 2008 __MyCompanyName__. All rights reserved.
*/
// TEST_CONFIG
// rdar://6230297
#include <stdio.h>
#include "test.h"
void (^global)(void) = ^{ printf("hello world\n"); };
int aresame(void *first, void *second) {
long *f = (long *)first;
long *s = (long *)second;
return *f == *s;
}
int main() {
int i = 10;
void (^local)(void) = ^ { printf("hi %d\n", i); };
void (^localisglobal)(void) = ^ { printf("hi\n"); };
if (aresame(local, localisglobal)) {
fail("local block could be global, but isn't");
}
if (!aresame(global, localisglobal)) {
fail("local block is not global, not stack, what is it??");
}
succeed(__FILE__);
}

20
objectTests/macro.c Normal file
View File

@ -0,0 +1,20 @@
/*
* Copyright (c) 2010 Apple Inc. All rights reserved.
*
* @APPLE_LLVM_LICENSE_HEADER@
*/
// TEST_CONFIG
// rdar://6718399
#include <stdio.h>
#include <Block.h>
#include "test.h"
int main() {
void (^bbb)(void) __unused = Block_copy(^ {
int j __unused, cnt __unused;
});
succeed(__FILE__);
}

20
objectTests/makefile Normal file
View File

@ -0,0 +1,20 @@
# quick test
all:
perl test.pl $(MAKEFLAGS)
# default-arch but otherwise comprehensive test for buildbot
buildbot:
perl test.pl $(MAKEFLAGS) MEM=mrc LANGUAGE=c,c++,objc,objc++
# comprehensive tests
mac macos macosx:
perl test.pl $(MAKEFLAGS) ARCH=x86_64,i386 MEM=mrc LANGUAGE=c,c++,objc,objc++
iphonesimulator:
perl test.pl $(MAKEFLAGS) ARCH=i386 SDK=iphonesimulator MEM=mrc LANGUAGE=c,c++,objc,objc++
iphoneos:
perl test.pl $(MAKEFLAGS) ARCH=armv6,armv7 SDK=iphoneos MEM=mrc LANGUAGE=c,c++,objc,objc++
clean:
@ perl test.pl clean

90
objectTests/member.mm Normal file
View File

@ -0,0 +1,90 @@
/*
* Copyright (c) 2010 Apple Inc. All rights reserved.
*
* @APPLE_LLVM_LICENSE_HEADER@
*/
// TEST_CFLAGS -framework Foundation
#import <Foundation/Foundation.h>
#import <Block.h>
#import "test.h"
int recovered = 0;
int constructors = 0;
int destructors = 0;
#define CONST const
class TestObject
{
public:
TestObject(CONST TestObject& inObj);
TestObject();
~TestObject();
//TestObject& operator=(CONST TestObject& inObj);
void test(void);
int version() CONST { return _version; }
private:
mutable int _version;
};
TestObject::TestObject(CONST TestObject& inObj)
{
++constructors;
_version = inObj._version;
printf("%p (%d) -- TestObject(const TestObject&) called", this, _version);
}
TestObject::TestObject()
{
_version = ++constructors;
//printf("%p (%d) -- TestObject() called\n", this, _version);
}
TestObject::~TestObject()
{
//printf("%p -- ~TestObject() called\n", this);
++destructors;
}
#if 0
TestObject& TestObject::operator=(CONST TestObject& inObj)
{
printf("%p -- operator= called", this);
_version = inObj._version;
return *this;
}
#endif
void TestObject::test(void) {
void (^b)(void) = ^{ recovered = _version; };
void (^b2)(void) = [b copy];
b2();
}
void testRoutine() {
TestObject one;
one.test();
}
int main() {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
testRoutine();
[pool drain];
if (recovered != 1) {
fail("didn't recover byref block variable");
}
succeed(__FILE__);
}

18
objectTests/modglobal.c Normal file
View File

@ -0,0 +1,18 @@
/*
* Copyright (c) 2010 Apple Inc. All rights reserved.
*
* @APPLE_LLVM_LICENSE_HEADER@
*/
#include <stdio.h>
#include "test.h"
// TEST_CONFIG
int AGlobal;
int main() {
void (^f)(void) __unused = ^ { AGlobal++; };
succeed(__FILE__);
}

56
objectTests/nestedBlock.m Normal file
View File

@ -0,0 +1,56 @@
/*
* Copyright (c) 2010 Apple Inc. All rights reserved.
*
* @APPLE_LLVM_LICENSE_HEADER@
*/
//
// nestedBlock.m
// testObjects
//
// Created by Blaine Garst on 6/24/08.
// Copyright 2008 __MyCompanyName__. All rights reserved.
//
// test -retain
// TEST_CONFIG
// TEST_CFLAGS -framework Foundation
#import <stdio.h>
#import <Block.h>
#import <Foundation/Foundation.h>
#import "test.h"
int Retained = 0;
@interface TestObject : NSObject
@end
@implementation TestObject
- (id)retain {
Retained = 1;
return [super retain];
}
@end
void callVoidVoid(void (^closure)(void)) {
closure();
}
int main(int argc, char *argv[] __unused) {
TestObject *to = [[TestObject alloc] init];
int i = argc;
// use a copy & see that it updates i
callVoidVoid(Block_copy(^{
if (i > 0) {
callVoidVoid(^{ [to self]; });
}
}));
if (Retained == 0) {
fail("didn't update Retained");
}
succeed(__FILE__);
}

89
objectTests/nestedId.m Normal file
View File

@ -0,0 +1,89 @@
/*
* Copyright (c) 2010 Apple Inc. All rights reserved.
*
* @APPLE_LLVM_LICENSE_HEADER@
*/
//
// nestedBlock.m
// testObjects
//
// Created by Blaine Garst on 6/24/08.
// Copyright 2008 __MyCompanyName__. All rights reserved.
//
// test -retain and -release
// TEST_CFLAGS -framework Foundation
#import <stdio.h>
#import <Block.h>
#import <Foundation/Foundation.h>
#import "test.h"
int Retained = 0;
void (^savedBlock)(void);
void (^savedBlock2)(void);
void saveit(void (^block)(void)) {
savedBlock = Block_copy(block);
}
void callit() {
savedBlock();
}
void releaseit() {
Block_release(savedBlock);
savedBlock = nil;
}
void saveit2(void (^block)(void)) {
savedBlock2 = Block_copy(block);
}
void callit2() {
savedBlock2();
}
void releaseit2() {
Block_release(savedBlock2);
savedBlock2 = nil;
}
@interface TestObject : NSObject
@end
@implementation TestObject
- (id)retain {
++Retained;
[super retain];
return self;
}
- (oneway void)release {
--Retained;
[super retain];
}
@end
id global;
void test(id param) {
saveit(^{
saveit2(
^{
global = param;
});
});
}
int main() {
TestObject *to = [[TestObject alloc] init];
test(to);
if (Retained == 0) {
fail("didn't update Retained");
}
callit();
callit2();
succeed(__FILE__);
}

89
objectTests/nestedSelf.m Normal file
View File

@ -0,0 +1,89 @@
/*
* Copyright (c) 2010 Apple Inc. All rights reserved.
*
* @APPLE_LLVM_LICENSE_HEADER@
*/
//
// nestedBlock.m
// testObjects
//
// Created by Blaine Garst on 6/24/08.
// Copyright 2008 __MyCompanyName__. All rights reserved.
//
// test -retain and -release
// TEST_CFLAGS -framework Foundation
#import <stdio.h>
#import <Block.h>
#import <Foundation/Foundation.h>
#import "test.h"
int Retained = 0;
void (^savedBlock)(void);
void (^savedBlock2)(void);
void saveit(void (^block)(void)) {
savedBlock = Block_copy(block);
}
void callit() {
savedBlock();
}
void releaseit() {
Block_release(savedBlock);
savedBlock = nil;
}
void saveit2(void (^block)(void)) {
savedBlock2 = Block_copy(block);
}
void callit2() {
savedBlock2();
}
void releaseit2() {
Block_release(savedBlock2);
savedBlock2 = nil;
}
@interface TestObject : NSObject
- (void)test;
@end
id global;
@implementation TestObject
- (id)retain {
++Retained;
[super retain];
return self;
}
- (oneway void)release {
--Retained;
[super retain];
}
- (void)test {
saveit(^{
saveit2(^{
global = self;
});
});
}
@end
int main() {
TestObject *to = [[TestObject alloc] init];
[to test];
if (Retained == 0) {
fail("didn't update Retained");
}
callit();
callit2();
succeed(__FILE__);
}

View File

@ -0,0 +1,42 @@
/*
* Copyright (c) 2010 Apple Inc. All rights reserved.
*
* @APPLE_LLVM_LICENSE_HEADER@
*/
//
// nestedimport.m
// testObjects
//
// Created by Blaine Garst on 6/24/08.
// Copyright 2008 Apple, Inc. All rights reserved.
//
// TEST_CONFIG
#include <stdio.h>
#include <stdlib.h>
#include "test.h"
int Global = 0;
void callVoidVoid(void (^closure)(void)) {
closure();
}
int main(int argc, char **argv __unused) {
int i = 1;
void (^vv)(void) = ^{
if (argc > 0) {
callVoidVoid(^{ Global = i; });
}
};
i = 2;
vv();
if (Global != 1) {
fail("Global not set to captured value");
}
succeed(__FILE__);
}

52
objectTests/notcopied.m Normal file
View File

@ -0,0 +1,52 @@
/*
* Copyright (c) 2010 Apple Inc. All rights reserved.
*
* @APPLE_LLVM_LICENSE_HEADER@
*/
//
// notcopied.m
// testObjects
//
// Created by Blaine Garst on 2/12/09.
// Copyright 2009 Apple. All rights reserved.
//
// TEST_CFLAGS -framework Foundation
// rdar://6557292
// Test that a __block Block variable with a reference to a stack based Block is not copied
// when a Block referencing the __block Block varible is copied.
// No magic for __block variables.
#import <stdio.h>
#import <Block.h>
#import <Block_private.h>
#import <Foundation/Foundation.h>
#import "test.h"
int Retained = 0;
@interface TestObject : NSObject
@end
@implementation TestObject
- (id)retain {
Retained = 1;
return [super retain];
}
@end
int main() {
TestObject *to = [[TestObject alloc] init];
__block void (^someBlock)(void) = ^ { [to self]; };
void (^someOtherBlock)(void) = ^ {
someBlock(); // reference someBlock. It shouldn't be copied under the new rules.
};
someOtherBlock = [someOtherBlock copy];
if (Retained != 0) {
fail("__block Block was copied when it shouldn't have");
}
succeed(__FILE__);
}

View File

@ -0,0 +1,42 @@
/*
* Copyright (c) 2010 Apple Inc. All rights reserved.
*
* @APPLE_LLVM_LICENSE_HEADER@
*/
//
// nullblockisa.m
// testObjects
//
// Created by Blaine Garst on 9/24/08.
// Copyright 2008 __MyCompanyName__. All rights reserved.
//
// TEST_CONFIG
// rdar://6244520
#include <stdio.h>
#include <stdlib.h>
#include <Block_private.h>
#include "test.h"
void check(void (^b)(void)) {
struct _custom {
struct Block_layout layout;
struct Block_byref *innerp;
} *custom = (struct _custom *)(void *)(b);
//printf("block is at %p, size is %lx, inner is %p\n", (void *)b, Block_size(b), innerp);
if (custom->innerp->isa != (void *)NULL) {
fail("not a NULL __block isa");
}
return;
}
int main() {
__block int i;
check(^{ printf("%d\n", ++i); });
succeed(__FILE__);
}

View File

@ -0,0 +1,72 @@
/*
* Copyright (c) 2010 Apple Inc. All rights reserved.
*
* @APPLE_LLVM_LICENSE_HEADER@
*/
/*
* objectassign.c
* testObjects
*
* Created by Blaine Garst on 10/28/08.
* Copyright 2008 __MyCompanyName__. All rights reserved.
*/
// TEST_CONFIG
// rdar://6175959
// This just tests that the compiler is issuing the proper helper routines
#include <stdio.h>
#include <Block_private.h>
#include "test.h"
int AssignCalled = 0;
int DisposeCalled = 0;
// local copy instead of libSystem.B.dylib copy
void _Block_object_assign(void *destAddr __unused, const void *object __unused, const int isWeak __unused) {
//printf("_Block_object_assign(%p, %p, %d) called\n", destAddr, object, isWeak);
AssignCalled = 1;
}
void _Block_object_dispose(const void *object __unused, const int isWeak __unused) {
//printf("_Block_object_dispose(%p, %d) called\n", object, isWeak);
DisposeCalled = 1;
}
struct MyStruct {
long isa;
long field;
};
typedef struct MyStruct *__attribute__((NSObject)) MyStruct_t;
int main() {
// create a block
struct MyStruct X;
MyStruct_t xp = (MyStruct_t)&X;
xp->field = 10;
void (^myBlock)(void) = ^{ printf("field is %ld\n", xp->field); };
// should be a copy helper generated with a calls to above routines
// Lets find out!
struct Block_layout *bl = (struct Block_layout *)(void *)myBlock;
if ((bl->flags & BLOCK_HAS_COPY_DISPOSE) != BLOCK_HAS_COPY_DISPOSE) {
fail("no copy dispose!!!!");
}
// call helper routines directly. These will, in turn, we hope, call the stubs above
long destBuffer[256];
//printf("destbuffer is at %p, block at %p\n", destBuffer, (void *)bl);
//printf("dump is %s\n", _Block_dump(myBlock));
struct Block_descriptor_2 *desc2 =
(struct Block_descriptor_2 *)(bl->descriptor + 1);
desc2->copy(destBuffer, bl);
desc2->dispose(bl);
if (AssignCalled == 0) {
fail("did not call assign helper!");
}
if (DisposeCalled == 0) {
fail("did not call dispose helper");
}
succeed(__FILE__);
}

31
objectTests/orbars.c Normal file
View File

@ -0,0 +1,31 @@
/*
* Copyright (c) 2010 Apple Inc. All rights reserved.
*
* @APPLE_LLVM_LICENSE_HEADER@
*/
/*
* orbars.c
* testObjects
*
* Created by Blaine Garst on 9/17/08.
* Copyright 2008 __MyCompanyName__. All rights reserved.
*/
// rdar://6276695 error: before | token
// TEST_CONFIG RUN=0
/*
TEST_BUILD_OUTPUT
.*orbars.c:29:\d+: error: expected expression
END
*/
#include <stdio.h>
#include "test.h"
int main() {
int i __unused = 10;
void (^b)(void) __unused = ^(void){ | i | printf("hello world, %d\n", i); };
fail("should not compile");
}

View File

@ -0,0 +1,28 @@
/*
* Copyright (c) 2010 Apple Inc. All rights reserved.
*
* @APPLE_LLVM_LICENSE_HEADER@
*/
// TEST_CFLAGS -framework Foundation
#import <Foundation/Foundation.h>
#import <Block_private.h>
#import "test.h"
typedef void (^void_block_t)(void);
int main () {
void_block_t c = ^{ NSLog(@"Hello!"); };
//printf("global block c looks like: %s\n", _Block_dump(c));
int j;
for (j = 0; j < 1000; j++)
{
void_block_t d = [c copy];
//if (j == 0) printf("copy looks like %s\n", _Block_dump(d));
[d release];
}
succeed(__FILE__);
}

30
objectTests/rdar6396238.c Normal file
View File

@ -0,0 +1,30 @@
/*
* Copyright (c) 2010 Apple Inc. All rights reserved.
*
* @APPLE_LLVM_LICENSE_HEADER@
*/
// TEST_CONFIG rdar://6396238
#include <stdio.h>
#include <stdlib.h>
#include "test.h"
static int count = 0;
void (^mkblock(void))(void)
{
count++;
return ^{
count++;
};
}
int main() {
mkblock()();
if (count != 2) {
fail("failure, 2 != %d\n", count);
}
succeed(__FILE__);
}

27
objectTests/rdar6405500.c Normal file
View File

@ -0,0 +1,27 @@
/*
* Copyright (c) 2010 Apple Inc. All rights reserved.
*
* @APPLE_LLVM_LICENSE_HEADER@
*/
// TEST_CONFIG rdar://6405500
#import <stdio.h>
#import <stdlib.h>
#import <dispatch/dispatch.h>
#import "test.h"
int main () {
__block void (^blockFu)(size_t t);
blockFu = ^(size_t t){
if (t == 20) {
succeed(__FILE__);
} else {
dispatch_async(dispatch_get_main_queue(), ^{ blockFu(20); });
}
};
dispatch_apply(10, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), blockFu);
dispatch_main();
fail("unreachable");
}

32
objectTests/rdar6414583.c Normal file
View File

@ -0,0 +1,32 @@
/*
* Copyright (c) 2010 Apple Inc. All rights reserved.
*
* @APPLE_LLVM_LICENSE_HEADER@
*/
// TEST_CONFIG rdar://6414583
// a smaller case of byrefcopyint
#include <Block.h>
#include <dispatch/dispatch.h>
#include <stdio.h>
#include "test.h"
int main() {
__block int c = 1;
//printf("&c = %p - c = %i\n", &c, c);
int i;
for(i =0; i < 2; i++) {
dispatch_block_t block = Block_copy(^{ c = i; });
block();
// printf("%i: &c = %p - c = %i\n", i, &c, c);
Block_release(block);
}
succeed(__FILE__);
}

63
objectTests/recover.m Normal file
View File

@ -0,0 +1,63 @@
/*
* Copyright (c) 2010 Apple Inc. All rights reserved.
*
* @APPLE_LLVM_LICENSE_HEADER@
*/
// TEST_CFLAGS -framework Foundation
#import <Foundation/Foundation.h>
#import <Block.h>
#import <Block_private.h>
#import "test.h"
int recovered = 0;
@interface TestObject : NSObject {
}
@end
@implementation TestObject
- (void)dealloc {
++recovered;
[super dealloc];
}
@end
typedef struct {
struct Block_layout layout; // assumes copy helper
struct Block_byref *byref_ptr;
} Block_with_byref;
void testRoutine() {
__block id to = [[TestObject alloc] init];
void (^b)(void) = [^{ [to self]; } copy];
for (int i = 0; i < 10; ++i)
[b retain];
for (int i = 0; i < 10; ++i)
[b release];
for (int i = 0; i < 10; ++i)
(void)Block_copy(b); // leak
for (int i = 0; i < 10; ++i)
Block_release(b);
for (int i = 0; i < 10; ++i) {
(void)Block_copy(b); // make sure up
Block_release(b); // and down work under GC
}
[b release];
[to release];
// block_byref_release needed under non-GC to get rid of testobject
}
int main() {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
for (int i = 0; i < 200; ++i) // do enough to trigger TLC if GC is on
testRoutine();
[pool drain];
if (recovered == 0) {
fail("didn't recover byref block variable");
}
succeed(__FILE__);
}

97
objectTests/recovercpp.mm Normal file
View File

@ -0,0 +1,97 @@
/*
* Copyright (c) 2010 Apple Inc. All rights reserved.
*
* @APPLE_LLVM_LICENSE_HEADER@
*/
// TEST_CONFIG rdar://6214670
// TEST_CFLAGS -framework Foundation
#import <Foundation/Foundation.h>
#import <Block.h>
#import "test.h"
int constructors = 0;
int destructors = 0;
#import <Block_private.h>
#define CONST const
class TestObject
{
public:
TestObject(CONST TestObject& inObj);
TestObject();
~TestObject();
TestObject& operator=(CONST TestObject& inObj);
int version() CONST { return _version; }
private:
mutable int _version;
};
TestObject::TestObject(CONST TestObject& inObj)
{
++constructors;
_version = inObj._version;
//printf("%p (%d) -- TestObject(const TestObject&) called\n", this, _version);
}
TestObject::TestObject()
{
_version = ++constructors;
//printf("%p (%d) -- TestObject() called\n", this, _version);
}
TestObject::~TestObject()
{
//printf("%p -- ~TestObject() called\n", this);
++destructors;
}
TestObject& TestObject::operator=(CONST TestObject& inObj)
{
//printf("%p -- operator= called\n", this);
_version = inObj._version;
return *this;
}
void testRoutine() {
TestObject one;
void (^b)(void) = [^{ printf("my copy of one is %d\n", one.version()); } copy];
#if 0
// just try one copy, one release
for (int i = 0; i < 10; ++i)
[b retain];
for (int i = 0; i < 10; ++i)
[b release];
for (int i = 0; i < 10; ++i)
Block_copy(b);
for (int i = 0; i < 10; ++i)
Block_release(b);
#endif
[b release];
}
int main() {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
//testGC();
for (int i = 0; i < 200; ++i) // do enough to trigger TLC if GC is on
testRoutine();
[pool drain];
if (constructors != destructors) {
fail("didn't recover %d const copies", constructors - destructors);
}
succeed(__FILE__);
}

64
objectTests/recovermany.m Normal file
View File

@ -0,0 +1,64 @@
/*
* Copyright (c) 2010 Apple Inc. All rights reserved.
*
* @APPLE_LLVM_LICENSE_HEADER@
*/
// TEST_CFLAGS -framework Foundation
#import <Foundation/Foundation.h>
#import <Block.h>
#import "test.h"
int recovered = 0;
@interface TestObject : NSObject {
}
@end
@implementation TestObject
- (void)dealloc {
++recovered;
[super dealloc];
}
@end
void testRoutine() {
__block id to = [[TestObject alloc] init];
__block int i = 10;
__block int j = 11;
__block int k = 12;
__block id to2 = [[TestObject alloc] init];
void (^b)(void) = [^{
[to self];
++i;
k = i + ++j;
[to2 self];
} copy];
for (int i = 0; i < 10; ++i)
[b retain];
for (int i = 0; i < 10; ++i)
[b release];
for (int i = 0; i < 10; ++i)
(void)Block_copy(b); // leak
for (int i = 0; i < 10; ++i)
Block_release(b);
[b release];
[to release];
// block_byref_release needed under non-GC to get rid of testobject
}
int main() {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
recovered = 0;
for (int i = 0; i < 200; ++i) // do enough to trigger TLC if GC is on
testRoutine();
[pool drain];
if (recovered == 0) {
fail("didn't recover byref block variable");
}
succeed(__FILE__);
}

View File

@ -0,0 +1,51 @@
/*
* Copyright (c) 2010 Apple Inc. All rights reserved.
*
* @APPLE_LLVM_LICENSE_HEADER@
*/
//
// recursive-assign-int.m
// testObjects
//
// Created by Blaine Garst on 12/4/08.
// Copyright 2008 __MyCompanyName__. All rights reserved.
//
// TEST_CONFIG rdar://6416474
// The compiler is prefetching x->forwarding before evaluting code that recomputes forwarding and so the value goes to a place that is never seen again.
#include <stdio.h>
#include <stdlib.h>
#include <Block.h>
#include "test.h"
typedef void (^blockOfVoidReturningVoid)(void);
blockOfVoidReturningVoid globalBlock;
int nTHCopy(blockOfVoidReturningVoid block) {
globalBlock = Block_copy(block);
return 1;
}
int main() {
__block int x = 0;
x = nTHCopy(^{
// x should be the value returned by nTHCopy
if (x != 1) {
fail("but it wasn't updated properly!");
}
});
globalBlock();
if (x == 0) {
fail("x here should be 1, but instead is: %d", x);
}
succeed(__FILE__);
}

View File

@ -0,0 +1,53 @@
/*
* Copyright (c) 2010 Apple Inc. All rights reserved.
*
* @APPLE_LLVM_LICENSE_HEADER@
*/
// TEST_CONFIG
#include <stdio.h>
#include <Block.h>
#include <Block_private.h>
#include <stdlib.h>
#include "test.h"
int cumulation = 0;
int doSomething(int i) {
cumulation += i;
return cumulation;
}
void dirtyStack() {
int i = (int)random();
int j = doSomething(i);
int k = doSomething(j);
doSomething(i + j + k);
}
typedef void (^voidVoid)(void);
voidVoid testFunction() {
int i = (int)random();
__block voidVoid inner = ^{ doSomething(i); };
//printf("inner, on stack, is %p\n", (void*)inner);
/*__block*/ voidVoid outer = ^{
//printf("will call inner block %p\n", (void *)inner);
inner();
};
//printf("outer looks like: %s\n", _Block_dump(outer));
voidVoid result = Block_copy(outer);
//Block_release(inner);
return result;
}
int main() {
voidVoid block = testFunction();
dirtyStack();
block();
Block_release(block);
succeed(__FILE__);
}

Some files were not shown because too many files have changed in this diff Show More