OSDN Git Service

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