In libobjc/: 2010-12-21 Nicola Pero <nicola.pero@meta-innovation.com>
[official-gcc.git] / libobjc / init.c
blob0e0d372adad699c29fb42ec628aed2657e2dd148
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>
7 This file is part of GCC.
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.
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.
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.
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/>. */
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" /* For __objc_resolve_class_links(). */
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() */
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
47 /* This list contains all modules currently loaded into the
48 runtime. */
49 static struct objc_list *__objc_module_list = 0; /* !T:MUTEX */
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 */
55 /* List of unresolved static instances. */
56 static struct objc_list *uninitialized_statics = 0; /* !T:MUTEX */
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;
71 /* Number of threads that are alive. */
72 int __objc_runtime_threads_alive = 1; /* !T:MUTEX */
74 /* Check compiler vs runtime version. */
75 static void init_check_module_version (struct objc_module *);
77 /* Assign isa links to protos. */
78 static void __objc_init_protocols (struct objc_protocol_list *protos);
80 /* Assign isa link to a protocol, and register it. */
81 static void __objc_init_protocol (struct objc_protocol *protocol);
83 /* Add protocol to class. */
84 static void __objc_class_add_protocols (Class, struct objc_protocol_list *);
86 /* Load callback hook. */
87 void (*_objc_load_callback) (Class class, struct objc_category *category); /* !T:SAFE */
89 /* Are all categories/classes resolved? */
90 BOOL __objc_dangling_categories = NO; /* !T:UNUSED */
92 /* Sends +load to all classes and categories in certain
93 situations. */
94 static void objc_send_load (void);
96 /* Inserts all the classes defined in module in a tree of classes that
97 resembles the class hierarchy. This tree is traversed in preorder
98 and the classes in its nodes receive the +load message if these
99 methods were not executed before. The algorithm ensures that when
100 the +load method of a class is executed all the superclasses have
101 been already received the +load message. */
102 static void __objc_create_classes_tree (struct objc_module *module);
104 static void __objc_call_callback (struct objc_module *module);
106 /* A special version that works only before the classes are completely
107 installed in the runtime. */
108 static BOOL class_is_subclass_of_class (Class class, Class superclass);
110 typedef struct objc_class_tree {
111 Class class;
112 struct objc_list *subclasses; /* `head' is pointer to an objc_class_tree */
113 } objc_class_tree;
115 /* This is a linked list of objc_class_tree trees. The head of these
116 trees are root classes (their super class is Nil). These different
117 trees represent different class hierarchies. */
118 static struct objc_list *__objc_class_tree_list = NULL;
120 /* Keeps the +load methods who have been already executed. This hash
121 should not be destroyed during the execution of the program. */
122 static cache_ptr __objc_load_methods = NULL;
124 /* This function is used when building the class tree used to send
125 ordinately the +load message to all classes needing it. The tree
126 is really needed so that superclasses will get the message before
127 subclasses.
129 This tree will contain classes which are being loaded (or have just
130 being loaded), and whose super_class pointers have not yet been
131 resolved. This implies that their super_class pointers point to a
132 string with the name of the superclass; when the first message is
133 sent to the class (/an object of that class) the class links will
134 be resolved, which will replace the super_class pointers with
135 pointers to the actual superclasses.
137 Unfortunately, the tree might also contain classes which had been
138 loaded previously, and whose class links have already been
139 resolved.
141 This function returns the superclass of a class in both cases, and
142 can be used to build the determine the class relationships while
143 building the tree. */
144 static Class class_superclass_of_class (Class class)
146 char *super_class_name;
148 /* If the class links have been resolved, use the resolved
149 links. */
150 if (CLS_ISRESOLV (class))
151 return class->super_class;
153 /* Else, 'class' has not yet been resolved. This means that its
154 super_class pointer is really the name of the super class (rather
155 than a pointer to the actual superclass). */
156 super_class_name = (char *)class->super_class;
158 /* Return Nil for a root class. */
159 if (super_class_name == NULL)
160 return Nil;
162 /* Lookup the superclass of non-root classes. */
163 return objc_getClass (super_class_name);
167 /* Creates a tree of classes whose topmost class is directly inherited
168 from `upper' and the bottom class in this tree is
169 `bottom_class'. The classes in this tree are super classes of
170 `bottom_class'. `subclasses' member of each tree node point to the
171 next subclass tree node. */
172 static objc_class_tree *
173 create_tree_of_subclasses_inherited_from (Class bottom_class, Class upper)
175 Class superclass;
176 objc_class_tree *tree, *prev;
178 if (bottom_class->super_class)
179 superclass = objc_getClass ((char *) bottom_class->super_class);
180 else
181 superclass = Nil;
183 DEBUG_PRINTF ("create_tree_of_subclasses_inherited_from:");
184 DEBUG_PRINTF ("bottom_class = %s, upper = %s\n",
185 (bottom_class ? bottom_class->name : NULL),
186 (upper ? upper->name : NULL));
188 tree = prev = objc_calloc (1, sizeof (objc_class_tree));
189 prev->class = bottom_class;
191 while (superclass != upper)
193 tree = objc_calloc (1, sizeof (objc_class_tree));
194 tree->class = superclass;
195 tree->subclasses = list_cons (prev, tree->subclasses);
196 superclass = class_superclass_of_class (superclass);
197 prev = tree;
200 return tree;
203 /* Insert the `class' into the proper place in the `tree' class
204 hierarchy. This function returns a new tree if the class has been
205 successfully inserted into the tree or NULL if the class is not
206 part of the classes hierarchy described by `tree'. This function is
207 private to objc_tree_insert_class (), you should not call it
208 directly. */
209 static objc_class_tree *
210 __objc_tree_insert_class (objc_class_tree *tree, Class class)
212 DEBUG_PRINTF ("__objc_tree_insert_class: tree = %x, class = %s\n",
213 tree, class->name);
215 if (tree == NULL)
216 return create_tree_of_subclasses_inherited_from (class, NULL);
217 else if (class == tree->class)
219 /* `class' has been already inserted. */
220 DEBUG_PRINTF ("1. class %s was previously inserted\n", class->name);
221 return tree;
223 else if (class_superclass_of_class (class) == tree->class)
225 /* If class is a direct subclass of tree->class then add class
226 to the list of subclasses. First check to see if it wasn't
227 already inserted. */
228 struct objc_list *list = tree->subclasses;
229 objc_class_tree *node;
231 while (list)
233 /* Class has been already inserted; do nothing just return
234 the tree. */
235 if (((objc_class_tree *) list->head)->class == class)
237 DEBUG_PRINTF ("2. class %s was previously inserted\n",
238 class->name);
239 return tree;
241 list = list->tail;
244 /* Create a new node class and insert it into the list of
245 subclasses. */
246 node = objc_calloc (1, sizeof (objc_class_tree));
247 node->class = class;
248 tree->subclasses = list_cons (node, tree->subclasses);
249 DEBUG_PRINTF ("3. class %s inserted\n", class->name);
250 return tree;
252 else
254 /* The class is not a direct subclass of tree->class. Search
255 for class's superclasses in the list of subclasses. */
256 struct objc_list *subclasses = tree->subclasses;
258 /* Precondition: the class must be a subclass of tree->class;
259 otherwise return NULL to indicate our caller that it must
260 take the next tree. */
261 if (! class_is_subclass_of_class (class, tree->class))
262 return NULL;
264 for (; subclasses != NULL; subclasses = subclasses->tail)
266 Class aClass = ((objc_class_tree *) (subclasses->head))->class;
268 if (class_is_subclass_of_class (class, aClass))
270 /* If we found one of class's superclasses we insert the
271 class into its subtree and return the original tree
272 since nothing has been changed. */
273 subclasses->head
274 = __objc_tree_insert_class (subclasses->head, class);
275 DEBUG_PRINTF ("4. class %s inserted\n", class->name);
276 return tree;
280 /* We haven't found a subclass of `class' in the `subclasses'
281 list. Create a new tree of classes whose topmost class is a
282 direct subclass of tree->class. */
284 objc_class_tree *new_tree
285 = create_tree_of_subclasses_inherited_from (class, tree->class);
286 tree->subclasses = list_cons (new_tree, tree->subclasses);
287 DEBUG_PRINTF ("5. class %s inserted\n", class->name);
288 return tree;
293 /* This function inserts `class' in the right tree hierarchy classes. */
294 static void
295 objc_tree_insert_class (Class class)
297 struct objc_list *list_node;
298 objc_class_tree *tree;
300 list_node = __objc_class_tree_list;
301 while (list_node)
303 tree = __objc_tree_insert_class (list_node->head, class);
304 if (tree)
306 list_node->head = tree;
307 break;
309 else
310 list_node = list_node->tail;
313 /* If the list was finished but the class hasn't been inserted,
314 insert it here. */
315 if (! list_node)
317 __objc_class_tree_list = list_cons (NULL, __objc_class_tree_list);
318 __objc_class_tree_list->head = __objc_tree_insert_class (NULL, class);
322 /* Traverse tree in preorder. Used to send +load. */
323 static void
324 objc_preorder_traverse (objc_class_tree *tree,
325 int level,
326 void (*function) (objc_class_tree *, int))
328 struct objc_list *node;
330 (*function) (tree, level);
331 for (node = tree->subclasses; node; node = node->tail)
332 objc_preorder_traverse (node->head, level + 1, function);
335 /* Traverse tree in postorder. Used to destroy a tree. */
336 static void
337 objc_postorder_traverse (objc_class_tree *tree,
338 int level,
339 void (*function) (objc_class_tree *, int))
341 struct objc_list *node;
343 for (node = tree->subclasses; node; node = node->tail)
344 objc_postorder_traverse (node->head, level + 1, function);
345 (*function) (tree, level);
348 /* Used to print a tree class hierarchy. */
349 #ifdef DEBUG
350 static void
351 __objc_tree_print (objc_class_tree *tree, int level)
353 int i;
355 for (i = 0; i < level; i++)
356 printf (" ");
357 printf ("%s\n", tree->class->name);
359 #endif
361 /* Walks on a linked list of methods in the reverse order and executes
362 all the methods corresponding to `op' selector. Walking in the
363 reverse order assures the +load of class is executed first and then
364 +load of categories because of the way in which categories are
365 added to the class methods. */
366 static void
367 __objc_send_message_in_list (struct objc_method_list *method_list, Class class, SEL op)
369 int i;
371 if (! method_list)
372 return;
374 /* First execute the `op' message in the following method lists. */
375 __objc_send_message_in_list (method_list->method_next, class, op);
377 /* Search the method list. */
378 for (i = 0; i < method_list->method_count; i++)
380 struct objc_method *mth = &method_list->method_list[i];
382 if (mth->method_name && sel_eq (mth->method_name, op)
383 && ! objc_hash_is_key_in_hash (__objc_load_methods, mth->method_imp))
385 /* Add this method into the +load hash table. */
386 objc_hash_add (&__objc_load_methods,
387 mth->method_imp,
388 mth->method_imp);
390 DEBUG_PRINTF ("sending +load in class: %s\n", class->name);
392 /* The method was found and wasn't previously executed. */
393 (*mth->method_imp) ((id)class, mth->method_name);
395 break;
400 static void
401 __objc_send_load (objc_class_tree *tree,
402 int level __attribute__ ((__unused__)))
404 static SEL load_sel = 0;
405 Class class = tree->class;
406 struct objc_method_list *method_list = class->class_pointer->methods;
408 if (! load_sel)
409 load_sel = sel_registerName ("load");
411 __objc_send_message_in_list (method_list, class, load_sel);
414 static void
415 __objc_destroy_class_tree_node (objc_class_tree *tree,
416 int level __attribute__ ((__unused__)))
418 objc_free (tree);
421 /* This is used to check if the relationship between two classes
422 before the runtime completely installs the classes. */
423 static BOOL
424 class_is_subclass_of_class (Class class, Class superclass)
426 for (; class != Nil;)
428 if (class == superclass)
429 return YES;
430 class = class_superclass_of_class (class);
433 return NO;
436 /* This list contains all the classes in the runtime system for whom
437 their superclasses are not yet known to the runtime. */
438 static struct objc_list *unresolved_classes = 0;
440 /* Extern function used to reference the Object class. */
441 extern void __objc_force_linking (void);
443 void
444 __objc_force_linking (void)
446 extern void __objc_linking (void);
447 __objc_linking ();
450 /* Run through the statics list, removing modules as soon as all its
451 statics have been initialized. */
452 static void
453 objc_init_statics (void)
455 struct objc_list **cell = &uninitialized_statics;
456 struct objc_static_instances **statics_in_module;
458 objc_mutex_lock (__objc_runtime_mutex);
460 while (*cell)
462 int module_initialized = 1;
464 for (statics_in_module = (*cell)->head;
465 *statics_in_module; statics_in_module++)
467 struct objc_static_instances *statics = *statics_in_module;
468 Class class = objc_getClass (statics->class_name);
470 if (! class)
472 /* It is unfortunate that this will cause all the
473 statics initialization to be done again (eg, if we
474 already initialized constant strings, and are now
475 initializing protocols, setting module_initialized to
476 0 would cause constant strings to be initialized
477 again). It would be good to be able to track if we
478 have already initialized some of them. */
479 module_initialized = 0;
481 else
483 /* Note that if this is a list of Protocol objects, some
484 of them may have been initialized already (because
485 they were attached to classes or categories, and the
486 class/category loading code automatically fixes them
487 up), and some of them may not. We really need to go
488 through the whole list to be sure! Protocols are
489 also special because we want to register them and
490 register all their selectors. */
491 id *inst;
493 if (strcmp (statics->class_name, "Protocol") == 0)
495 /* Protocols are special, because not only we want
496 to fix up their class pointers, but we also want
497 to register them and their selectors with the
498 runtime. */
499 for (inst = &statics->instances[0]; *inst; inst++)
500 __objc_init_protocol ((struct objc_protocol *)*inst);
502 else
504 /* Other static instances (typically constant
505 strings) are easier as we just fix up their class
506 pointers. */
507 for (inst = &statics->instances[0]; *inst; inst++)
508 (*inst)->class_pointer = class;
512 if (module_initialized)
514 /* Remove this module from the uninitialized list. */
515 struct objc_list *this = *cell;
516 *cell = this->tail;
517 objc_free (this);
519 else
520 cell = &(*cell)->tail;
523 objc_mutex_unlock (__objc_runtime_mutex);
526 /* This function is called by constructor functions generated for each
527 module compiled. (_GLOBAL_$I$...) The purpose of this function is
528 to gather the module pointers so that they may be processed by the
529 initialization routines as soon as possible. */
530 void
531 __objc_exec_class (struct objc_module *module)
533 /* Have we processed any constructors previously? This flag is used
534 to indicate that some global data structures need to be
535 built. */
536 static BOOL previous_constructors = 0;
538 static struct objc_list *unclaimed_categories = 0;
540 /* The symbol table (defined in objc-private/module-abi-8.h)
541 generated by gcc. */
542 struct objc_symtab *symtab = module->symtab;
544 /* The statics in this module. */
545 struct objc_static_instances **statics
546 = symtab->defs[symtab->cls_def_cnt + symtab->cat_def_cnt];
548 /* Entry used to traverse hash lists. */
549 struct objc_list **cell;
551 /* The table of selector references for this module. */
552 struct objc_selector *selectors = symtab->refs;
554 int i;
556 DEBUG_PRINTF ("received module: %s\n", module->name);
558 /* Check gcc version. */
559 init_check_module_version (module);
561 /* On the first call of this routine, initialize some data
562 structures. */
563 if (! previous_constructors)
565 /* Initialize thread-safe system. */
566 __objc_init_thread_system ();
567 __objc_runtime_threads_alive = 1;
568 __objc_runtime_mutex = objc_mutex_allocate ();
570 __objc_init_selector_tables ();
571 __objc_init_class_tables ();
572 __objc_init_dispatch_tables ();
573 __objc_class_tree_list = list_cons (NULL, __objc_class_tree_list);
574 __objc_load_methods = objc_hash_new (128,
575 (hash_func_type)objc_hash_ptr,
576 objc_compare_ptrs);
577 __objc_protocols_init ();
578 __objc_accessors_init ();
579 __objc_sync_init ();
580 previous_constructors = 1;
583 /* Save the module pointer for later processing. (not currently
584 used). */
585 objc_mutex_lock (__objc_runtime_mutex);
586 __objc_module_list = list_cons (module, __objc_module_list);
588 /* Replace referenced selectors from names to SELs. */
589 if (selectors)
590 __objc_register_selectors_from_module (selectors);
592 /* Parse the classes in the load module and gather selector
593 information. */
594 DEBUG_PRINTF ("gathering selectors from module: %s\n", module->name);
595 for (i = 0; i < symtab->cls_def_cnt; ++i)
597 Class class = (Class) symtab->defs[i];
598 const char *superclass = (char *) class->super_class;
600 /* Make sure we have what we think. */
601 assert (CLS_ISCLASS (class));
602 assert (CLS_ISMETA (class->class_pointer));
603 DEBUG_PRINTF ("phase 1, processing class: %s\n", class->name);
605 /* Initialize the subclass list to be NULL. In some cases it
606 isn't and this crashes the program. */
607 class->subclass_list = NULL;
609 __objc_init_class (class);
611 /* Check to see if the superclass is known in this point. If
612 it's not add the class to the unresolved_classes list. */
613 if (superclass && ! objc_getClass (superclass))
614 unresolved_classes = list_cons (class, unresolved_classes);
617 /* Process category information from the module. */
618 for (i = 0; i < symtab->cat_def_cnt; ++i)
620 struct objc_category *category = symtab->defs[i + symtab->cls_def_cnt];
621 Class class = objc_getClass (category->class_name);
623 /* If the class for the category exists then append its
624 methods. */
625 if (class)
628 DEBUG_PRINTF ("processing categories from (module,object): %s, %s\n",
629 module->name,
630 class->name);
632 /* Do instance methods. */
633 if (category->instance_methods)
634 class_add_method_list (class, category->instance_methods);
636 /* Do class methods. */
637 if (category->class_methods)
638 class_add_method_list ((Class) class->class_pointer,
639 category->class_methods);
641 if (category->protocols)
643 __objc_init_protocols (category->protocols);
644 __objc_class_add_protocols (class, category->protocols);
647 /* Register the instance methods as class methods, this is
648 only done for root classes. */
649 __objc_register_instance_methods_to_class (class);
651 else
653 /* The object to which the category methods belong can't be
654 found. Save the information. */
655 unclaimed_categories = list_cons (category, unclaimed_categories);
659 if (statics)
660 uninitialized_statics = list_cons (statics, uninitialized_statics);
661 if (uninitialized_statics)
662 objc_init_statics ();
664 /* Scan the unclaimed category hash. Attempt to attach any
665 unclaimed categories to objects. */
666 for (cell = &unclaimed_categories; *cell; )
668 struct objc_category *category = (*cell)->head;
669 Class class = objc_getClass (category->class_name);
671 if (class)
673 DEBUG_PRINTF ("attaching stored categories to object: %s\n",
674 class->name);
676 list_remove_head (cell);
678 if (category->instance_methods)
679 class_add_method_list (class, category->instance_methods);
681 if (category->class_methods)
682 class_add_method_list ((Class) class->class_pointer,
683 category->class_methods);
685 if (category->protocols)
687 __objc_init_protocols (category->protocols);
688 __objc_class_add_protocols (class, category->protocols);
691 /* Register the instance methods as class methods, this is
692 only done for root classes. */
693 __objc_register_instance_methods_to_class (class);
695 else
696 cell = &(*cell)->tail;
699 if (unclaimed_proto_list && objc_getClass ("Protocol"))
701 list_mapcar (unclaimed_proto_list,
702 (void (*) (void *))__objc_init_protocols);
703 list_free (unclaimed_proto_list);
704 unclaimed_proto_list = 0;
707 objc_send_load ();
709 /* Check if there are no unresolved classes (ie, classes whose
710 superclass has not been loaded yet) and that the 'Object' class,
711 used as the class of classes, exist. If so, it is worth
712 "resolving the class links" at this point, which will setup all
713 the class/superclass pointers. */
714 if (!unresolved_classes && objc_getClass ("Object"))
715 __objc_resolve_class_links ();
717 objc_mutex_unlock (__objc_runtime_mutex);
720 static void
721 objc_send_load (void)
723 if (! __objc_module_list)
724 return;
726 /* Try to find out if all the classes loaded so far also have their
727 superclasses known to the runtime. We suppose that the objects
728 that are allocated in the +load method are in general of a class
729 declared in the same module. */
730 if (unresolved_classes)
732 Class class = unresolved_classes->head;
734 while (objc_getClass ((char *) class->super_class))
736 list_remove_head (&unresolved_classes);
737 if (unresolved_classes)
738 class = unresolved_classes->head;
739 else
740 break;
743 /* If we still have classes for whom we don't have yet their
744 super classes known to the runtime we don't send the +load
745 messages. */
746 if (unresolved_classes)
747 return;
750 /* Special check. If 'Object', which is used by meta-classes, has
751 not been loaded yet, delay sending of +load. */
752 if (! objc_getClass ("Object"))
753 return;
755 /* Iterate over all modules in the __objc_module_list and call on
756 them the __objc_create_classes_tree function. This function
757 creates a tree of classes that resembles the class hierarchy. */
758 list_mapcar (__objc_module_list,
759 (void (*) (void *)) __objc_create_classes_tree);
761 while (__objc_class_tree_list)
763 #ifdef DEBUG
764 objc_preorder_traverse (__objc_class_tree_list->head,
765 0, __objc_tree_print);
766 #endif
767 objc_preorder_traverse (__objc_class_tree_list->head,
768 0, __objc_send_load);
769 objc_postorder_traverse (__objc_class_tree_list->head,
770 0, __objc_destroy_class_tree_node);
771 list_remove_head (&__objc_class_tree_list);
774 list_mapcar (__objc_module_list, (void (*) (void *)) __objc_call_callback);
775 list_free (__objc_module_list);
776 __objc_module_list = NULL;
779 static void
780 __objc_create_classes_tree (struct objc_module *module)
782 /* The runtime mutex is locked at this point */
783 struct objc_symtab *symtab = module->symtab;
784 int i;
786 /* Iterate thru classes defined in this module and insert them in
787 the classes tree hierarchy. */
788 for (i = 0; i < symtab->cls_def_cnt; i++)
790 Class class = (Class) symtab->defs[i];
792 objc_tree_insert_class (class);
796 static void
797 __objc_call_callback (struct objc_module *module)
799 /* The runtime mutex is locked at this point. */
800 struct objc_symtab *symtab = module->symtab;
801 int i;
803 /* Iterate thru classes defined in this module and call the callback
804 for each one. */
805 for (i = 0; i < symtab->cls_def_cnt; i++)
807 Class class = (Class) symtab->defs[i];
809 /* Call the _objc_load_callback for this class. */
810 if (_objc_load_callback)
811 _objc_load_callback (class, 0);
814 /* Call the _objc_load_callback for categories. Don't register the
815 instance methods as class methods for categories to root classes
816 since they were already added in the class. */
817 for (i = 0; i < symtab->cat_def_cnt; i++)
819 struct objc_category *category = symtab->defs[i + symtab->cls_def_cnt];
820 Class class = objc_getClass (category->class_name);
822 if (_objc_load_callback)
823 _objc_load_callback (class, category);
827 /* Sanity check the version of gcc used to compile `module'. */
828 static void
829 init_check_module_version (struct objc_module *module)
831 if ((module->version != OBJC_VERSION) || (module->size != sizeof (struct objc_module)))
833 _objc_abort ("Module %s version %d doesn't match runtime %d\n",
834 module->name, (int)module->version, OBJC_VERSION);
838 /* __objc_init_class must be called with __objc_runtime_mutex already locked. */
839 void
840 __objc_init_class (Class class)
842 /* Store the class in the class table and assign class numbers. */
843 __objc_add_class_to_hash (class);
845 /* Register all of the selectors in the class and meta class. */
846 __objc_register_selectors_from_class (class);
847 __objc_register_selectors_from_class ((Class) class->class_pointer);
849 /* Install the fake dispatch tables. */
850 __objc_install_premature_dtable (class);
851 __objc_install_premature_dtable (class->class_pointer);
853 /* Register the instance methods as class methods, this is only done
854 for root classes. */
855 __objc_register_instance_methods_to_class (class);
857 if (class->protocols)
858 __objc_init_protocols (class->protocols);
861 /* __objc_init_protocol must be called with __objc_runtime_mutex
862 already locked, and the "Protocol" class already registered. */
863 static void
864 __objc_init_protocol (struct objc_protocol *protocol)
866 static Class proto_class = 0;
868 if (! proto_class)
869 proto_class = objc_getClass ("Protocol");
871 if (((size_t)protocol->class_pointer) == PROTOCOL_VERSION)
873 /* Assign class pointer. */
874 protocol->class_pointer = proto_class;
876 /* Register all the selectors in the protocol with the runtime.
877 This both registers the selectors with the right types, and
878 it also fixes up the 'struct objc_method' structures inside
879 the protocol so that each method_name (a char * as compiled
880 by the compiler) is replaced with the appropriate runtime
881 SEL. */
882 if (protocol->class_methods)
883 __objc_register_selectors_from_description_list (protocol->class_methods);
885 if (protocol->instance_methods)
886 __objc_register_selectors_from_description_list (protocol->instance_methods);
888 /* Register the protocol in the hashtable or protocols by
889 name. */
890 __objc_protocols_add_protocol (protocol->protocol_name, protocol);
892 /* Init super protocols. */
893 __objc_init_protocols (protocol->protocol_list);
895 else if (protocol->class_pointer != proto_class)
897 _objc_abort ("Version %d doesn't match runtime protocol version %d\n",
898 (int) ((char *) protocol->class_pointer
899 - (char *) 0),
900 PROTOCOL_VERSION);
904 static void
905 __objc_init_protocols (struct objc_protocol_list *protos)
907 size_t i;
908 static Class proto_class = 0;
910 if (! protos)
911 return;
913 objc_mutex_lock (__objc_runtime_mutex);
915 if (! proto_class)
916 proto_class = objc_getClass ("Protocol");
918 if (! proto_class)
920 unclaimed_proto_list = list_cons (protos, unclaimed_proto_list);
921 objc_mutex_unlock (__objc_runtime_mutex);
922 return;
925 #if 0
926 assert (protos->next == 0); /* Only single ones allowed. */
927 #endif
929 for (i = 0; i < protos->count; i++)
931 struct objc_protocol *aProto = protos->list[i];
932 __objc_init_protocol (aProto);
935 objc_mutex_unlock (__objc_runtime_mutex);
938 static void
939 __objc_class_add_protocols (Class class, struct objc_protocol_list *protos)
941 if (! protos)
942 return;
944 protos->next = class->protocols;
945 class->protocols = protos;