Improve +load handling

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/libobjc/trunk@16754 72102866-910b-0410-8b05-ffd578937521
main
CaS 23 years ago
parent 4f1798f647
commit d6a0da739c

@ -1,3 +1,7 @@
2003-05-20 Richard Frith-Macdonald <rrfm@gnu.org>
* init.c: Replace last change with Nicola's improved version.
2003-05-12 Richard Frith-Macdonald <rrfm@gnu.org> 2003-05-12 Richard Frith-Macdonald <rrfm@gnu.org>
* init.c: When performing superclass lookups, check to see if the * init.c: When performing superclass lookups, check to see if the

@ -99,17 +99,50 @@ static struct objc_list *__objc_class_tree_list = NULL;
should not be destroyed during the execution of the program. */ should not be destroyed during the execution of the program. */
static cache_ptr __objc_load_methods = NULL; static cache_ptr __objc_load_methods = NULL;
/* Return the super class by resorting to objc_lookup_class() /* This function is used when building the class tree used to send
if links are not yet resolved. */ ordinately the +load message to all classes needing it. The tree
static Class lookup_super(Class class) is really needed so that superclasses will get the message before
subclasses.
This tree will contain classes which are being loaded (or have just
being loaded), and whose super_class pointers have not yet been
resolved. This implies that their super_class pointers point to a
string with the name of the superclass; when the first message is
sent to the class (/an object of that class) the class links will
be resolved, which will replace the super_class pointers with
pointers to the actual superclasses.
Unfortunately, the tree might also contain classes which had been
loaded previously, and whose class links have already been
resolved.
This function returns the superclass of a class in both cases, and
can be used to build the determine the class relationships while
building the tree.
*/
static Class class_superclass_of_class (Class class)
{ {
if (class->super_class == Nil) char *super_class_name;
return Nil;
if (CLS_ISRESOLV(class)) /* If the class links have been resolved, use the resolved
* links. */
if (CLS_ISRESOLV (class))
return class->super_class; return class->super_class;
return objc_lookup_class((char*)class->super_class);
/* Else, 'class' has not yet been resolved. This means that its
* super_class pointer is really the name of the super class (rather
* than a pointer to the actual superclass). */
super_class_name = (char *)class->super_class;
/* Return Nil for a root class. */
if (super_class_name == NULL)
return Nil;
/* Lookup the superclass of non-root classes. */
return objc_lookup_class (super_class_name);
} }
/* Creates a tree of classes whose topmost class is directly inherited /* Creates a tree of classes whose topmost class is directly inherited
from `upper' and the bottom class in this tree is from `upper' and the bottom class in this tree is
`bottom_class'. The classes in this tree are super classes of `bottom_class'. The classes in this tree are super classes of
@ -119,8 +152,10 @@ static Class lookup_super(Class class)
static objc_class_tree * static objc_class_tree *
create_tree_of_subclasses_inherited_from (Class bottom_class, Class upper) create_tree_of_subclasses_inherited_from (Class bottom_class, Class upper)
{ {
Class superclass = lookup_super(bottom_class); Class superclass = bottom_class->super_class ?
objc_lookup_class ((char *) bottom_class->super_class)
: Nil;
objc_class_tree *tree, *prev; objc_class_tree *tree, *prev;
DEBUG_PRINTF ("create_tree_of_subclasses_inherited_from:"); DEBUG_PRINTF ("create_tree_of_subclasses_inherited_from:");
@ -131,12 +166,12 @@ create_tree_of_subclasses_inherited_from (Class bottom_class, Class upper)
tree = prev = objc_calloc (1, sizeof (objc_class_tree)); tree = prev = objc_calloc (1, sizeof (objc_class_tree));
prev->class = bottom_class; prev->class = bottom_class;
while (superclass != Nil && superclass != upper) while (superclass != upper)
{ {
tree = objc_calloc (1, sizeof (objc_class_tree)); tree = objc_calloc (1, sizeof (objc_class_tree));
tree->class = superclass; tree->class = superclass;
tree->subclasses = list_cons (prev, tree->subclasses); tree->subclasses = list_cons (prev, tree->subclasses);
superclass = lookup_super(superclass); superclass = class_superclass_of_class (superclass);
prev = tree; prev = tree;
} }
@ -164,7 +199,7 @@ __objc_tree_insert_class (objc_class_tree *tree, Class class)
DEBUG_PRINTF ("1. class %s was previously inserted\n", class->name); DEBUG_PRINTF ("1. class %s was previously inserted\n", class->name);
return tree; return tree;
} }
else if (lookup_super(class) == tree->class) else if (class_superclass_of_class (class) == tree->class)
{ {
/* If class is a direct subclass of tree->class then add class to the /* If class is a direct subclass of tree->class then add class to the
list of subclasses. First check to see if it wasn't already list of subclasses. First check to see if it wasn't already
@ -374,7 +409,7 @@ class_is_subclass_of_class (Class class, Class superclass)
{ {
if (class == superclass) if (class == superclass)
return YES; return YES;
class = lookup_super(class); class = class_superclass_of_class (class);
} }
return NO; return NO;
@ -564,7 +599,7 @@ __objc_exec_class (Module_t module)
/* Check to see if the superclass is known in this point. If it's not /* Check to see if the superclass is known in this point. If it's not
add the class to the unresolved_classes list. */ add the class to the unresolved_classes list. */
if (superclass && ! lookup_super (class)) if (superclass && ! objc_lookup_class (superclass))
unresolved_classes = list_cons (class, unresolved_classes); unresolved_classes = list_cons (class, unresolved_classes);
} }
@ -676,7 +711,7 @@ objc_send_load (void)
{ {
Class class = unresolved_classes->head; Class class = unresolved_classes->head;
while (lookup_super (class)) while (objc_lookup_class ((char *) class->super_class))
{ {
list_remove_head (&unresolved_classes); list_remove_head (&unresolved_classes);
if (unresolved_classes) if (unresolved_classes)
@ -698,7 +733,6 @@ objc_send_load (void)
other classes are known, delay sending of +load. */ other classes are known, delay sending of +load. */
if (!objc_lookup_class ("NXConstantString") || if (!objc_lookup_class ("NXConstantString") ||
!objc_lookup_class ("Object")) !objc_lookup_class ("Object"))
return;
#else #else
/* /*
* The above check prevents +load being called at all if NXConstantString * The above check prevents +load being called at all if NXConstantString

Loading…
Cancel
Save