Merge from vendor branch NTPD:
[dragonfly.git] / contrib / gcc-3.4 / libobjc / init.c
1 /* GNU Objective C Runtime initialization 
2    Copyright (C) 1993, 1995, 1996, 1997, 2002 Free Software Foundation, Inc.
3    Contributed by Kresten Krab Thorup
4    +load support contributed by Ovidiu Predescu <ovidiu@net-community.com>
5
6 This file is part of GCC.
7
8 GCC is free software; you can redistribute it and/or modify it under the
9 terms of the GNU General Public License as published by the Free Software
10 Foundation; either version 2, or (at your option) any later version.
11
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
15 details.
16
17 You should have received a copy of the GNU General Public License along with
18 GCC; see the file COPYING.  If not, write to the Free Software
19 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
20
21 /* As a special exception, if you link this library with files compiled with
22    GCC to produce an executable, this does not cause the resulting executable
23    to be covered by the GNU General Public License. This exception does not
24    however invalidate any other reasons why the executable file might be
25    covered by the GNU General Public License.  */
26
27 #include "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           && ! hash_is_key_in_hash (__objc_load_methods, mth->method_imp))
367         {
368           /* Add this method into the +load hash table */
369           hash_add (&__objc_load_methods, mth->method_imp, mth->method_imp);
370
371           DEBUG_PRINTF ("sending +load in class: %s\n", class->name);
372
373           /* The method was found and wasn't previously executed.  */
374           (*mth->method_imp) ((id)class, mth->method_name);
375
376           break;
377         }
378     }
379 }
380
381 static void
382 __objc_send_load (objc_class_tree *tree,
383                   int level __attribute__ ((__unused__)))
384 {
385   static SEL load_sel = 0;
386   Class class = tree->class;
387   MethodList_t method_list = class->class_pointer->methods;
388
389   if (! load_sel)
390     load_sel = sel_register_name ("load");
391
392   __objc_send_message_in_list (method_list, class, load_sel);
393 }
394
395 static void
396 __objc_destroy_class_tree_node (objc_class_tree *tree,
397                                 int level __attribute__ ((__unused__)))
398 {
399   objc_free (tree);
400 }
401
402 /* This is used to check if the relationship between two classes
403    before the runtime completely installs the classes.  */
404
405 static BOOL
406 class_is_subclass_of_class (Class class, Class superclass)
407 {
408   for (; class != Nil;)
409     {
410       if (class == superclass)
411         return YES;
412       class = class_superclass_of_class (class);
413     }
414
415   return NO;
416 }
417
418 /* This list contains all the classes in the runtime system for whom
419    their superclasses are not yet known to the runtime.  */
420 static struct objc_list *unresolved_classes = 0;
421
422 /* Extern function used to reference the Object and NXConstantString
423    classes.  */
424
425 extern void __objc_force_linking (void);
426
427 void
428 __objc_force_linking (void)
429 {
430   extern void __objc_linking (void);
431   __objc_linking ();
432 }
433
434 /* Run through the statics list, removing modules as soon as all its
435    statics have been initialized.  */
436
437 static void
438 objc_init_statics (void)
439 {
440   struct objc_list **cell = &uninitialized_statics;
441   struct objc_static_instances **statics_in_module;
442
443   objc_mutex_lock (__objc_runtime_mutex);
444
445   while (*cell)
446     {
447       int module_initialized = 1;
448
449       for (statics_in_module = (*cell)->head;
450            *statics_in_module; statics_in_module++)
451         {
452           struct objc_static_instances *statics = *statics_in_module;
453           Class class = objc_lookup_class (statics->class_name);
454
455           if (! class)
456             module_initialized = 0;
457           /* Actually, the static's class_pointer will be NULL when we
458              haven't been here before.  However, the comparison is to be
459              reminded of taking into account class posing and to think about
460              possible semantics...  */
461           else if (class != statics->instances[0]->class_pointer)
462             {
463               id *inst;
464
465               for (inst = &statics->instances[0]; *inst; inst++)
466                 {
467                   (*inst)->class_pointer = class;
468
469                   /* ??? Make sure the object will not be freed.  With
470                      refcounting, invoke `-retain'.  Without refcounting, do
471                      nothing and hope that `-free' will never be invoked.  */
472
473                   /* ??? Send the object an `-initStatic' or something to
474                      that effect now or later on?  What are the semantics of
475                      statically allocated instances, besides the trivial
476                      NXConstantString, anyway?  */
477                 }
478             }
479         }
480       if (module_initialized)
481         {
482           /* Remove this module from the uninitialized list.  */
483           struct objc_list *this = *cell;
484           *cell = this->tail;
485           objc_free (this);
486         }
487       else
488         cell = &(*cell)->tail;
489     }
490
491   objc_mutex_unlock (__objc_runtime_mutex);
492 } /* objc_init_statics */
493
494 /* This function is called by constructor functions generated for each
495    module compiled.  (_GLOBAL_$I$...) The purpose of this function is
496    to gather the module pointers so that they may be processed by the
497    initialization routines as soon as possible.  */
498
499 void
500 __objc_exec_class (Module_t module)
501 {
502   /* Have we processed any constructors previously?  This flag is used to
503      indicate that some global data structures need to be built.  */
504   static BOOL previous_constructors = 0;
505
506   static struct objc_list *unclaimed_categories = 0;
507
508   /* The symbol table (defined in objc-api.h) generated by gcc */
509   Symtab_t symtab = module->symtab;
510
511   /* The statics in this module */
512   struct objc_static_instances **statics
513     = symtab->defs[symtab->cls_def_cnt + symtab->cat_def_cnt];
514
515   /* Entry used to traverse hash lists */
516   struct objc_list **cell;
517
518   /* The table of selector references for this module */
519   SEL selectors = symtab->refs; 
520
521   /* dummy counter */
522   int i;
523
524   DEBUG_PRINTF ("received module: %s\n", module->name);
525
526   /* check gcc version */
527   init_check_module_version (module);
528
529   /* On the first call of this routine, initialize some data structures.  */
530   if (! previous_constructors)
531     {
532         /* Initialize thread-safe system */
533       __objc_init_thread_system ();
534       __objc_runtime_threads_alive = 1;
535       __objc_runtime_mutex = objc_mutex_allocate ();
536
537       __objc_init_selector_tables ();
538       __objc_init_class_tables ();
539       __objc_init_dispatch_tables ();
540       __objc_class_tree_list = list_cons (NULL, __objc_class_tree_list);
541       __objc_load_methods
542           = hash_new (128, (hash_func_type)hash_ptr, compare_ptrs);
543       previous_constructors = 1;
544     }
545
546   /* Save the module pointer for later processing. (not currently used) */
547   objc_mutex_lock (__objc_runtime_mutex);
548   __objc_module_list = list_cons (module, __objc_module_list);
549
550   /* Replace referenced selectors from names to SEL's.  */
551   if (selectors)
552     {
553       for (i = 0; selectors[i].sel_id; ++i)
554         {
555           const char *name, *type;
556           name = (char *) selectors[i].sel_id;
557           type = (char *) selectors[i].sel_types;
558           /* Constructors are constant static data so we can safely store
559              pointers to them in the runtime structures. is_const == YES */
560           __sel_register_typed_name (name, type, 
561                                      (struct objc_selector *) &(selectors[i]),
562                                      YES);
563         }
564     }
565
566   /* Parse the classes in the load module and gather selector information.  */
567   DEBUG_PRINTF ("gathering selectors from module: %s\n", module->name);
568   for (i = 0; i < symtab->cls_def_cnt; ++i)
569     {
570       Class class = (Class) symtab->defs[i];
571       const char *superclass = (char *) class->super_class;
572
573       /* Make sure we have what we think.  */
574       assert (CLS_ISCLASS (class));
575       assert (CLS_ISMETA (class->class_pointer));
576       DEBUG_PRINTF ("phase 1, processing class: %s\n", class->name);
577
578       /* Initialize the subclass list to be NULL.
579          In some cases it isn't and this crashes the program.  */
580       class->subclass_list = NULL;
581
582       /* Store the class in the class table and assign class numbers.  */
583       __objc_add_class_to_hash (class);
584
585       /* Register all of the selectors in the class and meta class.  */
586       __objc_register_selectors_from_class (class);
587       __objc_register_selectors_from_class ((Class) class->class_pointer);
588
589       /* Install the fake dispatch tables */
590       __objc_install_premature_dtable (class);
591       __objc_install_premature_dtable (class->class_pointer);
592
593       /* Register the instance methods as class methods, this is
594          only done for root classes.  */
595       __objc_register_instance_methods_to_class (class);
596
597       if (class->protocols)
598         __objc_init_protocols (class->protocols);
599
600       /* Check to see if the superclass is known in this point. If it's not
601          add the class to the unresolved_classes list.  */
602       if (superclass && ! objc_lookup_class (superclass))
603         unresolved_classes = list_cons (class, unresolved_classes);
604    }
605
606   /* Process category information from the module.  */
607   for (i = 0; i < symtab->cat_def_cnt; ++i)
608     {
609       Category_t category = symtab->defs[i + symtab->cls_def_cnt];
610       Class class = objc_lookup_class (category->class_name);
611       
612       /* If the class for the category exists then append its methods.  */
613       if (class)
614         {
615
616           DEBUG_PRINTF ("processing categories from (module,object): %s, %s\n",
617                         module->name,
618                         class->name);
619
620           /* Do instance methods.  */
621           if (category->instance_methods)
622             class_add_method_list (class, category->instance_methods);
623
624           /* Do class methods.  */
625           if (category->class_methods)
626             class_add_method_list ((Class) class->class_pointer, 
627                                    category->class_methods);
628
629           if (category->protocols)
630             {
631               __objc_init_protocols (category->protocols);
632               __objc_class_add_protocols (class, category->protocols);
633             }
634
635           /* Register the instance methods as class methods, this is
636              only done for root classes.  */
637           __objc_register_instance_methods_to_class (class);
638         }
639       else
640         {
641           /* The object to which the category methods belong can't be found.
642              Save the information.  */
643           unclaimed_categories = list_cons (category, unclaimed_categories);
644         }
645     }
646
647   if (statics)
648     uninitialized_statics = list_cons (statics, uninitialized_statics);
649   if (uninitialized_statics)
650     objc_init_statics ();
651
652   /* Scan the unclaimed category hash.  Attempt to attach any unclaimed
653      categories to objects.  */
654   for (cell = &unclaimed_categories; *cell; )
655     {
656       Category_t category = (*cell)->head;
657       Class class = objc_lookup_class (category->class_name);
658       
659       if (class)
660         {
661           DEBUG_PRINTF ("attaching stored categories to object: %s\n",
662                         class->name);
663           
664           list_remove_head (cell);
665           
666           if (category->instance_methods)
667             class_add_method_list (class, category->instance_methods);
668           
669           if (category->class_methods)
670             class_add_method_list ((Class) class->class_pointer,
671                                    category->class_methods);
672
673           if (category->protocols)
674             {
675               __objc_init_protocols (category->protocols);
676               __objc_class_add_protocols (class, category->protocols);
677             }
678
679           /* Register the instance methods as class methods, this is
680              only done for root classes.  */
681           __objc_register_instance_methods_to_class (class);
682         }
683       else
684         cell = &(*cell)->tail;
685     }
686   
687   if (unclaimed_proto_list && objc_lookup_class ("Protocol"))
688     {
689       list_mapcar (unclaimed_proto_list,
690                    (void (*) (void *))__objc_init_protocols);
691       list_free (unclaimed_proto_list);
692       unclaimed_proto_list = 0;
693     }
694
695   objc_send_load ();
696
697   objc_mutex_unlock (__objc_runtime_mutex);
698 }
699
700 static void
701 objc_send_load (void)
702 {
703   if (! __objc_module_list)
704     return;
705  
706   /* Try to find out if all the classes loaded so far also have their
707      superclasses known to the runtime. We suppose that the objects
708      that are allocated in the +load method are in general of a class
709      declared in the same module.  */
710   if (unresolved_classes)
711     {
712       Class class = unresolved_classes->head;
713
714       while (objc_lookup_class ((char *) class->super_class))
715         {
716           list_remove_head (&unresolved_classes);
717           if (unresolved_classes)
718             class = unresolved_classes->head;
719           else
720             break;
721         }
722
723       /* If we still have classes for whom we don't have yet their
724          super classes known to the runtime we don't send the +load
725          messages.  */
726       if (unresolved_classes)
727         return;
728     }
729
730   /* Special check to allow creating and sending messages to constant
731      strings in +load methods. If these classes are not yet known,
732      even if all the other classes are known, delay sending of +load.  */
733   if (! objc_lookup_class ("NXConstantString") ||
734       ! objc_lookup_class ("Object"))
735     return;
736
737   /* Iterate over all modules in the __objc_module_list and call on
738      them the __objc_create_classes_tree function. This function
739      creates a tree of classes that resembles the class hierarchy.  */
740   list_mapcar (__objc_module_list,
741                (void (*) (void *)) __objc_create_classes_tree);
742
743   while (__objc_class_tree_list)
744     {
745 #ifdef DEBUG
746       objc_preorder_traverse (__objc_class_tree_list->head,
747                               0, __objc_tree_print);
748 #endif
749       objc_preorder_traverse (__objc_class_tree_list->head,
750                               0, __objc_send_load);
751       objc_postorder_traverse (__objc_class_tree_list->head,
752                               0, __objc_destroy_class_tree_node);
753       list_remove_head (&__objc_class_tree_list);
754     }
755
756   list_mapcar (__objc_module_list, (void (*) (void *)) __objc_call_callback);
757   list_free (__objc_module_list);
758   __objc_module_list = NULL;
759 }
760
761 static void
762 __objc_create_classes_tree (Module_t module)
763 {
764   /* The runtime mutex is locked in this point */
765
766   Symtab_t symtab = module->symtab;
767   int i;
768
769   /* Iterate thru classes defined in this module and insert them in
770      the classes tree hierarchy.  */
771   for (i = 0; i < symtab->cls_def_cnt; i++)
772     {
773       Class class = (Class) symtab->defs[i];
774
775       objc_tree_insert_class (class);
776     }
777 }
778
779 static void
780 __objc_call_callback (Module_t module)
781 {
782   /* The runtime mutex is locked in this point.  */
783
784   Symtab_t symtab = module->symtab;
785   int i;
786
787   /* Iterate thru classes defined in this module and call the callback
788      for each one.  */
789   for (i = 0; i < symtab->cls_def_cnt; i++)
790     {
791       Class class = (Class) symtab->defs[i];
792
793       /* Call the _objc_load_callback for this class.  */
794       if (_objc_load_callback)
795         _objc_load_callback (class, 0);
796     }
797
798   /* Call the _objc_load_callback for categories. Don't register the
799      instance methods as class methods for categories to root classes
800      since they were already added in the class.  */
801   for (i = 0; i < symtab->cat_def_cnt; i++)
802     {
803       Category_t category = symtab->defs[i + symtab->cls_def_cnt];
804       Class class = objc_lookup_class (category->class_name);
805       
806       if (_objc_load_callback)
807         _objc_load_callback (class, category);
808     }
809 }
810
811 /* Sanity check the version of gcc used to compile `module'.  */
812
813 static void
814 init_check_module_version (Module_t module)
815 {
816   if ((module->version != OBJC_VERSION) || (module->size != sizeof (Module)))
817     {
818       int code;
819
820       if (module->version > OBJC_VERSION)
821         code = OBJC_ERR_OBJC_VERSION;
822       else if (module->version < OBJC_VERSION)
823         code = OBJC_ERR_GCC_VERSION;
824       else
825         code = OBJC_ERR_MODULE_SIZE;
826
827       objc_error (nil, code, "Module %s version %d doesn't match runtime %d\n",
828                   module->name, (int)module->version, OBJC_VERSION);
829     }
830 }
831
832 static void
833 __objc_init_protocols (struct objc_protocol_list *protos)
834 {
835   size_t i;
836   static Class proto_class = 0;
837
838   if (! protos)
839     return;
840
841   objc_mutex_lock (__objc_runtime_mutex);
842
843   if (! proto_class)
844     proto_class = objc_lookup_class ("Protocol");
845
846   if (! proto_class)
847     {
848       unclaimed_proto_list = list_cons (protos, unclaimed_proto_list);
849       objc_mutex_unlock (__objc_runtime_mutex);
850       return;
851     }
852
853 #if 0
854   assert (protos->next == 0);   /* only single ones allowed */
855 #endif
856
857   for (i = 0; i < protos->count; i++)
858     {
859       struct objc_protocol *aProto = protos->list[i];
860       if (((size_t)aProto->class_pointer) == PROTOCOL_VERSION)
861         {
862           /* assign class pointer */
863           aProto->class_pointer = proto_class;
864
865           /* init super protocols */
866           __objc_init_protocols (aProto->protocol_list);
867         }
868       else if (protos->list[i]->class_pointer != proto_class)
869         {
870           objc_error (nil, OBJC_ERR_PROTOCOL_VERSION,
871                      "Version %d doesn't match runtime protocol version %d\n",
872                      (int) ((char *) protos->list[i]->class_pointer
873                             - (char *) 0),
874                      PROTOCOL_VERSION);
875         }
876     }
877
878   objc_mutex_unlock (__objc_runtime_mutex);
879 }
880
881 static void
882 __objc_class_add_protocols (Class class, struct objc_protocol_list *protos)
883 {
884   /* Well...  */
885   if (! protos)
886     return;
887
888   /* Add it...  */
889   protos->next = class->protocols;
890   class->protocols = protos;
891 }