OSDN Git Service

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