From 93ac6e7f2f9403c474e3d9414368fe6df4f664fe Mon Sep 17 00:00:00 2001 From: theraven Date: Sun, 20 Dec 2009 16:49:27 +0000 Subject: [PATCH] Fixed block class creation so libobjc2 no longer has a static dependency on NSObject. This lets blocks work without Foundation, just as on OS X. This requires GNUstep to call a runtime function when NSObject is loaded. --- NSBlocks.m | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/NSBlocks.m b/NSBlocks.m index 3ad1026..23a6145 100644 --- a/NSBlocks.m +++ b/NSBlocks.m @@ -6,19 +6,24 @@ struct objc_class _NSConcreteGlobalBlock; struct objc_class _NSConcreteStackBlock; +static struct objc_class _NSConcreteGlobalBlockMeta; +static struct objc_class _NSConcreteStackBlockMeta; + +static struct objc_class _NSBlock; +static struct objc_class _NSBlockMeta; + @interface NSBlock : NSObject @end void __objc_update_dispatch_table_for_class(Class); extern struct sarray *__objc_uninstalled_dtable; extern objc_mutex_t __objc_runtime_mutex; -static void createNSBlockSubclass(Class superclass, Class newClass, char *name) -{ - // Create the metaclass - Class metaClass = calloc(1, sizeof(struct objc_class)); +static void createNSBlockSubclass(Class superclass, Class newClass, + Class metaClass, char *name) +{ // Initialize the metaclass metaClass->class_pointer = superclass->class_pointer; - metaClass->super_class = superclass->class_pointer->super_class; + metaClass->super_class = superclass->class_pointer; metaClass->info = _CLS_META; metaClass->dtable = __objc_uninstalled_dtable; @@ -45,11 +50,14 @@ static void createNSBlockSubclass(Class superclass, Class newClass, char *name) objc_mutex_unlock(__objc_runtime_mutex); } -@implementation NSBlock -+ (void)load +#define NEW_CLASS(super, sub) \ + createNSBlockSubclass(super, &sub, &sub ## Meta, #sub) + +BOOL objc_create_block_classes_as_subclasses_of(Class super) { - createNSBlockSubclass(self, &_NSConcreteGlobalBlock, "_NSConcreteGlobalBlockPrivate"); - createNSBlockSubclass(self, &_NSConcreteStackBlock, "_NSConcreteStackBlockPrivate"); -} -@end + if (_NSBlock.super_class != NULL) { return NO; } + NEW_CLASS(super, _NSBlock); + NEW_CLASS(&_NSBlock, _NSConcreteStackBlock); + NEW_CLASS(&_NSBlock, _NSConcreteGlobalBlock); +}