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