xref: /netbsd-src/external/gpl3/gcc.old/dist/libobjc/init.c (revision b7b7574d3bf8eeb51a1fa3977b59142ec6434a55)
1 /* GNU Objective C Runtime initialization
2    Copyright (C) 1993, 1995, 1996, 1997, 2002, 2009
3    Free Software Foundation, Inc.
4    Contributed by Kresten Krab Thorup
5    +load support contributed by Ovidiu Predescu <ovidiu@net-community.com>
6 
7 This file is part of GCC.
8 
9 GCC is free software; you can redistribute it and/or modify it under the
10 terms of the GNU General Public License as published by the Free Software
11 Foundation; either version 3, or (at your option) any later version.
12 
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15 FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
16 details.
17 
18 Under Section 7 of GPL version 3, you are granted additional
19 permissions described in the GCC Runtime Library Exception, version
20 3.1, as published by the Free Software Foundation.
21 
22 You should have received a copy of the GNU General Public License and
23 a copy of the GCC Runtime Library Exception along with this program;
24 see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
25 <http://www.gnu.org/licenses/>.  */
26 
27 #include "objc/runtime.h"
28 
29 /* The version number of this runtime.  This must match the number
30    defined in gcc (objc-act.c).  */
31 #define OBJC_VERSION 8
32 #define PROTOCOL_VERSION 2
33 
34 /* This list contains all modules currently loaded into the runtime.  */
35 static struct objc_list *__objc_module_list = 0; 	/* !T:MUTEX */
36 
37 /* This list contains all proto_list's not yet assigned class links.  */
38 static struct objc_list *unclaimed_proto_list = 0; 	/* !T:MUTEX */
39 
40 /* List of unresolved static instances.  */
41 static struct objc_list *uninitialized_statics = 0; 	/* !T:MUTEX */
42 
43 /* Global runtime "write" mutex.  */
44 objc_mutex_t __objc_runtime_mutex = 0;
45 
46 /* Number of threads that are alive.  */
47 int __objc_runtime_threads_alive = 1;			/* !T:MUTEX */
48 
49 /* Check compiler vs runtime version.  */
50 static void init_check_module_version (Module_t);
51 
52 /* Assign isa links to protos.  */
53 static void __objc_init_protocols (struct objc_protocol_list *protos);
54 
55 /* Add protocol to class.  */
56 static void __objc_class_add_protocols (Class, struct objc_protocol_list *);
57 
58 /* This is a hook which is called by __objc_exec_class every time a
59    class or a category is loaded into the runtime.  This may e.g. help
60    a dynamic loader determine the classes that have been loaded when
61    an object file is dynamically linked in.  */
62 void (*_objc_load_callback) (Class class, Category *category); /* !T:SAFE */
63 
64 /* Is all categories/classes resolved?  */
65 BOOL __objc_dangling_categories = NO;           /* !T:UNUSED */
66 
67 extern SEL
68 __sel_register_typed_name (const char *name, const char *types,
69 			   struct objc_selector *orig, BOOL is_const);
70 
71 /* Sends +load to all classes and categories in certain situations.  */
72 static void objc_send_load (void);
73 
74 /* Inserts all the classes defined in module in a tree of classes that
75    resembles the class hierarchy. This tree is traversed in preorder
76    and the classes in its nodes receive the +load message if these
77    methods were not executed before. The algorithm ensures that when
78    the +load method of a class is executed all the superclasses have
79    been already received the +load message.  */
80 static void __objc_create_classes_tree (Module_t module);
81 
82 static void __objc_call_callback (Module_t module);
83 
84 /* A special version that works only before the classes are completely
85    installed in the runtime.  */
86 static BOOL class_is_subclass_of_class (Class class, Class superclass);
87 
88 typedef struct objc_class_tree {
89   Class class;
90   struct objc_list *subclasses; /* `head' is pointer to an objc_class_tree */
91 } objc_class_tree;
92 
93 /* This is a linked list of objc_class_tree trees. The head of these
94    trees are root classes (their super class is Nil). These different
95    trees represent different class hierarchies.  */
96 static struct objc_list *__objc_class_tree_list = NULL;
97 
98 /* Keeps the +load methods who have been already executed. This hash
99    should not be destroyed during the execution of the program.  */
100 static cache_ptr __objc_load_methods = NULL;
101 
102 /* This function is used when building the class tree used to send
103    ordinately the +load message to all classes needing it.  The tree
104    is really needed so that superclasses will get the message before
105    subclasses.
106 
107    This tree will contain classes which are being loaded (or have just
108    being loaded), and whose super_class pointers have not yet been
109    resolved.  This implies that their super_class pointers point to a
110    string with the name of the superclass; when the first message is
111    sent to the class (/an object of that class) the class links will
112    be resolved, which will replace the super_class pointers with
113    pointers to the actual superclasses.
114 
115    Unfortunately, the tree might also contain classes which had been
116    loaded previously, and whose class links have already been
117    resolved.
118 
119    This function returns the superclass of a class in both cases, and
120    can be used to build the determine the class relationships while
121    building the tree.
122 */
123 static Class  class_superclass_of_class (Class class)
124 {
125   char *super_class_name;
126 
127   /* If the class links have been resolved, use the resolved
128    * links.  */
129   if (CLS_ISRESOLV (class))
130     return class->super_class;
131 
132   /* Else, 'class' has not yet been resolved.  This means that its
133    * super_class pointer is really the name of the super class (rather
134    * than a pointer to the actual superclass).  */
135   super_class_name = (char *)class->super_class;
136 
137   /* Return Nil for a root class.  */
138   if (super_class_name == NULL)
139     return Nil;
140 
141   /* Lookup the superclass of non-root classes.  */
142   return objc_lookup_class (super_class_name);
143 }
144 
145 
146 /* Creates a tree of classes whose topmost class is directly inherited
147    from `upper' and the bottom class in this tree is
148    `bottom_class'. The classes in this tree are super classes of
149    `bottom_class'. `subclasses' member of each tree node point to the
150    next subclass tree node.  */
151 
152 static objc_class_tree *
153 create_tree_of_subclasses_inherited_from (Class bottom_class, Class upper)
154 {
155   Class superclass = bottom_class->super_class ?
156 			objc_lookup_class ((char *) bottom_class->super_class)
157 		      : Nil;
158 
159   objc_class_tree *tree, *prev;
160 
161   DEBUG_PRINTF ("create_tree_of_subclasses_inherited_from:");
162   DEBUG_PRINTF ("bottom_class = %s, upper = %s\n",
163 		(bottom_class ? bottom_class->name : NULL),
164 		(upper ? upper->name : NULL));
165 
166   tree = prev = objc_calloc (1, sizeof (objc_class_tree));
167   prev->class = bottom_class;
168 
169   while (superclass != upper)
170     {
171       tree = objc_calloc (1, sizeof (objc_class_tree));
172       tree->class = superclass;
173       tree->subclasses = list_cons (prev, tree->subclasses);
174       superclass = class_superclass_of_class (superclass);
175       prev = tree;
176     }
177 
178   return tree;
179 }
180 
181 /* Insert the `class' into the proper place in the `tree' class
182    hierarchy. This function returns a new tree if the class has been
183    successfully inserted into the tree or NULL if the class is not
184    part of the classes hierarchy described by `tree'. This function is
185    private to objc_tree_insert_class (), you should not call it
186    directly.  */
187 
188 static objc_class_tree *
189 __objc_tree_insert_class (objc_class_tree *tree, Class class)
190 {
191   DEBUG_PRINTF ("__objc_tree_insert_class: tree = %x, class = %s\n",
192 		tree, class->name);
193 
194   if (tree == NULL)
195     return create_tree_of_subclasses_inherited_from (class, NULL);
196   else if (class == tree->class)
197     {
198       /* `class' has been already inserted */
199       DEBUG_PRINTF ("1. class %s was previously inserted\n", class->name);
200       return tree;
201     }
202   else if (class_superclass_of_class (class) == tree->class)
203     {
204       /* If class is a direct subclass of tree->class then add class to the
205 	 list of subclasses. First check to see if it wasn't already
206 	 inserted.  */
207       struct objc_list *list = tree->subclasses;
208       objc_class_tree *node;
209 
210       while (list)
211 	{
212 	  /* Class has been already inserted; do nothing just return
213 	     the tree.  */
214 	  if (((objc_class_tree *) list->head)->class == class)
215 	    {
216 	      DEBUG_PRINTF ("2. class %s was previously inserted\n",
217 			    class->name);
218 	      return tree;
219 	    }
220 	  list = list->tail;
221 	}
222 
223       /* Create a new node class and insert it into the list of subclasses */
224       node = objc_calloc (1, sizeof (objc_class_tree));
225       node->class = class;
226       tree->subclasses = list_cons (node, tree->subclasses);
227       DEBUG_PRINTF ("3. class %s inserted\n", class->name);
228       return tree;
229     }
230   else
231     {
232       /* The class is not a direct subclass of tree->class. Search for
233          class's superclasses in the list of subclasses.  */
234       struct objc_list *subclasses = tree->subclasses;
235 
236       /* Precondition: the class must be a subclass of tree->class;
237          otherwise return NULL to indicate our caller that it must
238          take the next tree.  */
239       if (! class_is_subclass_of_class (class, tree->class))
240 	return NULL;
241 
242       for (; subclasses != NULL; subclasses = subclasses->tail)
243 	{
244 	  Class aClass = ((objc_class_tree *) (subclasses->head))->class;
245 
246 	  if (class_is_subclass_of_class (class, aClass))
247 	    {
248 	      /* If we found one of class's superclasses we insert the
249 	         class into its subtree and return the original tree
250 	         since nothing has been changed.  */
251 	      subclasses->head
252 		  = __objc_tree_insert_class (subclasses->head, class);
253  	      DEBUG_PRINTF ("4. class %s inserted\n", class->name);
254 	      return tree;
255 	    }
256 	}
257 
258       /* We haven't found a subclass of `class' in the `subclasses'
259          list.  Create a new tree of classes whose topmost class is a
260          direct subclass of tree->class.  */
261       {
262 	objc_class_tree *new_tree
263 	  = create_tree_of_subclasses_inherited_from (class, tree->class);
264 	tree->subclasses = list_cons (new_tree, tree->subclasses);
265  	DEBUG_PRINTF ("5. class %s inserted\n", class->name);
266 	return tree;
267       }
268     }
269 }
270 
271 /* This function inserts `class' in the right tree hierarchy classes.  */
272 
273 static void
274 objc_tree_insert_class (Class class)
275 {
276   struct objc_list *list_node;
277   objc_class_tree *tree;
278 
279   list_node = __objc_class_tree_list;
280   while (list_node)
281     {
282       tree = __objc_tree_insert_class (list_node->head, class);
283       if (tree)
284 	{
285 	  list_node->head = tree;
286 	  break;
287 	}
288       else
289 	list_node = list_node->tail;
290     }
291 
292   /* If the list was finished but the class hasn't been inserted,
293      insert it here.  */
294   if (! list_node)
295     {
296       __objc_class_tree_list = list_cons (NULL, __objc_class_tree_list);
297       __objc_class_tree_list->head = __objc_tree_insert_class (NULL, class);
298     }
299 }
300 
301 /* Traverse tree in preorder. Used to send +load.  */
302 
303 static void
304 objc_preorder_traverse (objc_class_tree *tree,
305 			int level,
306 			void (*function) (objc_class_tree *, int))
307 {
308   struct objc_list *node;
309 
310   (*function) (tree, level);
311   for (node = tree->subclasses; node; node = node->tail)
312     objc_preorder_traverse (node->head, level + 1, function);
313 }
314 
315 /* Traverse tree in postorder. Used to destroy a tree.  */
316 
317 static void
318 objc_postorder_traverse (objc_class_tree *tree,
319 			 int level,
320 			 void (*function) (objc_class_tree *, int))
321 {
322   struct objc_list *node;
323 
324   for (node = tree->subclasses; node; node = node->tail)
325     objc_postorder_traverse (node->head, level + 1, function);
326   (*function) (tree, level);
327 }
328 
329 /* Used to print a tree class hierarchy.  */
330 
331 #ifdef DEBUG
332 static void
333 __objc_tree_print (objc_class_tree *tree, int level)
334 {
335   int i;
336 
337   for (i = 0; i < level; i++)
338     printf ("  ");
339   printf ("%s\n", tree->class->name);
340 }
341 #endif
342 
343 /* Walks on a linked list of methods in the reverse order and executes
344    all the methods corresponding to `op' selector. Walking in the
345    reverse order assures the +load of class is executed first and then
346    +load of categories because of the way in which categories are
347    added to the class methods.  */
348 
349 static void
350 __objc_send_message_in_list (MethodList_t method_list, Class class, SEL op)
351 {
352   int i;
353 
354   if (! method_list)
355     return;
356 
357   /* First execute the `op' message in the following method lists */
358   __objc_send_message_in_list (method_list->method_next, class, op);
359 
360   /* Search the method list.  */
361   for (i = 0; i < method_list->method_count; i++)
362     {
363       Method_t mth = &method_list->method_list[i];
364 
365       if (mth->method_name && sel_eq (mth->method_name, op)
366 	  && ! objc_hash_is_key_in_hash (__objc_load_methods, mth->method_imp))
367 	{
368 	  /* Add this method into the +load hash table */
369 	  objc_hash_add (&__objc_load_methods,
370 			 mth->method_imp,
371 			 mth->method_imp);
372 
373 	  DEBUG_PRINTF ("sending +load in class: %s\n", class->name);
374 
375 	  /* The method was found and wasn't previously executed.  */
376 	  (*mth->method_imp) ((id)class, mth->method_name);
377 
378 	  break;
379 	}
380     }
381 }
382 
383 static void
384 __objc_send_load (objc_class_tree *tree,
385 		  int level __attribute__ ((__unused__)))
386 {
387   static SEL load_sel = 0;
388   Class class = tree->class;
389   MethodList_t method_list = class->class_pointer->methods;
390 
391   if (! load_sel)
392     load_sel = sel_register_name ("load");
393 
394   __objc_send_message_in_list (method_list, class, load_sel);
395 }
396 
397 static void
398 __objc_destroy_class_tree_node (objc_class_tree *tree,
399 				int level __attribute__ ((__unused__)))
400 {
401   objc_free (tree);
402 }
403 
404 /* This is used to check if the relationship between two classes
405    before the runtime completely installs the classes.  */
406 
407 static BOOL
408 class_is_subclass_of_class (Class class, Class superclass)
409 {
410   for (; class != Nil;)
411     {
412       if (class == superclass)
413 	return YES;
414       class = class_superclass_of_class (class);
415     }
416 
417   return NO;
418 }
419 
420 /* This list contains all the classes in the runtime system for whom
421    their superclasses are not yet known to the runtime.  */
422 static struct objc_list *unresolved_classes = 0;
423 
424 /* Extern function used to reference the Object and NXConstantString
425    classes.  */
426 
427 extern void __objc_force_linking (void);
428 
429 void
430 __objc_force_linking (void)
431 {
432   extern void __objc_linking (void);
433   __objc_linking ();
434 }
435 
436 /* Run through the statics list, removing modules as soon as all its
437    statics have been initialized.  */
438 
439 static void
440 objc_init_statics (void)
441 {
442   struct objc_list **cell = &uninitialized_statics;
443   struct objc_static_instances **statics_in_module;
444 
445   objc_mutex_lock (__objc_runtime_mutex);
446 
447   while (*cell)
448     {
449       int module_initialized = 1;
450 
451       for (statics_in_module = (*cell)->head;
452 	   *statics_in_module; statics_in_module++)
453 	{
454 	  struct objc_static_instances *statics = *statics_in_module;
455 	  Class class = objc_lookup_class (statics->class_name);
456 
457 	  if (! class)
458 	    module_initialized = 0;
459 	  /* Actually, the static's class_pointer will be NULL when we
460              haven't been here before.  However, the comparison is to be
461              reminded of taking into account class posing and to think about
462              possible semantics...  */
463 	  else if (class != statics->instances[0]->class_pointer)
464 	    {
465 	      id *inst;
466 
467 	      for (inst = &statics->instances[0]; *inst; inst++)
468 		{
469 		  (*inst)->class_pointer = class;
470 
471 		  /* ??? Make sure the object will not be freed.  With
472                      refcounting, invoke `-retain'.  Without refcounting, do
473                      nothing and hope that `-free' will never be invoked.  */
474 
475 		  /* ??? Send the object an `-initStatic' or something to
476                      that effect now or later on?  What are the semantics of
477                      statically allocated instances, besides the trivial
478                      NXConstantString, anyway?  */
479 		}
480 	    }
481 	}
482       if (module_initialized)
483 	{
484 	  /* Remove this module from the uninitialized list.  */
485 	  struct objc_list *this = *cell;
486 	  *cell = this->tail;
487 	  objc_free (this);
488 	}
489       else
490 	cell = &(*cell)->tail;
491     }
492 
493   objc_mutex_unlock (__objc_runtime_mutex);
494 } /* objc_init_statics */
495 
496 /* This function is called by constructor functions generated for each
497    module compiled.  (_GLOBAL_$I$...) The purpose of this function is
498    to gather the module pointers so that they may be processed by the
499    initialization routines as soon as possible.  */
500 
501 void
502 __objc_exec_class (Module_t module)
503 {
504   /* Have we processed any constructors previously?  This flag is used to
505      indicate that some global data structures need to be built.  */
506   static BOOL previous_constructors = 0;
507 
508   static struct objc_list *unclaimed_categories = 0;
509 
510   /* The symbol table (defined in objc-api.h) generated by gcc */
511   Symtab_t symtab = module->symtab;
512 
513   /* The statics in this module */
514   struct objc_static_instances **statics
515     = symtab->defs[symtab->cls_def_cnt + symtab->cat_def_cnt];
516 
517   /* Entry used to traverse hash lists */
518   struct objc_list **cell;
519 
520   /* The table of selector references for this module */
521   SEL selectors = symtab->refs;
522 
523   /* dummy counter */
524   int i;
525 
526   DEBUG_PRINTF ("received module: %s\n", module->name);
527 
528   /* check gcc version */
529   init_check_module_version (module);
530 
531   /* On the first call of this routine, initialize some data structures.  */
532   if (! previous_constructors)
533     {
534 	/* Initialize thread-safe system */
535       __objc_init_thread_system ();
536       __objc_runtime_threads_alive = 1;
537       __objc_runtime_mutex = objc_mutex_allocate ();
538 
539       __objc_init_selector_tables ();
540       __objc_init_class_tables ();
541       __objc_init_dispatch_tables ();
542       __objc_class_tree_list = list_cons (NULL, __objc_class_tree_list);
543       __objc_load_methods = objc_hash_new (128,
544 					   (hash_func_type)objc_hash_ptr,
545 					   objc_compare_ptrs);
546       previous_constructors = 1;
547     }
548 
549   /* Save the module pointer for later processing. (not currently used) */
550   objc_mutex_lock (__objc_runtime_mutex);
551   __objc_module_list = list_cons (module, __objc_module_list);
552 
553   /* Replace referenced selectors from names to SEL's.  */
554   if (selectors)
555     {
556       for (i = 0; selectors[i].sel_id; ++i)
557 	{
558 	  const char *name, *type;
559 	  name = (char *) selectors[i].sel_id;
560 	  type = (char *) selectors[i].sel_types;
561 	  /* Constructors are constant static data so we can safely store
562 	     pointers to them in the runtime structures. is_const == YES */
563 	  __sel_register_typed_name (name, type,
564 				     (struct objc_selector *) &(selectors[i]),
565 				     YES);
566 	}
567     }
568 
569   /* Parse the classes in the load module and gather selector information.  */
570   DEBUG_PRINTF ("gathering selectors from module: %s\n", module->name);
571   for (i = 0; i < symtab->cls_def_cnt; ++i)
572     {
573       Class class = (Class) symtab->defs[i];
574       const char *superclass = (char *) class->super_class;
575 
576       /* Make sure we have what we think.  */
577       assert (CLS_ISCLASS (class));
578       assert (CLS_ISMETA (class->class_pointer));
579       DEBUG_PRINTF ("phase 1, processing class: %s\n", class->name);
580 
581       /* Initialize the subclass list to be NULL.
582 	 In some cases it isn't and this crashes the program.  */
583       class->subclass_list = NULL;
584 
585       /* Store the class in the class table and assign class numbers.  */
586       __objc_add_class_to_hash (class);
587 
588       /* Register all of the selectors in the class and meta class.  */
589       __objc_register_selectors_from_class (class);
590       __objc_register_selectors_from_class ((Class) class->class_pointer);
591 
592       /* Install the fake dispatch tables */
593       __objc_install_premature_dtable (class);
594       __objc_install_premature_dtable (class->class_pointer);
595 
596       /* Register the instance methods as class methods, this is
597 	 only done for root classes.  */
598       __objc_register_instance_methods_to_class (class);
599 
600       if (class->protocols)
601 	__objc_init_protocols (class->protocols);
602 
603       /* Check to see if the superclass is known in this point. If it's not
604 	 add the class to the unresolved_classes list.  */
605       if (superclass && ! objc_lookup_class (superclass))
606 	unresolved_classes = list_cons (class, unresolved_classes);
607    }
608 
609   /* Process category information from the module.  */
610   for (i = 0; i < symtab->cat_def_cnt; ++i)
611     {
612       Category_t category = symtab->defs[i + symtab->cls_def_cnt];
613       Class class = objc_lookup_class (category->class_name);
614 
615       /* If the class for the category exists then append its methods.  */
616       if (class)
617 	{
618 
619 	  DEBUG_PRINTF ("processing categories from (module,object): %s, %s\n",
620 			module->name,
621 			class->name);
622 
623 	  /* Do instance methods.  */
624 	  if (category->instance_methods)
625 	    class_add_method_list (class, category->instance_methods);
626 
627 	  /* Do class methods.  */
628 	  if (category->class_methods)
629 	    class_add_method_list ((Class) class->class_pointer,
630 				   category->class_methods);
631 
632 	  if (category->protocols)
633 	    {
634 	      __objc_init_protocols (category->protocols);
635 	      __objc_class_add_protocols (class, category->protocols);
636 	    }
637 
638           /* Register the instance methods as class methods, this is
639              only done for root classes.  */
640           __objc_register_instance_methods_to_class (class);
641 	}
642       else
643 	{
644 	  /* The object to which the category methods belong can't be found.
645 	     Save the information.  */
646 	  unclaimed_categories = list_cons (category, unclaimed_categories);
647 	}
648     }
649 
650   if (statics)
651     uninitialized_statics = list_cons (statics, uninitialized_statics);
652   if (uninitialized_statics)
653     objc_init_statics ();
654 
655   /* Scan the unclaimed category hash.  Attempt to attach any unclaimed
656      categories to objects.  */
657   for (cell = &unclaimed_categories; *cell; )
658     {
659       Category_t category = (*cell)->head;
660       Class class = objc_lookup_class (category->class_name);
661 
662       if (class)
663 	{
664 	  DEBUG_PRINTF ("attaching stored categories to object: %s\n",
665 			class->name);
666 
667 	  list_remove_head (cell);
668 
669 	  if (category->instance_methods)
670 	    class_add_method_list (class, category->instance_methods);
671 
672 	  if (category->class_methods)
673 	    class_add_method_list ((Class) class->class_pointer,
674 				   category->class_methods);
675 
676 	  if (category->protocols)
677 	    {
678 	      __objc_init_protocols (category->protocols);
679 	      __objc_class_add_protocols (class, category->protocols);
680 	    }
681 
682           /* Register the instance methods as class methods, this is
683              only done for root classes.  */
684           __objc_register_instance_methods_to_class (class);
685 	}
686       else
687 	cell = &(*cell)->tail;
688     }
689 
690   if (unclaimed_proto_list && objc_lookup_class ("Protocol"))
691     {
692       list_mapcar (unclaimed_proto_list,
693 		   (void (*) (void *))__objc_init_protocols);
694       list_free (unclaimed_proto_list);
695       unclaimed_proto_list = 0;
696     }
697 
698   objc_send_load ();
699 
700   objc_mutex_unlock (__objc_runtime_mutex);
701 }
702 
703 static void
704 objc_send_load (void)
705 {
706   if (! __objc_module_list)
707     return;
708 
709   /* Try to find out if all the classes loaded so far also have their
710      superclasses known to the runtime. We suppose that the objects
711      that are allocated in the +load method are in general of a class
712      declared in the same module.  */
713   if (unresolved_classes)
714     {
715       Class class = unresolved_classes->head;
716 
717       while (objc_lookup_class ((char *) class->super_class))
718 	{
719 	  list_remove_head (&unresolved_classes);
720 	  if (unresolved_classes)
721 	    class = unresolved_classes->head;
722 	  else
723 	    break;
724 	}
725 
726       /* If we still have classes for whom we don't have yet their
727          super classes known to the runtime we don't send the +load
728          messages.  */
729       if (unresolved_classes)
730 	return;
731     }
732 
733   /* Special check to allow creating and sending messages to constant
734      strings in +load methods. If these classes are not yet known,
735      even if all the other classes are known, delay sending of +load.  */
736   if (! objc_lookup_class ("NXConstantString") ||
737       ! objc_lookup_class ("Object"))
738     return;
739 
740   /* Iterate over all modules in the __objc_module_list and call on
741      them the __objc_create_classes_tree function. This function
742      creates a tree of classes that resembles the class hierarchy.  */
743   list_mapcar (__objc_module_list,
744 	       (void (*) (void *)) __objc_create_classes_tree);
745 
746   while (__objc_class_tree_list)
747     {
748 #ifdef DEBUG
749       objc_preorder_traverse (__objc_class_tree_list->head,
750 			      0, __objc_tree_print);
751 #endif
752       objc_preorder_traverse (__objc_class_tree_list->head,
753 			      0, __objc_send_load);
754       objc_postorder_traverse (__objc_class_tree_list->head,
755 			      0, __objc_destroy_class_tree_node);
756       list_remove_head (&__objc_class_tree_list);
757     }
758 
759   list_mapcar (__objc_module_list, (void (*) (void *)) __objc_call_callback);
760   list_free (__objc_module_list);
761   __objc_module_list = NULL;
762 }
763 
764 static void
765 __objc_create_classes_tree (Module_t module)
766 {
767   /* The runtime mutex is locked in this point */
768 
769   Symtab_t symtab = module->symtab;
770   int i;
771 
772   /* Iterate thru classes defined in this module and insert them in
773      the classes tree hierarchy.  */
774   for (i = 0; i < symtab->cls_def_cnt; i++)
775     {
776       Class class = (Class) symtab->defs[i];
777 
778       objc_tree_insert_class (class);
779     }
780 }
781 
782 static void
783 __objc_call_callback (Module_t module)
784 {
785   /* The runtime mutex is locked in this point.  */
786 
787   Symtab_t symtab = module->symtab;
788   int i;
789 
790   /* Iterate thru classes defined in this module and call the callback
791      for each one.  */
792   for (i = 0; i < symtab->cls_def_cnt; i++)
793     {
794       Class class = (Class) symtab->defs[i];
795 
796       /* Call the _objc_load_callback for this class.  */
797       if (_objc_load_callback)
798 	_objc_load_callback (class, 0);
799     }
800 
801   /* Call the _objc_load_callback for categories. Don't register the
802      instance methods as class methods for categories to root classes
803      since they were already added in the class.  */
804   for (i = 0; i < symtab->cat_def_cnt; i++)
805     {
806       Category_t category = symtab->defs[i + symtab->cls_def_cnt];
807       Class class = objc_lookup_class (category->class_name);
808 
809       if (_objc_load_callback)
810 	_objc_load_callback (class, category);
811     }
812 }
813 
814 /* Sanity check the version of gcc used to compile `module'.  */
815 
816 static void
817 init_check_module_version (Module_t module)
818 {
819   if ((module->version != OBJC_VERSION) || (module->size != sizeof (Module)))
820     {
821       int code;
822 
823       if (module->version > OBJC_VERSION)
824 	code = OBJC_ERR_OBJC_VERSION;
825       else if (module->version < OBJC_VERSION)
826 	code = OBJC_ERR_GCC_VERSION;
827       else
828 	code = OBJC_ERR_MODULE_SIZE;
829 
830       objc_error (nil, code, "Module %s version %d doesn't match runtime %d\n",
831 		  module->name, (int)module->version, OBJC_VERSION);
832     }
833 }
834 
835 static void
836 __objc_init_protocols (struct objc_protocol_list *protos)
837 {
838   size_t i;
839   static Class proto_class = 0;
840 
841   if (! protos)
842     return;
843 
844   objc_mutex_lock (__objc_runtime_mutex);
845 
846   if (! proto_class)
847     proto_class = objc_lookup_class ("Protocol");
848 
849   if (! proto_class)
850     {
851       unclaimed_proto_list = list_cons (protos, unclaimed_proto_list);
852       objc_mutex_unlock (__objc_runtime_mutex);
853       return;
854     }
855 
856 #if 0
857   assert (protos->next == 0);	/* only single ones allowed */
858 #endif
859 
860   for (i = 0; i < protos->count; i++)
861     {
862       struct objc_protocol *aProto = protos->list[i];
863       if (((size_t)aProto->class_pointer) == PROTOCOL_VERSION)
864 	{
865 	  /* assign class pointer */
866 	  aProto->class_pointer = proto_class;
867 
868 	  /* init super protocols */
869 	  __objc_init_protocols (aProto->protocol_list);
870 	}
871       else if (protos->list[i]->class_pointer != proto_class)
872 	{
873 	  objc_error (nil, OBJC_ERR_PROTOCOL_VERSION,
874 		     "Version %d doesn't match runtime protocol version %d\n",
875 		     (int) ((char *) protos->list[i]->class_pointer
876 			    - (char *) 0),
877 		     PROTOCOL_VERSION);
878 	}
879     }
880 
881   objc_mutex_unlock (__objc_runtime_mutex);
882 }
883 
884 static void
885 __objc_class_add_protocols (Class class, struct objc_protocol_list *protos)
886 {
887   /* Well...  */
888   if (! protos)
889     return;
890 
891   /* Add it...  */
892   protos->next = class->protocols;
893   class->protocols = protos;
894 }
895