Update for the compiler / linker setting up superclass pointers.

In the legact ABI, superclass pointers are initially set to strings
containing the superclass name and the runtime fixes them up.  In the
new ABI, the compiler sets up the linkage directly.
main
David Chisnall 8 years ago
parent f3386c530e
commit 0964d63ba9

@ -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);
}

@ -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;
}

@ -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;

@ -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 |

Loading…
Cancel
Save