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