OSDN Git Service

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