OSDN Git Service

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