X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=libobjc%2Finit.c;h=fc3d7ff3c0cd3feb0a9a992badb9dceb58bcc7a4;hb=38fecea44e0d352440294c1c3337bcce542ad5e3;hp=098e253649ff9dc6b016432658de1e27552acb87;hpb=617763557711795ccc8087e4c7af30832f1af171;p=pf3gnuchains%2Fgcc-fork.git diff --git a/libobjc/init.c b/libobjc/init.c index 098e253649f..fc3d7ff3c0c 100644 --- a/libobjc/init.c +++ b/libobjc/init.c @@ -3,20 +3,20 @@ Contributed by Kresten Krab Thorup +load support contributed by Ovidiu Predescu -This file is part of GNU CC. +This file is part of GCC. -GNU CC is free software; you can redistribute it and/or modify it under the +GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. -GNU CC is distributed in the hope that it will be useful, but WITHOUT ANY +GCC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with -GNU CC; see the file COPYING. If not, write to the Free Software -Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +GCC; see the file COPYING. If not, write to the Free Software +Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* As a special exception, if you link this library with files compiled with GCC to produce an executable, this does not cause the resulting executable @@ -24,7 +24,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ however invalidate any other reasons why the executable file might be covered by the GNU General Public License. */ -#include "runtime.h" +#include "objc/runtime.h" /* The version number of this runtime. This must match the number defined in gcc (objc-act.c). */ @@ -99,6 +99,50 @@ static struct objc_list *__objc_class_tree_list = NULL; should not be destroyed during the execution of the program. */ static cache_ptr __objc_load_methods = NULL; +/* This function is used when building the class tree used to send + ordinately the +load message to all classes needing it. The tree + 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) +{ + char *super_class_name; + + /* If the class links have been resolved, use the resolved + * links. */ + if (CLS_ISRESOLV (class)) + return 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 from `upper' and the bottom class in this tree is `bottom_class'. The classes in this tree are super classes of @@ -127,9 +171,7 @@ create_tree_of_subclasses_inherited_from (Class bottom_class, Class upper) tree = objc_calloc (1, sizeof (objc_class_tree)); tree->class = superclass; tree->subclasses = list_cons (prev, tree->subclasses); - superclass = (superclass->super_class ? - objc_lookup_class ((char *) superclass->super_class) - : Nil); + superclass = class_superclass_of_class (superclass); prev = tree; } @@ -157,10 +199,7 @@ __objc_tree_insert_class (objc_class_tree *tree, Class class) DEBUG_PRINTF ("1. class %s was previously inserted\n", class->name); return tree; } - else if ((class->super_class ? - objc_lookup_class ((char *) class->super_class) - : Nil) - == 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 list of subclasses. First check to see if it wasn't already @@ -324,10 +363,12 @@ __objc_send_message_in_list (MethodList_t method_list, Class class, SEL op) Method_t mth = &method_list->method_list[i]; if (mth->method_name && sel_eq (mth->method_name, op) - && ! hash_is_key_in_hash (__objc_load_methods, mth->method_imp)) + && ! objc_hash_is_key_in_hash (__objc_load_methods, mth->method_imp)) { /* Add this method into the +load hash table */ - hash_add (&__objc_load_methods, mth->method_imp, mth->method_imp); + objc_hash_add (&__objc_load_methods, + mth->method_imp, + mth->method_imp); DEBUG_PRINTF ("sending +load in class: %s\n", class->name); @@ -370,9 +411,7 @@ class_is_subclass_of_class (Class class, Class superclass) { if (class == superclass) return YES; - class = (class->super_class ? - objc_lookup_class ((char *) class->super_class) - : Nil); + class = class_superclass_of_class (class); } return NO; @@ -501,8 +540,9 @@ __objc_exec_class (Module_t module) __objc_init_class_tables (); __objc_init_dispatch_tables (); __objc_class_tree_list = list_cons (NULL, __objc_class_tree_list); - __objc_load_methods - = hash_new (128, (hash_func_type)hash_ptr, compare_ptrs); + __objc_load_methods = objc_hash_new (128, + (hash_func_type)objc_hash_ptr, + objc_compare_ptrs); previous_constructors = 1; }