Index: src/runtime/class.m ================================================================== --- src/runtime/class.m +++ src/runtime/class.m @@ -160,10 +160,36 @@ cls->superclass->name); cls->superclass->subclass_list[i] = cls; cls->superclass->subclass_list[i + 1] = Nil; } + +static void +setup_class(Class cls) +{ + const char *superclass; + + if (cls->info & OBJC_CLASS_INFO_SETUP) + return; + + if ((superclass = ((struct objc_abi_class*)cls)->superclass) != NULL) { + if ((cls->superclass = objc_lookup_class(superclass)) == Nil) + return; + + cls->isa->superclass = cls->superclass->isa; + + add_subclass(cls); + add_subclass(cls->isa); + } else + cls->isa->superclass = cls; + + objc_update_dtable(cls); + objc_update_dtable(cls->isa); + + cls->info |= OBJC_CLASS_INFO_SETUP; + cls->isa->info |= OBJC_CLASS_INFO_SETUP; +} inline Class objc_classname_to_class(const char *name) { Class c; @@ -196,11 +222,10 @@ inline Class objc_lookup_class(const char *name) { Class cls = objc_classname_to_class(name); - const char *superclass; if (cls == NULL) return Nil; if (cls->info & OBJC_CLASS_INFO_INITIALIZED) @@ -216,26 +241,18 @@ if (cls->info & OBJC_CLASS_INFO_INITIALIZED) { objc_global_mutex_unlock(); return cls; } - if ((superclass = ((struct objc_abi_class*)cls)->superclass) != NULL) { - if ((cls->superclass = objc_lookup_class(superclass)) == Nil) { - objc_global_mutex_unlock(); - return Nil; - } - - cls->isa->superclass = cls->superclass->isa; - - add_subclass(cls); - add_subclass(cls->isa); - } else - cls->isa->superclass = cls; - - objc_update_dtable(cls); - objc_update_dtable(cls->isa); - + setup_class(cls); + + if (!(cls->info & OBJC_CLASS_INFO_SETUP)) { + objc_global_mutex_unlock(); + return Nil; + } + + /* Set it first to prevent calling it recursively */ cls->info |= OBJC_CLASS_INFO_INITIALIZED; cls->isa->info |= OBJC_CLASS_INFO_INITIALIZED; call_initialize(cls); Index: src/runtime/runtime-private.h ================================================================== --- src/runtime/runtime-private.h +++ src/runtime/runtime-private.h @@ -117,11 +117,13 @@ }; enum objc_abi_class_info { OBJC_CLASS_INFO_CLASS = 0x01, OBJC_CLASS_INFO_METACLASS = 0x02, - OBJC_CLASS_INFO_INITIALIZED = 0x04 + OBJC_CLASS_INFO_SETUP = 0x04, + OBJC_CLASS_INFO_LOADED = 0x08, + OBJC_CLASS_INFO_INITIALIZED = 0x10 }; typedef struct { of_mutex_t mutex; of_thread_t owner;