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