OSDN Git Service

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