2010-06-06 21:11:25 +00:00
|
|
|
#import "objc/runtime.h"
|
|
|
|
#import "class.h"
|
|
|
|
#import "lock.h"
|
2009-11-17 21:13:41 +00:00
|
|
|
#import "objc/blocks_runtime.h"
|
2010-06-06 21:11:25 +00:00
|
|
|
#import "dtable.h"
|
2009-11-17 21:13:41 +00:00
|
|
|
#include <assert.h>
|
|
|
|
|
|
|
|
struct objc_class _NSConcreteGlobalBlock;
|
|
|
|
struct objc_class _NSConcreteStackBlock;
|
|
|
|
|
2009-12-20 16:49:27 +00:00
|
|
|
static struct objc_class _NSConcreteGlobalBlockMeta;
|
|
|
|
static struct objc_class _NSConcreteStackBlockMeta;
|
|
|
|
|
|
|
|
static struct objc_class _NSBlock;
|
|
|
|
static struct objc_class _NSBlockMeta;
|
|
|
|
|
|
|
|
static void createNSBlockSubclass(Class superclass, Class newClass,
|
|
|
|
Class metaClass, char *name)
|
|
|
|
{
|
2009-11-17 21:13:41 +00:00
|
|
|
// Initialize the metaclass
|
2010-03-12 22:47:10 +00:00
|
|
|
//metaClass->class_pointer = superclass->class_pointer;
|
|
|
|
//metaClass->super_class = superclass->class_pointer;
|
2010-06-06 21:11:25 +00:00
|
|
|
metaClass->info = objc_class_flag_meta;
|
2009-11-17 21:13:41 +00:00
|
|
|
metaClass->dtable = __objc_uninstalled_dtable;
|
|
|
|
|
|
|
|
// Set up the new class
|
2010-06-06 21:11:25 +00:00
|
|
|
newClass->isa = metaClass;
|
2010-03-12 22:59:36 +00:00
|
|
|
newClass->super_class = (Class)superclass->name;
|
2009-11-17 21:13:41 +00:00
|
|
|
newClass->name = name;
|
2010-06-06 21:11:25 +00:00
|
|
|
newClass->info = objc_class_flag_class;
|
2009-11-17 21:13:41 +00:00
|
|
|
newClass->dtable = __objc_uninstalled_dtable;
|
|
|
|
|
2010-06-06 21:11:25 +00:00
|
|
|
LOCK_UNTIL_RETURN(__objc_runtime_mutex);
|
|
|
|
class_table_insert(newClass);
|
2010-03-12 22:47:10 +00:00
|
|
|
|
2009-11-17 21:13:41 +00:00
|
|
|
}
|
|
|
|
|
2009-12-20 16:49:27 +00:00
|
|
|
#define NEW_CLASS(super, sub) \
|
|
|
|
createNSBlockSubclass(super, &sub, &sub ## Meta, #sub)
|
|
|
|
|
|
|
|
BOOL objc_create_block_classes_as_subclasses_of(Class super)
|
2009-11-17 21:13:41 +00:00
|
|
|
{
|
2009-12-20 16:49:27 +00:00
|
|
|
if (_NSBlock.super_class != NULL) { return NO; }
|
2009-11-17 21:13:41 +00:00
|
|
|
|
2009-12-20 16:49:27 +00:00
|
|
|
NEW_CLASS(super, _NSBlock);
|
|
|
|
NEW_CLASS(&_NSBlock, _NSConcreteStackBlock);
|
|
|
|
NEW_CLASS(&_NSBlock, _NSConcreteGlobalBlock);
|
2010-01-04 18:00:34 +00:00
|
|
|
return YES;
|
2009-12-20 16:49:27 +00:00
|
|
|
}
|