/* GNU Objective C Runtime initialization 
   Copyright (C) 1993, 1995, 1996, 1997, 2002 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 2, 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.

You should have received a copy of the GNU General Public License along with
GCC; see the file COPYING.  If not, write to the Free Software
Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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
   to be covered by the GNU General Public License. This exception does not
   however invalidate any other reasons why the executable file might be
   covered by the GNU General Public License.  */

#include "runtime.h"

/* 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 all modules currently loaded into the runtime.  */
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 */

/* Global runtime "write" 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 (Module_t);

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

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

/* This is a hook which is called by __objc_exec_class every time a
   class or a category is loaded into the runtime.  This may e.g. help
   a dynamic loader determine the classes that have been loaded when
   an object file is dynamically linked in.  */
void (*_objc_load_callback) (Class class, Category *category); /* !T:SAFE */

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

extern SEL
__sel_register_typed_name (const char *name, const char *types, 
			   struct objc_selector *orig, BOOL is_const);

/* 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 (Module_t module);

static void __objc_call_callback (Module_t 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);

typedef struct objc_class_tree {
  Class class;
  struct objc_list *subclasses; /* `head' is pointer to an objc_class_tree */
} 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 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
   `bottom_class'. `subclasses' member of each tree node point to the
   next subclass tree node.  */

static objc_class_tree *
create_tree_of_subclasses_inherited_from (Class bottom_class, Class upper)
{
  Class superclass = bottom_class->super_class ?
			objc_lookup_class ((char *) bottom_class->super_class)
		      : Nil;
					
  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));

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

  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 = %x, class = %s\n",
		tree, 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)
    {
      tree = __objc_tree_insert_class (list_node->head, class);
      if (tree)
	{
	  list_node->head = tree;
	  break;
	}
      else
	list_node = list_node->tail;
    }

  /* If the list was finished but the class hasn't been inserted,
     insert it here.  */
  if (! list_node)
    {
      __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 `op' 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.  */

static void
__objc_send_message_in_list (MethodList_t method_list, Class class, SEL op)
{
  int i;

  if (! method_list)
    return;

  /* First execute the `op' message in the following method lists */
  __objc_send_message_in_list (method_list->method_next, class, op);

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

      if (mth->method_name && sel_eq (mth->method_name, op)
	  && ! objc_hash_is_key_in_hash (__objc_load_methods, mth->method_imp))
	{
	  /* Add this method into the +load hash table */
	  objc_hash_add (&__objc_load_methods,
			 mth->method_imp,
			 mth->method_imp);

	  DEBUG_PRINTF ("sending +load in class: %s\n", class->name);

	  /* The method was found and wasn't previously executed.  */
	  (*mth->method_imp) ((id)class, mth->method_name);

	  break;
	}
    }
}

static void
__objc_send_load (objc_class_tree *tree,
		  int level __attribute__ ((__unused__)))
{
  static SEL load_sel = 0;
  Class class = tree->class;
  MethodList_t method_list = class->class_pointer->methods;

  if (! load_sel)
    load_sel = sel_register_name ("load");

  __objc_send_message_in_list (method_list, class, load_sel);
}

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 and NXConstantString
   classes.  */

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_lookup_class (statics->class_name);

	  if (! class)
	    module_initialized = 0;
	  /* Actually, the static's class_pointer will be NULL when we
             haven't been here before.  However, the comparison is to be
             reminded of taking into account class posing and to think about
             possible semantics...  */
	  else if (class != statics->instances[0]->class_pointer)
	    {
	      id *inst;

	      for (inst = &statics->instances[0]; *inst; inst++)
		{
		  (*inst)->class_pointer = class;

		  /* ??? Make sure the object will not be freed.  With
                     refcounting, invoke `-retain'.  Without refcounting, do
                     nothing and hope that `-free' will never be invoked.  */

		  /* ??? Send the object an `-initStatic' or something to
                     that effect now or later on?  What are the semantics of
                     statically allocated instances, besides the trivial
                     NXConstantString, anyway?  */
		}
	    }
	}
      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);
} /* objc_init_statics */

/* 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 (Module_t 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-api.h) generated by gcc */
  Symtab_t 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 */
  SEL selectors = symtab->refs; 

  /* dummy counter */
  int i;

  DEBUG_PRINTF ("received module: %s\n", module->name);

  /* 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 ();
      __objc_class_tree_list = list_cons (NULL, __objc_class_tree_list);
      __objc_load_methods = objc_hash_new (128, 
					   (hash_func_type)objc_hash_ptr,
					   objc_compare_ptrs);
      previous_constructors = 1;
    }

  /* Save the module pointer for later processing. (not currently used) */
  objc_mutex_lock (__objc_runtime_mutex);
  __objc_module_list = list_cons (module, __objc_module_list);

  /* Replace referenced selectors from names to SEL's.  */
  if (selectors)
    {
      for (i = 0; selectors[i].sel_id; ++i)
	{
	  const char *name, *type;
	  name = (char *) selectors[i].sel_id;
	  type = (char *) selectors[i].sel_types;
	  /* Constructors are constant static data so we can safely store
	     pointers to them in the runtime structures. is_const == YES */
	  __sel_register_typed_name (name, type, 
				     (struct objc_selector *) &(selectors[i]),
				     YES);
	}
    }

  /* Parse the classes in the load module and gather selector information.  */
  DEBUG_PRINTF ("gathering selectors from module: %s\n", module->name);
  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 ("phase 1, processing class: %s\n", class->name);

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

      /* Store the class in the class table and assign class numbers.  */
      __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);

      /* 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_lookup_class (superclass))
	unresolved_classes = list_cons (class, unresolved_classes);
   }

  /* Process category information from the module.  */
  for (i = 0; i < symtab->cat_def_cnt; ++i)
    {
      Category_t category = symtab->defs[i + symtab->cls_def_cnt];
      Class class = objc_lookup_class (category->class_name);
      
      /* If the class for the category exists then append its methods.  */
      if (class)
	{

	  DEBUG_PRINTF ("processing categories from (module,object): %s, %s\n",
			module->name,
			class->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
	{
	  /* 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; )
    {
      Category_t category = (*cell)->head;
      Class class = objc_lookup_class (category->class_name);
      
      if (class)
	{
	  DEBUG_PRINTF ("attaching stored categories to object: %s\n",
			class->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_lookup_class ("Protocol"))
    {
      list_mapcar (unclaimed_proto_list,
		   (void (*) (void *))__objc_init_protocols);
      list_free (unclaimed_proto_list);
      unclaimed_proto_list = 0;
    }

  objc_send_load ();

  objc_mutex_unlock (__objc_runtime_mutex);
}

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_lookup_class ((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.  */
      if (unresolved_classes)
	return;
    }

  /* Special check to allow creating and sending messages to constant
     strings in +load methods. If these classes are not yet known,
     even if all the other classes are known, delay sending of +load.  */
  if (! objc_lookup_class ("NXConstantString") ||
      ! objc_lookup_class ("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);
    }

  list_mapcar (__objc_module_list, (void (*) (void *)) __objc_call_callback);
  list_free (__objc_module_list);
  __objc_module_list = NULL;
}

static void
__objc_create_classes_tree (Module_t module)
{
  /* The runtime mutex is locked in this point */

  Symtab_t 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];

      objc_tree_insert_class (class);
    }
}

static void
__objc_call_callback (Module_t module)
{
  /* The runtime mutex is locked in this point.  */

  Symtab_t 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];

      /* Call the _objc_load_callback for this class.  */
      if (_objc_load_callback)
	_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++)
    {
      Category_t category = symtab->defs[i + symtab->cls_def_cnt];
      Class class = objc_lookup_class (category->class_name);
      
      if (_objc_load_callback)
	_objc_load_callback (class, category);
    }
}

/* Sanity check the version of gcc used to compile `module'.  */

static void
init_check_module_version (Module_t module)
{
  if ((module->version != OBJC_VERSION) || (module->size != sizeof (Module)))
    {
      int code;

      if (module->version > OBJC_VERSION)
	code = OBJC_ERR_OBJC_VERSION;
      else if (module->version < OBJC_VERSION)
	code = OBJC_ERR_GCC_VERSION;
      else
	code = OBJC_ERR_MODULE_SIZE;

      objc_error (nil, code, "Module %s version %d doesn't match runtime %d\n",
		  module->name, (int)module->version, OBJC_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_lookup_class ("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];
      if (((size_t)aProto->class_pointer) == PROTOCOL_VERSION)
	{
	  /* assign class pointer */
	  aProto->class_pointer = proto_class;

	  /* init super protocols */
	  __objc_init_protocols (aProto->protocol_list);
	}
      else if (protos->list[i]->class_pointer != proto_class)
	{
	  objc_error (nil, OBJC_ERR_PROTOCOL_VERSION,
		     "Version %d doesn't match runtime protocol version %d\n",
		     (int) ((char *) protos->list[i]->class_pointer
			    - (char *) 0),
		     PROTOCOL_VERSION);
	}
    }

  objc_mutex_unlock (__objc_runtime_mutex);
}

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

  /* Add it...  */
  protos->next = class->protocols;
  class->protocols = protos;
}
