/* GNU Objective C Runtime initialization 
   Copyright (C) 1993, 1995, 1996, 1997, 2002, 2009, 2010
   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 accomodate 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 thru 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 thru 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;
}
