OSDN Git Service

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