diff --git a/NSBlocks.m b/NSBlocks.m index 32870da..2235069 100644 --- a/NSBlocks.m +++ b/NSBlocks.m @@ -1,5 +1,6 @@ #import "objc/runtime.h" #import "class.h" +#import "loader.h" #import "lock.h" #import "objc/blocks_runtime.h" #import "dtable.h" @@ -27,13 +28,13 @@ static void createNSBlockSubclass(Class superclass, Class newClass, // Set up the new class newClass->isa = metaClass; - newClass->super_class = (Class)superclass->name; + newClass->super_class = superclass; newClass->name = name; newClass->info = objc_class_flag_class; newClass->dtable = uninstalled_dtable; LOCK_RUNTIME_FOR_SCOPE(); - class_table_insert(newClass); + objc_load_class(newClass); } diff --git a/class_table.c b/class_table.c index e829a7e..f49276a 100644 --- a/class_table.c +++ b/class_table.c @@ -155,8 +155,7 @@ PRIVATE BOOL objc_resolve_class(Class cls) // We can only resolve the class if its superclass is resolved. if (cls->super_class) { - Class super = (Class)objc_getClass((char*)cls->super_class); - if (Nil == super) { return NO; } + Class super = cls->super_class; if (!objc_test_class_flag(super, objc_class_flag_resolved)) { @@ -166,6 +165,24 @@ PRIVATE BOOL objc_resolve_class(Class cls) } } } + else + { + struct legacy_gnustep_objc_class *ocls = objc_legacy_class_for_class(cls); + if (ocls != NULL) + { + const char *super_name = (const char*)ocls->super_class; + if (super_name) + { + Class super = (Class)objc_getClass(super_name); + if (super == Nil) + { + return NO; + } + cls->super_class = super; + return objc_resolve_class(cls); + } + } + } // Remove the class from the unresolved class list @@ -203,14 +220,13 @@ PRIVATE BOOL objc_resolve_class(Class cls) else { // Resolve the superclass if it isn't already resolved - Class super = (Class)objc_getClass((char*)cls->super_class); + Class super = cls->super_class; if (!objc_test_class_flag(super, objc_class_flag_resolved)) { objc_resolve_class(super); } superMeta = super->isa; // Set the superclass pointer for the class and the superclass - cls->super_class = super; do { metaMeta = super->isa; @@ -402,13 +418,6 @@ PRIVATE void objc_load_class(struct objc_class *class) return; } - // The compiler initialises the super class pointer to the name of the - // superclass, not the superclass pointer. - // Note: With the new ABI, the class pointer is public. We could, - // therefore, directly reference the superclass from the compiler and make - // the linker resolve it. This should be done in the GCC-incompatible ABI. - const char *superclassName = (char*)class->super_class; - // Work around a bug in some versions of GCC that don't initialize the // class structure correctly. class->subclass_list = NULL; @@ -422,7 +431,7 @@ PRIVATE void objc_load_class(struct objc_class *class) // If this is a root class, make the class into the metaclass's superclass. // This means that all instance methods will be available to the class. - if (NULL == superclassName) + if (NULL == class->super_class) { class->isa->super_class = class; } diff --git a/legacy.c b/legacy.c index 64d3668..6d8c22a 100644 --- a/legacy.c +++ b/legacy.c @@ -108,7 +108,7 @@ PRIVATE Class objc_upgrade_class(struct legacy_gnustep_objc_class *oldClass) { Class cls = calloc(sizeof(struct objc_class), 1); cls->isa = oldClass->isa; - cls->super_class = (struct objc_class*)oldClass->super_class; + // super_class is left nil and we upgrade it later. cls->name = oldClass->name; cls->version = oldClass->version; cls->info = oldClass->info; diff --git a/runtime.c b/runtime.c index ac153ae..0138906 100644 --- a/runtime.c +++ b/runtime.c @@ -199,7 +199,7 @@ BOOL class_addMethod(Class cls, SEL name, IMP imp, const char *types) methods->methods[0].types = strdup(types); methods->methods[0].imp = imp; - if (objc_test_class_flag(cls, objc_class_flag_resolved)) + if (classHasDtable(cls)) { add_method_list_to_class(cls, methods); } @@ -712,7 +712,7 @@ Class objc_allocateClassPair(Class superclass, const char *name, size_t extraByt // in objc_resolve_class(). // If the superclass is not yet resolved, then we need to look it up // via the class table. - metaClass->isa = (Class)superclass->isa->isa->name; + metaClass->isa = superclass->isa; metaClass->super_class = superclass->isa; } metaClass->name = strdup(name); @@ -723,9 +723,7 @@ Class objc_allocateClassPair(Class superclass, const char *name, size_t extraByt // Set up the new class newClass->isa = metaClass; - // Set the superclass pointer to the name. The runtime will fix this when - // the class links are resolved. - newClass->super_class = (Nil == superclass) ? Nil : (Class)(superclass->name); + newClass->super_class = superclass; newClass->name = strdup(name); newClass->info = objc_class_flag_class | objc_class_flag_user_created |