1 2#import <objc/objc.h> 3 4#if defined (__GNU_LIBOBJC__) 5 6#warning Unable to build NSBlocks for this runtime. 7 8/* FIXME ... these let us link, but blocks will be broken. 9 */ 10void *_NSConcreteStackBlock; 11BOOL objc_create_block_classes_as_subclasses_of(Class super) 12{ 13 return NO; 14} 15 16#else 17 18#import <objc/objc-api.h> 19#import "ObjectiveC2/objc/runtime.h" 20 21#import "ObjectiveC2/objc/blocks_runtime.h" 22#include <assert.h> 23 24struct objc_class _NSConcreteGlobalBlock; 25struct objc_class _NSConcreteStackBlock; 26 27static struct objc_class _NSConcreteGlobalBlockMeta; 28static struct objc_class _NSConcreteStackBlockMeta; 29 30static struct objc_class _NSBlock; 31static struct objc_class _NSBlockMeta; 32 33void __objc_update_dispatch_table_for_class(Class); 34extern struct sarray *__objc_uninstalled_dtable; 35extern objc_mutex_t __objc_runtime_mutex; 36 37static void 38createNSBlockSubclass(Class superclass, Class newClass, 39 Class metaClass, char *name) 40{ 41 // Initialize the metaclass 42 metaClass->class_pointer = superclass->class_pointer; 43 metaClass->super_class = superclass->class_pointer; 44 metaClass->info = _CLS_META; 45 metaClass->dtable = __objc_uninstalled_dtable; 46 47 // Set up the new class 48 newClass->class_pointer = metaClass; 49 newClass->super_class = superclass; 50 newClass->name = name; 51 newClass->info = _CLS_CLASS; 52 newClass->dtable = __objc_uninstalled_dtable; 53 54 // Initialize the dispatch table for the class and metaclass. 55 __objc_update_dispatch_table_for_class(metaClass); 56 __objc_update_dispatch_table_for_class(newClass); 57 CLS_SETINITIALIZED(metaClass); 58 CLS_SETINITIALIZED(newClass); 59 CLS_SETRESOLV(metaClass); 60 CLS_SETRESOLV(newClass); 61 // Add pointer from super class 62 objc_mutex_lock(__objc_runtime_mutex); 63 newClass->sibling_class = newClass->super_class->subclass_list; 64 newClass->super_class->subclass_list = newClass; 65 metaClass->sibling_class = metaClass->super_class->subclass_list; 66 metaClass->super_class->subclass_list = metaClass; 67 objc_mutex_unlock(__objc_runtime_mutex); 68} 69 70#define NEW_CLASS(super, sub) \ 71 createNSBlockSubclass(super, &sub, &sub ## Meta, #sub) 72 73BOOL objc_create_block_classes_as_subclasses_of(Class super) 74{ 75 if (_NSBlock.super_class != NULL) { return NO; } 76 77 NEW_CLASS(super, _NSBlock); 78 NEW_CLASS(&_NSBlock, _NSConcreteStackBlock); 79 NEW_CLASS(&_NSBlock, _NSConcreteGlobalBlock); 80 return YES; 81} 82 83#endif /* defined (__GNU_LIBOBJC__) */ 84 85