/* GNU Objective C Runtime initialization 
   Copyright (C) 1993-2021 Free Software Foundation, Inc.
   Contributed by Kresten Krab Thorup
   +load support contributed by Ovidiu Predescu <ovidiu@net-community.com>

This file is part of GCC.

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 3, or (at your option) any later version.

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.

Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.

You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
<http://www.gnu.org/licenses/>.  */

/* Uncommented the following line to enable debug logging.  Use this
   only while debugging the runtime.  */
/* #define DEBUG 1 */

#include "objc-private/common.h"
#include "objc-private/error.h"
#include "objc/runtime.h"
#include "objc/thr.h"
#include "objc-private/hash.h"
#include "objc-private/objc-list.h" 
#include "objc-private/module-abi-8.h" 
#include "objc-private/runtime.h"   /* For __objc_resolve_class_links().  */
#include "objc-private/selector.h"  /* For __sel_register_typed_name().  */
#include "objc-private/objc-sync.h" /* For __objc_sync_init() */
#include "objc-private/protocols.h" /* For __objc_protocols_init(),
				       __objc_protocols_add_protocol()
				       __objc_protocols_register_selectors() */
#include "objc-private/accessors.h" /* For __objc_accessors_init() */

/* The version number of this runtime.  This must match the number
   defined in gcc (objc-act.c).  */
#define OBJC_VERSION 8
#define PROTOCOL_VERSION 2

/* This list contains modules currently loaded into the runtime and
   for which the +load method (and the load callback, if any) has not
   been called yet.  */
static struct objc_list *__objc_module_list = 0; 	/* !T:MUTEX */

/* This list contains all proto_list's not yet assigned class
   links.  */
static struct objc_list *unclaimed_proto_list = 0; 	/* !T:MUTEX */

/* List of unresolved static instances.  */
static struct objc_list *uninitialized_statics = 0; 	/* !T:MUTEX */

/* List of duplicated classes found while loading modules.  If we find
   a class twice, we ignore it the second time.  On some platforms,
   where the order in which modules are loaded is well defined, this
   allows you to replace a class in a shared library by linking in a
   new implementation which is loaded in in the right order, and which
   overrides the existing one.

   Protected by __objc_runtime_mutex.  */
static cache_ptr duplicate_classes = NULL;

/* Global runtime "write" mutex.  Having a single mutex prevents
   deadlocks, but reduces concurrency.  To improve concurrency, some
   groups of functions in the runtime have their own separate mutex
   (eg, __class_table_lock in class.c); to avoid deadlocks, these
   routines must make sure that they never acquire any other lock
   while holding their own local lock.  Ie, they should lock, execute
   some C code that does not perform any calls to other runtime
   functions which may potentially lock different locks, then unlock.
   If they need to perform any calls to other runtime functions that
   may potentially lock other locks, then they should use the global
   __objc_runtime_mutex.  */
objc_mutex_t __objc_runtime_mutex = 0;

/* Number of threads that are alive.  */
int __objc_runtime_threads_alive = 1;			/* !T:MUTEX */

/* Check compiler vs runtime version.  */
static void init_check_module_version (struct objc_module *);

/* Assign isa links to protos.  */
static void __objc_init_protocols (struct objc_protocol_list *protos);

/* Assign isa link to a protocol, and register it.  */
static void __objc_init_protocol (struct objc_protocol *protocol);

/* Add protocol to class.  */
static void __objc_class_add_protocols (Class, struct objc_protocol_list *);

/* Load callback hook.  */
void (*_objc_load_callback) (Class class, struct objc_category *category) = 0; /* !T:SAFE */

/* Are all categories/classes resolved ?  */
BOOL __objc_dangling_categories = NO;           /* !T:UNUSED */

/* Sends +load to all classes and categories in certain
   situations.  */
static void objc_send_load (void);

/* Inserts all the classes defined in module in a tree of classes that
   resembles the class hierarchy.  This tree is traversed in preorder
   and the classes in its nodes receive the +load message if these
   methods were not executed before.  The algorithm ensures that when
   the +load method of a class is executed all the superclasses have
   been already received the +load message.  */
static void __objc_create_classes_tree (struct objc_module *module);

/* Calls the _objc_load_callback for each class and category in the
   module (if _objc_load_callback is not NULL).  */
static void __objc_call_load_callback (struct objc_module *module);

/* A special version that works only before the classes are completely
   installed in the runtime.  */
static BOOL class_is_subclass_of_class (Class class, Class superclass);

/* This is a node in the class tree hierarchy used to send +load
   messages.  */
typedef struct objc_class_tree
{
  /* The class corresponding to the node.  */
  Class class;

  /* This is a linked list of all the direct subclasses of this class.
     'head' points to a subclass node; 'tail' points to the next
     objc_list node (whose 'head' points to another subclass node,
     etc).  */
  struct objc_list *subclasses;
} objc_class_tree;

/* This is a linked list of objc_class_tree trees.  The head of these
   trees are root classes (their super class is Nil).  These different
   trees represent different class hierarchies.  */
static struct objc_list *__objc_class_tree_list = NULL;

/* Keeps the +load methods who have been already executed. This hash
   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 may 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_getClass (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'.
   If `upper' is Nil, creates a class hierarchy up to a root class.
   The classes in this tree are super classes of `bottom_class'.  The
   `subclasses' member of each tree node point to the list of
   subclasses for the node.  */
static objc_class_tree *
create_tree_of_subclasses_inherited_from (Class bottom_class, Class upper)
{
  Class superclass;
  objc_class_tree *tree, *prev;

  DEBUG_PRINTF ("create_tree_of_subclasses_inherited_from:");
  DEBUG_PRINTF (" bottom_class = %s, upper = %s\n",
		(bottom_class ? bottom_class->name : NULL),
		(upper ? upper->name : NULL));

  superclass = class_superclass_of_class (bottom_class);

  prev = objc_calloc (1, sizeof (objc_class_tree));
  prev->class = bottom_class;

  if (superclass == upper)
    return prev;

  while (superclass != upper)
    {
      tree = objc_calloc (1, sizeof (objc_class_tree));
      tree->class = superclass;
      tree->subclasses = list_cons (prev, tree->subclasses);
      superclass = class_superclass_of_class (superclass);
      prev = tree;
    }

  return tree;
}

/* Insert the `class' into the proper place in the `tree' class
   hierarchy.  This function returns a new tree if the class has been
   successfully inserted into the tree or NULL if the class is not
   part of the classes hierarchy described by `tree'.  This function
   is private to objc_tree_insert_class (), you should not call it
   directly.  */
static objc_class_tree *
__objc_tree_insert_class (objc_class_tree *tree, Class class)
{
  DEBUG_PRINTF ("__objc_tree_insert_class: tree = %p (root: %s), class = %s\n",
		tree, ((tree && tree->class) ? tree->class->name : "Nil"), class->name);

  if (tree == NULL)
    return create_tree_of_subclasses_inherited_from (class, NULL);
  else if (class == tree->class)
    {
      /* `class' has been already inserted.  */
      DEBUG_PRINTF (" 1. class %s was previously inserted\n", class->name);
      return tree;
    }
  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 inserted.  */
      struct objc_list *list = tree->subclasses;
      objc_class_tree *node;

      while (list)
	{
	  /* Class has been already inserted; do nothing just return
	     the tree.  */
	  if (((objc_class_tree *) list->head)->class == class)
	    {
	      DEBUG_PRINTF (" 2. class %s was previously inserted\n",
			    class->name);
	      return tree;
	    }
	  list = list->tail;
	}

      /* Create a new node class and insert it into the list of
	 subclasses.  */
      node = objc_calloc (1, sizeof (objc_class_tree));
      node->class = class;
      tree->subclasses = list_cons (node, tree->subclasses);
      DEBUG_PRINTF (" 3. class %s inserted\n", class->name);
      return tree;
    }
  else
    {
      /* The class is not a direct subclass of tree->class.  Search
         for class's superclasses in the list of subclasses.  */
      struct objc_list *subclasses = tree->subclasses;

      /* Precondition: the class must be a subclass of tree->class;
         otherwise return NULL to indicate our caller that it must
         take the next tree.  */
      if (! class_is_subclass_of_class (class, tree->class))
	return NULL;

      for (; subclasses != NULL; subclasses = subclasses->tail)
	{
	  Class aClass = ((objc_class_tree *) (subclasses->head))->class;

	  if (class_is_subclass_of_class (class, aClass))
	    {
	      /* If we found one of class's superclasses we insert the
	         class into its subtree and return the original tree
	         since nothing has been changed.  */
	      subclasses->head
		  = __objc_tree_insert_class (subclasses->head, class);
 	      DEBUG_PRINTF (" 4. class %s inserted\n", class->name);
	      return tree;
	    }
	}

      /* We haven't found a subclass of `class' in the `subclasses'
         list.  Create a new tree of classes whose topmost class is a
         direct subclass of tree->class.  */
      {
	objc_class_tree *new_tree
	  = create_tree_of_subclasses_inherited_from (class, tree->class);
	tree->subclasses = list_cons (new_tree, tree->subclasses);
 	DEBUG_PRINTF (" 5. class %s inserted\n", class->name);
	return tree;
      }
    }
}

/* This function inserts `class' in the right tree hierarchy classes.  */
static void
objc_tree_insert_class (Class class)
{
  struct objc_list *list_node;
  objc_class_tree *tree;
  
  list_node = __objc_class_tree_list;
  while (list_node)
    {
      /* Try to insert the class in this class hierarchy.  */
      tree = __objc_tree_insert_class (list_node->head, class);
      if (tree)
	{
	  list_node->head = tree;
	  return;
	}
      else
	list_node = list_node->tail;
    }
  
  /* If the list was finished but the class hasn't been inserted, we
     don't have an existing class hierarchy that can accommodate it.
     Create a new one.  */
  __objc_class_tree_list = list_cons (NULL, __objc_class_tree_list);
  __objc_class_tree_list->head = __objc_tree_insert_class (NULL, class);
}

/* Traverse tree in preorder. Used to send +load.  */
static void
objc_preorder_traverse (objc_class_tree *tree,
			int level,
			void (*function) (objc_class_tree *, int))
{
  struct objc_list *node;

  (*function) (tree, level);
  for (node = tree->subclasses; node; node = node->tail)
    objc_preorder_traverse (node->head, level + 1, function);
}

/* Traverse tree in postorder. Used to destroy a tree.  */
static void
objc_postorder_traverse (objc_class_tree *tree,
			 int level,
			 void (*function) (objc_class_tree *, int))
{
  struct objc_list *node;

  for (node = tree->subclasses; node; node = node->tail)
    objc_postorder_traverse (node->head, level + 1, function);
  (*function) (tree, level);
}

/* Used to print a tree class hierarchy.  */
#ifdef DEBUG
static void
__objc_tree_print (objc_class_tree *tree, int level)
{
  int i;

  for (i = 0; i < level; i++)
    printf ("  ");
  printf ("%s\n", tree->class->name);
}
#endif

/* Walks on a linked list of methods in the reverse order and executes
   all the methods corresponding to the `+load' selector.  Walking in
   the reverse order assures the +load of class is executed first and
   then +load of categories because of the way in which categories are
   added to the class methods.  This function needs to be called with
   the objc_runtime_mutex locked.  */
static void
__objc_send_load_using_method_list (struct objc_method_list *method_list, Class class)
{
  static SEL load_selector = 0;
  int i;

  if (!method_list)
    return;

  /* This needs no lock protection because we are called with the
     objc_runtime_mutex locked.  */
  if (!load_selector)
    load_selector = sel_registerName ("load");

  /* method_list is a linked list of method lists; since we're
     executing in reverse order, we need to do the next list before we
     do this one.  */
  __objc_send_load_using_method_list (method_list->method_next, class);

  /* Search the method list.  */
  for (i = 0; i < method_list->method_count; i++)
    {
      struct objc_method *mth = &method_list->method_list[i];

      /* We are searching for +load methods that we haven't executed
	 yet.  */
      if (mth->method_name && sel_eq (mth->method_name, load_selector)
	  && ! objc_hash_is_key_in_hash (__objc_load_methods, mth->method_imp))
	{
	  /* Add this method into the +load hash table, so we won't
	     execute it again next time.  */
	  objc_hash_add (&__objc_load_methods,
			 mth->method_imp,
			 mth->method_imp);
	  
	  /* Call +load.  */
	  DEBUG_PRINTF (" begin of [%s +load]\n", class->name);
	  (*mth->method_imp) ((id)class, mth->method_name);
	  DEBUG_PRINTF (" end of [%s +load]\n", class->name);

	  break;
	}
    }
}

/* This function needs to be called with the objc_runtime_mutex
   locked.  */
static void
__objc_send_load (objc_class_tree *tree,
		  int level __attribute__ ((__unused__)))
{
  Class class = tree->class;
  struct objc_method_list *method_list = class->class_pointer->methods;

  DEBUG_PRINTF ("+load: need to send load to class '%s'\n", class->name);
  __objc_send_load_using_method_list (method_list, class);
}

static void
__objc_destroy_class_tree_node (objc_class_tree *tree,
				int level __attribute__ ((__unused__)))
{
  objc_free (tree);
}

/* This is used to check if the relationship between two classes
   before the runtime completely installs the classes.  */
static BOOL
class_is_subclass_of_class (Class class, Class superclass)
{
  for (; class != Nil;)
    {
      if (class == superclass)
	return YES;
      class = class_superclass_of_class (class);
    }

  return NO;
}

/* This list contains all the classes in the runtime system for whom
   their superclasses are not yet known to the runtime.  */
static struct objc_list *unresolved_classes = 0;

/* Extern function used to reference the Object class.  */
extern void __objc_force_linking (void);

void
__objc_force_linking (void)
{
  extern void __objc_linking (void);
  __objc_linking ();
}

/* Run through the statics list, removing modules as soon as all its
   statics have been initialized.  */
static void
objc_init_statics (void)
{
  struct objc_list **cell = &uninitialized_statics;
  struct objc_static_instances **statics_in_module;

  objc_mutex_lock (__objc_runtime_mutex);

  while (*cell)
    {
      int module_initialized = 1;

      for (statics_in_module = (*cell)->head;
	   *statics_in_module; statics_in_module++)
	{
	  struct objc_static_instances *statics = *statics_in_module;
	  Class class = objc_getClass (statics->class_name);

	  if (! class)
	    {
	      /* It is unfortunate that this will cause all the
		 statics initialization to be done again (eg, if we
		 already initialized constant strings, and are now
		 initializing protocols, setting module_initialized to
		 0 would cause constant strings to be initialized
		 again).  It would be good to be able to track if we
		 have already initialized some of them.  */
	      module_initialized = 0;
	    }
	  else
	    {
	      /* Note that if this is a list of Protocol objects, some
		 of them may have been initialized already (because
		 they were attached to classes or categories, and the
		 class/category loading code automatically fixes them
		 up), and some of them may not.  We really need to go
		 through the whole list to be sure!  Protocols are
		 also special because we want to register them and
		 register all their selectors.  */
	      id *inst;

	      if (strcmp (statics->class_name, "Protocol") == 0)
		{
		  /* Protocols are special, because not only we want
		     to fix up their class pointers, but we also want
		     to register them and their selectors with the
		     runtime.  */
		  for (inst = &statics->instances[0]; *inst; inst++)
		    __objc_init_protocol ((struct objc_protocol *)*inst);
		}
	      else
		{
		  /* Other static instances (typically constant
		     strings) are easier as we just fix up their class
		     pointers.  */
		  for (inst = &statics->instances[0]; *inst; inst++)		  
		    (*inst)->class_pointer = class;
		}
	    }
	}
      if (module_initialized)
	{
	  /* Remove this module from the uninitialized list.  */
	  struct objc_list *this = *cell;
	  *cell = this->tail;
	  objc_free (this);
	}
      else
	cell = &(*cell)->tail;
    }

  objc_mutex_unlock (__objc_runtime_mutex);
}

/* This function is called by constructor functions generated for each
   module compiled.  (_GLOBAL_$I$...) The purpose of this function is
   to gather the module pointers so that they may be processed by the
   initialization routines as soon as possible.  */
void
__objc_exec_class (struct objc_module *module)
{
  /* Have we processed any constructors previously?  This flag is used
     to indicate that some global data structures need to be
     built.  */
  static BOOL previous_constructors = 0;

  static struct objc_list *unclaimed_categories = 0;

  /* The symbol table (defined in objc-private/module-abi-8.h)
     generated by gcc.  */
  struct objc_symtab *symtab = module->symtab;

  /* The statics in this module.  */
  struct objc_static_instances **statics
    = symtab->defs[symtab->cls_def_cnt + symtab->cat_def_cnt];

  /* Entry used to traverse hash lists.  */
  struct objc_list **cell;

  /* The table of selector references for this module.  */
  struct objc_selector *selectors = symtab->refs;

  int i;

  DEBUG_PRINTF ("\n__objc_exec_class (%p) - start processing module...\n", module);

  /* Check gcc version.  */
  init_check_module_version (module);

  /* On the first call of this routine, initialize some data
     structures.  */
  if (! previous_constructors)
    {
	/* Initialize thread-safe system.  */
      __objc_init_thread_system ();
      __objc_runtime_threads_alive = 1;
      __objc_runtime_mutex = objc_mutex_allocate ();

      __objc_init_selector_tables ();
      __objc_init_class_tables ();
      __objc_init_dispatch_tables ();
      duplicate_classes = objc_hash_new (8,
					 (hash_func_type)objc_hash_ptr,
					 objc_compare_ptrs);
      __objc_load_methods = objc_hash_new (128, 
					   (hash_func_type)objc_hash_ptr,
					   objc_compare_ptrs);
      __objc_protocols_init ();
      __objc_accessors_init ();
      __objc_sync_init ();
      previous_constructors = 1;
    }

  /* Save the module pointer so that later we remember to call +load
     on all classes and categories on it.  */
  objc_mutex_lock (__objc_runtime_mutex);
  __objc_module_list = list_cons (module, __objc_module_list);

  /* Replace referenced selectors from names to SELs.  */
  if (selectors)
    {
      DEBUG_PRINTF (" registering selectors\n");
      __objc_register_selectors_from_module (selectors);
    }

  /* Parse the classes in the load module and gather selector
     information.  */
  for (i = 0; i < symtab->cls_def_cnt; ++i)
    {
      Class class = (Class) symtab->defs[i];
      const char *superclass = (char *) class->super_class;

      /* Make sure we have what we think.  */
      assert (CLS_ISCLASS (class));
      assert (CLS_ISMETA (class->class_pointer));
      DEBUG_PRINTF (" installing class '%s'\n", class->name);

      /* Workaround for a bug in clang: Clang may set flags other than
	 _CLS_CLASS and _CLS_META even when compiling for the
	 traditional ABI (version 8), confusing our runtime.  Try to
	 wipe these flags out.  */
      if (CLS_ISCLASS (class))
	__CLS_INFO (class) = _CLS_CLASS;
      else
	__CLS_INFO (class) = _CLS_META;

      /* Initialize the subclass list to be NULL.  In some cases it
	 isn't and this crashes the program.  */
      class->subclass_list = NULL;

      if (__objc_init_class (class))
	{
	  /* Check to see if the superclass is known in this point. If
	     it's not add the class to the unresolved_classes list.  */
	  if (superclass && ! objc_getClass (superclass))
	    unresolved_classes = list_cons (class, unresolved_classes);
	}
    }

  /* Process category information from the module.  */
  for (i = 0; i < symtab->cat_def_cnt; ++i)
    {
      struct objc_category *category = symtab->defs[i + symtab->cls_def_cnt];
      Class class = objc_getClass (category->class_name);
      
      /* If the class for the category exists then append its
	 methods.  */
      if (class)
	{
	  DEBUG_PRINTF (" installing category '%s (%s)'\n", category->class_name, category->category_name);
	  /* Do instance methods.  */
	  if (category->instance_methods)
	    class_add_method_list (class, category->instance_methods);

	  /* Do class methods.  */
	  if (category->class_methods)
	    class_add_method_list ((Class) class->class_pointer, 
				   category->class_methods);

	  if (category->protocols)
	    {
	      __objc_init_protocols (category->protocols);
	      __objc_class_add_protocols (class, category->protocols);
	    }

          /* Register the instance methods as class methods, this is
             only done for root classes.  */
          __objc_register_instance_methods_to_class (class);
	}
      else
	{
	  DEBUG_PRINTF (" delaying installation of category '%s (%s)'\n", category->class_name, category->category_name);
	  /* The object to which the category methods belong can't be
	     found.  Save the information.  */
	  unclaimed_categories = list_cons (category, unclaimed_categories);
	}
    }

  if (statics)
    uninitialized_statics = list_cons (statics, uninitialized_statics);
  if (uninitialized_statics)
    objc_init_statics ();

  /* Scan the unclaimed category hash.  Attempt to attach any
     unclaimed categories to objects.  */
  for (cell = &unclaimed_categories; *cell; )
    {
      struct objc_category *category = (*cell)->head;
      Class class = objc_getClass (category->class_name);
      
      if (class)
	{
	  DEBUG_PRINTF (" installing (delayed) category '%s (%s)'\n", category->class_name, category->category_name);
	  list_remove_head (cell);
	  
	  if (category->instance_methods)
	    class_add_method_list (class, category->instance_methods);
	  
	  if (category->class_methods)
	    class_add_method_list ((Class) class->class_pointer,
				   category->class_methods);

	  if (category->protocols)
	    {
	      __objc_init_protocols (category->protocols);
	      __objc_class_add_protocols (class, category->protocols);
	    }

          /* Register the instance methods as class methods, this is
             only done for root classes.  */
          __objc_register_instance_methods_to_class (class);
	}
      else
	cell = &(*cell)->tail;
    }
  
  if (unclaimed_proto_list && objc_getClass ("Protocol"))
    {
      list_mapcar (unclaimed_proto_list,
		   (void (*) (void *))__objc_init_protocols);
      list_free (unclaimed_proto_list);
      unclaimed_proto_list = 0;
    }

  objc_send_load ();

  /* Check if there are no unresolved classes (ie, classes whose
     superclass has not been loaded yet) and that the 'Object' class,
     used as the class of classes, exist.  If so, it is worth
     "resolving the class links" at this point, which will setup all
     the class/superclass pointers.  */
  if (!unresolved_classes && objc_getClass ("Object"))
    {
      DEBUG_PRINTF (" resolving class links\n");
      __objc_resolve_class_links ();
    }

  objc_mutex_unlock (__objc_runtime_mutex);

  DEBUG_PRINTF ("__objc_exec_class (%p) - finished processing module...\n\n", module);
}

/* This function needs to be called with the objc_runtime_mutex
   locked.  */
static void
objc_send_load (void)
{
  if (!__objc_module_list)
    return;
 
  /* Try to find out if all the classes loaded so far also have their
     superclasses known to the runtime.  We suppose that the objects
     that are allocated in the +load method are in general of a class
     declared in the same module.  */
  if (unresolved_classes)
    {
      Class class = unresolved_classes->head;

      while (objc_getClass ((char *) class->super_class))
	{
	  list_remove_head (&unresolved_classes);
	  if (unresolved_classes)
	    class = unresolved_classes->head;
	  else
	    break;
	}

      /* If we still have classes for whom we don't have yet their
         super classes known to the runtime we don't send the +load
         messages (and call the load callback) yet.  */
      if (unresolved_classes)
	return;
    }

  /* Special check.  If 'Object', which is used by meta-classes, has
     not been loaded yet, delay sending of +load.  */
  if (! objc_getClass ("Object"))
    return;

  /* Iterate over all modules in the __objc_module_list and call on
     them the __objc_create_classes_tree function.  This function
     creates a tree of classes that resembles the class hierarchy.  */
  list_mapcar (__objc_module_list,
	       (void (*) (void *)) __objc_create_classes_tree);

  while (__objc_class_tree_list)
    {
#ifdef DEBUG
      objc_preorder_traverse (__objc_class_tree_list->head,
			      0, __objc_tree_print);
#endif
      objc_preorder_traverse (__objc_class_tree_list->head,
			      0, __objc_send_load);
      objc_postorder_traverse (__objc_class_tree_list->head,
			      0, __objc_destroy_class_tree_node);
      list_remove_head (&__objc_class_tree_list);
    }

  /* For each module, call the _objc_load_callback if any is
     defined.  */
  list_mapcar (__objc_module_list, (void (*) (void *)) __objc_call_load_callback);

  /* Empty the list of modules.  */
  list_free (__objc_module_list);
  __objc_module_list = NULL;
}

static void
__objc_create_classes_tree (struct objc_module *module)
{
  /* The runtime mutex is locked at this point */
  struct objc_symtab *symtab = module->symtab;
  int i;

  /* Iterate through classes defined in this module and insert them in
     the classes tree hierarchy.  */
  for (i = 0; i < symtab->cls_def_cnt; i++)
    {
      Class class = (Class) symtab->defs[i];

      if (!objc_hash_is_key_in_hash (duplicate_classes, class))
	objc_tree_insert_class (class);
    }

  /* Now iterate over "claimed" categories too (ie, categories that
     extend a class that has already been loaded by the runtime), and
     insert them in the classes tree hiearchy too.  Otherwise, if you
     add a category, its +load method would not be called if the class
     is already loaded in the runtime.  It the category is
     "unclaimed", ie, we haven't loaded the main class yet, postpone
     sending +load as we want to execute +load from the class before
     we execute the one from the category.  */
  for (i = 0; i < symtab->cat_def_cnt; ++i)
    {
      struct objc_category *category = symtab->defs[i + symtab->cls_def_cnt];
      Class class = objc_getClass (category->class_name);
      
      /* If the class for the category exists then append its
	 methods.  */
      if (class)
	objc_tree_insert_class (class);
    }
}

static void
__objc_call_load_callback (struct objc_module *module)
{
  if (_objc_load_callback)
    {
      /* The runtime mutex is locked at this point.  */
      struct objc_symtab *symtab = module->symtab;
      int i;
      
      /* Iterate through classes defined in this module and call the callback
	 for each one.  */
      for (i = 0; i < symtab->cls_def_cnt; i++)
	{
	  Class class = (Class) symtab->defs[i];
	
	  if (!objc_hash_is_key_in_hash (duplicate_classes, class))
	    {
	      /* Call the _objc_load_callback for this class.  */
	      DEBUG_PRINTF (" calling the load callback for class '%s'\n", class->name);
	      _objc_load_callback (class, 0);
	    }
	}
      
      /* Call the _objc_load_callback for categories.  Don't register
	 the instance methods as class methods for categories to root
	 classes since they were already added in the class.  */
      for (i = 0; i < symtab->cat_def_cnt; i++)
	{
	  struct objc_category *category = symtab->defs[i + symtab->cls_def_cnt];
	  Class class = objc_getClass (category->class_name);
	  
	  DEBUG_PRINTF (" calling the load callback for category '%s (%s)'\n",
			category->class_name, category->category_name);
	  _objc_load_callback (class, category);
	}
    }
}

/* Sanity check the version of gcc used to compile `module'.  */
static void
init_check_module_version (struct objc_module *module)
{
  if ((module->version != OBJC_VERSION) || (module->size != sizeof (struct objc_module)))
    {
      _objc_abort ("Module %s version %d doesn't match runtime %d\n",
		   module->name, (int)module->version, OBJC_VERSION);
    }
}

/* __objc_init_class must be called with __objc_runtime_mutex already
   locked.  Return YES if the class could be setup; return NO if the
   class could not be setup because a class with the same name already
   exists.  */
BOOL
__objc_init_class (Class class)
{
  /* Store the class in the class table and assign class numbers.  */
  if (__objc_add_class_to_hash (class))
    {
      /* Register all of the selectors in the class and meta class.  */
      __objc_register_selectors_from_class (class);
      __objc_register_selectors_from_class ((Class) class->class_pointer);
      
      /* Install the fake dispatch tables.  */
      __objc_install_premature_dtable (class);
      __objc_install_premature_dtable (class->class_pointer);
      
      /* Register the instance methods as class methods, this is only
	 done for root classes.  */
      __objc_register_instance_methods_to_class (class);
      
      if (class->protocols)
	__objc_init_protocols (class->protocols);

      return YES;
    }
  else
    {
      /* The module contains a duplicate class.  Remember it so that
	 we will ignore it later.  */
      DEBUG_PRINTF (" duplicate class '%s' - will be ignored\n", class->name);
      objc_hash_add (&duplicate_classes, class, class);
      return NO;
    }
}

/* __objc_init_protocol must be called with __objc_runtime_mutex
   already locked, and the "Protocol" class already registered.  */
static void
__objc_init_protocol (struct objc_protocol *protocol)
{
  static Class proto_class = 0;

  if (! proto_class)
    proto_class = objc_getClass ("Protocol");

  if (((size_t)protocol->class_pointer) == PROTOCOL_VERSION)
    {
      /* Assign class pointer.  */
      protocol->class_pointer = proto_class;
      
      /* Register all the selectors in the protocol with the runtime.
	 This both registers the selectors with the right types, and
	 it also fixes up the 'struct objc_method' structures inside
	 the protocol so that each method_name (a char * as compiled
	 by the compiler) is replaced with the appropriate runtime
	 SEL.  */
      if (protocol->class_methods)
	__objc_register_selectors_from_description_list (protocol->class_methods);

      if (protocol->instance_methods)
	__objc_register_selectors_from_description_list (protocol->instance_methods);

      /* Register the protocol in the hashtable or protocols by
	 name.  */
      __objc_protocols_add_protocol (protocol->protocol_name, protocol);
      
      /* Init super protocols.  */
      __objc_init_protocols (protocol->protocol_list);
    }
  else if (protocol->class_pointer != proto_class)
    {
      _objc_abort ("Version %d doesn't match runtime protocol version %d\n",
		   (int) ((char *) protocol->class_pointer
			  - (char *) 0),
		   PROTOCOL_VERSION);
    }
}

static void
__objc_init_protocols (struct objc_protocol_list *protos)
{
  size_t i;
  static Class proto_class = 0;

  if (! protos)
    return;

  objc_mutex_lock (__objc_runtime_mutex);

  if (! proto_class)
    proto_class = objc_getClass ("Protocol");

  if (! proto_class)
    {
      unclaimed_proto_list = list_cons (protos, unclaimed_proto_list);
      objc_mutex_unlock (__objc_runtime_mutex);
      return;
    }

#if 0
  assert (protos->next == 0); /* Only single ones allowed.  */
#endif

  for (i = 0; i < protos->count; i++)
    {
      struct objc_protocol *aProto = protos->list[i];
      __objc_init_protocol (aProto);
    }

  objc_mutex_unlock (__objc_runtime_mutex);
}

static void
__objc_class_add_protocols (Class class, struct objc_protocol_list *protos)
{
  if (! protos)
    return;

  protos->next = class->protocols;
  class->protocols = protos;
}
