OSDN Git Service

2008-05-22 Andrew Haley <aph@redhat.com>
[pf3gnuchains/gcc-fork.git] / libobjc / init.c
index 098e253..fc3d7ff 100644 (file)
@@ -3,20 +3,20 @@
    Contributed by Kresten Krab Thorup
    +load support contributed by Ovidiu Predescu <ovidiu@net-community.com>
 
-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;
     }