OSDN Git Service

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