In gcc/objc/: 2010-11-29 Nicola Pero <nicola.pero@meta-innovation.com>
[official-gcc.git] / libobjc / init.c
blobb348e77d0fd1a75cf22e64707fc43d86aad8a3ff
1 /* GNU Objective C Runtime initialization
2 Copyright (C) 1993, 1995, 1996, 1997, 2002, 2009
3 Free Software Foundation, Inc.
4 Contributed by Kresten Krab Thorup
5 +load support contributed by Ovidiu Predescu <ovidiu@net-community.com>
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/objc-api.h"
30 #include "objc/thr.h"
31 #include "objc-private/hash.h"
32 #include "objc-private/objc-list.h"
33 #include "objc-private/runtime.h"
34 #include "objc-private/objc-sync.h" /* For __objc_sync_init() */
35 #include "objc-private/protocols.h" /* For __objc_protocols_init(),
36 __objc_protocols_add_protocol()
37 __objc_protocols_register_selectors() */
38 #include "objc-private/accessors.h" /* For __objc_accessors_init() */
40 /* The version number of this runtime. This must match the number
41 defined in gcc (objc-act.c). */
42 #define OBJC_VERSION 8
43 #define PROTOCOL_VERSION 2
45 /* This list contains all modules currently loaded into the runtime. */
46 static struct objc_list *__objc_module_list = 0; /* !T:MUTEX */
48 /* This list contains all proto_list's not yet assigned class links. */
49 static struct objc_list *unclaimed_proto_list = 0; /* !T:MUTEX */
51 /* List of unresolved static instances. */
52 static struct objc_list *uninitialized_statics = 0; /* !T:MUTEX */
54 /* Global runtime "write" mutex. Having a single mutex prevents
55 deadlocks, but reduces concurrency. To improve concurrency, some
56 groups of functions in the runtime have their own separate mutex
57 (eg, __class_table_lock in class.c); to avoid deadlocks, these
58 routines must make sure that they never acquire any other lock
59 while holding their own local lock. Ie, they should lock, execute
60 some C code that does not perform any calls to other runtime
61 functions which may potentially lock different locks, then unlock.
62 If they need to perform any calls to other runtime functions that
63 may potentially lock other locks, then they should use the global
64 __objc_runtime_mutex. */
65 objc_mutex_t __objc_runtime_mutex = 0;
67 /* Number of threads that are alive. */
68 int __objc_runtime_threads_alive = 1; /* !T:MUTEX */
70 /* Check compiler vs runtime version. */
71 static void init_check_module_version (Module_t);
73 /* Assign isa links to protos. */
74 static void __objc_init_protocols (struct objc_protocol_list *protos);
76 /* Assign isa link to a protocol, and register it. */
77 static void __objc_init_protocol (struct objc_protocol *protocol);
79 /* Add protocol to class. */
80 static void __objc_class_add_protocols (Class, struct objc_protocol_list *);
82 /* This is a hook which is called by __objc_exec_class every time a
83 class or a category is loaded into the runtime. This may e.g. help
84 a dynamic loader determine the classes that have been loaded when
85 an object file is dynamically linked in. */
86 void (*_objc_load_callback) (Class class, Category *category); /* !T:SAFE */
88 /* Is all categories/classes resolved? */
89 BOOL __objc_dangling_categories = NO; /* !T:UNUSED */
91 extern SEL
92 __sel_register_typed_name (const char *name, const char *types,
93 struct objc_selector *orig, BOOL is_const);
95 /* Sends +load to all classes and categories in certain situations. */
96 static void objc_send_load (void);
98 /* Inserts all the classes defined in module in a tree of classes that
99 resembles the class hierarchy. This tree is traversed in preorder
100 and the classes in its nodes receive the +load message if these
101 methods were not executed before. The algorithm ensures that when
102 the +load method of a class is executed all the superclasses have
103 been already received the +load message. */
104 static void __objc_create_classes_tree (Module_t module);
106 static void __objc_call_callback (Module_t module);
108 /* A special version that works only before the classes are completely
109 installed in the runtime. */
110 static BOOL class_is_subclass_of_class (Class class, Class superclass);
112 typedef struct objc_class_tree {
113 Class class;
114 struct objc_list *subclasses; /* `head' is pointer to an objc_class_tree */
115 } objc_class_tree;
117 /* This is a linked list of objc_class_tree trees. The head of these
118 trees are root classes (their super class is Nil). These different
119 trees represent different class hierarchies. */
120 static struct objc_list *__objc_class_tree_list = NULL;
122 /* Keeps the +load methods who have been already executed. This hash
123 should not be destroyed during the execution of the program. */
124 static cache_ptr __objc_load_methods = NULL;
126 /* This function is used when building the class tree used to send
127 ordinately the +load message to all classes needing it. The tree
128 is really needed so that superclasses will get the message before
129 subclasses.
131 This tree will contain classes which are being loaded (or have just
132 being loaded), and whose super_class pointers have not yet been
133 resolved. This implies that their super_class pointers point to a
134 string with the name of the superclass; when the first message is
135 sent to the class (/an object of that class) the class links will
136 be resolved, which will replace the super_class pointers with
137 pointers to the actual superclasses.
139 Unfortunately, the tree might also contain classes which had been
140 loaded previously, and whose class links have already been
141 resolved.
143 This function returns the superclass of a class in both cases, and
144 can be used to build the determine the class relationships while
145 building the tree.
147 static Class class_superclass_of_class (Class class)
149 char *super_class_name;
151 /* If the class links have been resolved, use the resolved
152 * links. */
153 if (CLS_ISRESOLV (class))
154 return class->super_class;
156 /* Else, 'class' has not yet been resolved. This means that its
157 * super_class pointer is really the name of the super class (rather
158 * than a pointer to the actual superclass). */
159 super_class_name = (char *)class->super_class;
161 /* Return Nil for a root class. */
162 if (super_class_name == NULL)
163 return Nil;
165 /* Lookup the superclass of non-root classes. */
166 return objc_lookup_class (super_class_name);
170 /* Creates a tree of classes whose topmost class is directly inherited
171 from `upper' and the bottom class in this tree is
172 `bottom_class'. The classes in this tree are super classes of
173 `bottom_class'. `subclasses' member of each tree node point to the
174 next subclass tree node. */
176 static objc_class_tree *
177 create_tree_of_subclasses_inherited_from (Class bottom_class, Class upper)
179 Class superclass = bottom_class->super_class ?
180 objc_lookup_class ((char *) bottom_class->super_class)
181 : Nil;
183 objc_class_tree *tree, *prev;
185 DEBUG_PRINTF ("create_tree_of_subclasses_inherited_from:");
186 DEBUG_PRINTF ("bottom_class = %s, upper = %s\n",
187 (bottom_class ? bottom_class->name : NULL),
188 (upper ? upper->name : NULL));
190 tree = prev = objc_calloc (1, sizeof (objc_class_tree));
191 prev->class = bottom_class;
193 while (superclass != upper)
195 tree = objc_calloc (1, sizeof (objc_class_tree));
196 tree->class = superclass;
197 tree->subclasses = list_cons (prev, tree->subclasses);
198 superclass = class_superclass_of_class (superclass);
199 prev = tree;
202 return tree;
205 /* Insert the `class' into the proper place in the `tree' class
206 hierarchy. This function returns a new tree if the class has been
207 successfully inserted into the tree or NULL if the class is not
208 part of the classes hierarchy described by `tree'. This function is
209 private to objc_tree_insert_class (), you should not call it
210 directly. */
212 static objc_class_tree *
213 __objc_tree_insert_class (objc_class_tree *tree, Class class)
215 DEBUG_PRINTF ("__objc_tree_insert_class: tree = %x, class = %s\n",
216 tree, class->name);
218 if (tree == NULL)
219 return create_tree_of_subclasses_inherited_from (class, NULL);
220 else if (class == tree->class)
222 /* `class' has been already inserted */
223 DEBUG_PRINTF ("1. class %s was previously inserted\n", class->name);
224 return tree;
226 else if (class_superclass_of_class (class) == tree->class)
228 /* If class is a direct subclass of tree->class then add class to the
229 list of subclasses. First check to see if it wasn't already
230 inserted. */
231 struct objc_list *list = tree->subclasses;
232 objc_class_tree *node;
234 while (list)
236 /* Class has been already inserted; do nothing just return
237 the tree. */
238 if (((objc_class_tree *) list->head)->class == class)
240 DEBUG_PRINTF ("2. class %s was previously inserted\n",
241 class->name);
242 return tree;
244 list = list->tail;
247 /* Create a new node class and insert it into the list of subclasses */
248 node = objc_calloc (1, sizeof (objc_class_tree));
249 node->class = class;
250 tree->subclasses = list_cons (node, tree->subclasses);
251 DEBUG_PRINTF ("3. class %s inserted\n", class->name);
252 return tree;
254 else
256 /* The class is not a direct subclass of tree->class. Search for
257 class's superclasses in the list of subclasses. */
258 struct objc_list *subclasses = tree->subclasses;
260 /* Precondition: the class must be a subclass of tree->class;
261 otherwise return NULL to indicate our caller that it must
262 take the next tree. */
263 if (! class_is_subclass_of_class (class, tree->class))
264 return NULL;
266 for (; subclasses != NULL; subclasses = subclasses->tail)
268 Class aClass = ((objc_class_tree *) (subclasses->head))->class;
270 if (class_is_subclass_of_class (class, aClass))
272 /* If we found one of class's superclasses we insert the
273 class into its subtree and return the original tree
274 since nothing has been changed. */
275 subclasses->head
276 = __objc_tree_insert_class (subclasses->head, class);
277 DEBUG_PRINTF ("4. class %s inserted\n", class->name);
278 return tree;
282 /* We haven't found a subclass of `class' in the `subclasses'
283 list. Create a new tree of classes whose topmost class is a
284 direct subclass of tree->class. */
286 objc_class_tree *new_tree
287 = create_tree_of_subclasses_inherited_from (class, tree->class);
288 tree->subclasses = list_cons (new_tree, tree->subclasses);
289 DEBUG_PRINTF ("5. class %s inserted\n", class->name);
290 return tree;
295 /* This function inserts `class' in the right tree hierarchy classes. */
297 static void
298 objc_tree_insert_class (Class class)
300 struct objc_list *list_node;
301 objc_class_tree *tree;
303 list_node = __objc_class_tree_list;
304 while (list_node)
306 tree = __objc_tree_insert_class (list_node->head, class);
307 if (tree)
309 list_node->head = tree;
310 break;
312 else
313 list_node = list_node->tail;
316 /* If the list was finished but the class hasn't been inserted,
317 insert it here. */
318 if (! list_node)
320 __objc_class_tree_list = list_cons (NULL, __objc_class_tree_list);
321 __objc_class_tree_list->head = __objc_tree_insert_class (NULL, class);
325 /* 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))
332 struct objc_list *node;
334 (*function) (tree, level);
335 for (node = tree->subclasses; node; node = node->tail)
336 objc_preorder_traverse (node->head, level + 1, function);
339 /* Traverse tree in postorder. Used to destroy a tree. */
341 static void
342 objc_postorder_traverse (objc_class_tree *tree,
343 int level,
344 void (*function) (objc_class_tree *, int))
346 struct objc_list *node;
348 for (node = tree->subclasses; node; node = node->tail)
349 objc_postorder_traverse (node->head, level + 1, function);
350 (*function) (tree, level);
353 /* Used to print a tree class hierarchy. */
355 #ifdef DEBUG
356 static void
357 __objc_tree_print (objc_class_tree *tree, int level)
359 int i;
361 for (i = 0; i < level; i++)
362 printf (" ");
363 printf ("%s\n", tree->class->name);
365 #endif
367 /* Walks on a linked list of methods in the reverse order and executes
368 all the methods corresponding to `op' selector. Walking in the
369 reverse order assures the +load of class is executed first and then
370 +load of categories because of the way in which categories are
371 added to the class methods. */
373 static void
374 __objc_send_message_in_list (MethodList_t method_list, Class class, SEL op)
376 int i;
378 if (! method_list)
379 return;
381 /* First execute the `op' message in the following method lists */
382 __objc_send_message_in_list (method_list->method_next, class, op);
384 /* Search the method list. */
385 for (i = 0; i < method_list->method_count; i++)
387 Method_t mth = &method_list->method_list[i];
389 if (mth->method_name && sel_eq (mth->method_name, op)
390 && ! objc_hash_is_key_in_hash (__objc_load_methods, mth->method_imp))
392 /* Add this method into the +load hash table */
393 objc_hash_add (&__objc_load_methods,
394 mth->method_imp,
395 mth->method_imp);
397 DEBUG_PRINTF ("sending +load in class: %s\n", class->name);
399 /* The method was found and wasn't previously executed. */
400 (*mth->method_imp) ((id)class, mth->method_name);
402 break;
407 static void
408 __objc_send_load (objc_class_tree *tree,
409 int level __attribute__ ((__unused__)))
411 static SEL load_sel = 0;
412 Class class = tree->class;
413 MethodList_t method_list = class->class_pointer->methods;
415 if (! load_sel)
416 load_sel = sel_register_name ("load");
418 __objc_send_message_in_list (method_list, class, load_sel);
421 static void
422 __objc_destroy_class_tree_node (objc_class_tree *tree,
423 int level __attribute__ ((__unused__)))
425 objc_free (tree);
428 /* This is used to check if the relationship between two classes
429 before the runtime completely installs the classes. */
431 static BOOL
432 class_is_subclass_of_class (Class class, Class superclass)
434 for (; class != Nil;)
436 if (class == superclass)
437 return YES;
438 class = class_superclass_of_class (class);
441 return NO;
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;
448 /* Extern function used to reference the Object class. */
450 extern void __objc_force_linking (void);
452 void
453 __objc_force_linking (void)
455 extern void __objc_linking (void);
456 __objc_linking ();
459 /* Run through the statics list, removing modules as soon as all its
460 statics have been initialized. */
462 static void
463 objc_init_statics (void)
465 struct objc_list **cell = &uninitialized_statics;
466 struct objc_static_instances **statics_in_module;
468 objc_mutex_lock (__objc_runtime_mutex);
470 while (*cell)
472 int module_initialized = 1;
474 for (statics_in_module = (*cell)->head;
475 *statics_in_module; statics_in_module++)
477 struct objc_static_instances *statics = *statics_in_module;
478 Class class = objc_lookup_class (statics->class_name);
480 if (! class)
482 /* It is unfortunate that this will cause all the
483 statics initialization to be done again (eg, if we
484 already initialized constant strings, and are now
485 initializing protocols, setting module_initialized to
486 0 would cause constant strings to be initialized
487 again). It would be good to be able to track if we
488 have already initialized some of them. */
489 module_initialized = 0;
491 else
493 /* Note that if this is a list of Protocol objects, some
494 of them may have been initialized already (because
495 they were attached to classes or categories, and the
496 class/category loading code automatically fixes them
497 up), and some of them may not. We really need to go
498 through the whole list to be sure! Protocols are
499 also special because we want to register them and
500 register all their selectors. */
501 id *inst;
503 if (strcmp (statics->class_name, "Protocol") == 0)
505 /* Protocols are special, because not only we want
506 to fix up their class pointers, but we also want
507 to register them and their selectors with the
508 runtime. */
509 for (inst = &statics->instances[0]; *inst; inst++)
510 __objc_init_protocol ((struct objc_protocol *)*inst);
512 else
514 /* Other static instances (typically constant strings) are
515 easier as we just fix up their class pointers. */
516 for (inst = &statics->instances[0]; *inst; inst++)
517 (*inst)->class_pointer = class;
521 if (module_initialized)
523 /* Remove this module from the uninitialized list. */
524 struct objc_list *this = *cell;
525 *cell = this->tail;
526 objc_free (this);
528 else
529 cell = &(*cell)->tail;
532 objc_mutex_unlock (__objc_runtime_mutex);
533 } /* objc_init_statics */
535 /* This function is called by constructor functions generated for each
536 module compiled. (_GLOBAL_$I$...) The purpose of this function is
537 to gather the module pointers so that they may be processed by the
538 initialization routines as soon as possible. */
540 void
541 __objc_exec_class (Module_t module)
543 /* Have we processed any constructors previously? This flag is used to
544 indicate that some global data structures need to be built. */
545 static BOOL previous_constructors = 0;
547 static struct objc_list *unclaimed_categories = 0;
549 /* The symbol table (defined in objc-api.h) generated by gcc */
550 Symtab_t symtab = module->symtab;
552 /* The statics in this module */
553 struct objc_static_instances **statics
554 = symtab->defs[symtab->cls_def_cnt + symtab->cat_def_cnt];
556 /* Entry used to traverse hash lists */
557 struct objc_list **cell;
559 /* The table of selector references for this module */
560 SEL selectors = symtab->refs;
562 /* dummy counter */
563 int i;
565 DEBUG_PRINTF ("received module: %s\n", module->name);
567 /* check gcc version */
568 init_check_module_version (module);
570 /* On the first call of this routine, initialize some data structures. */
571 if (! previous_constructors)
573 /* Initialize thread-safe system */
574 __objc_init_thread_system ();
575 __objc_runtime_threads_alive = 1;
576 __objc_runtime_mutex = objc_mutex_allocate ();
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;
591 /* Save the module pointer for later processing. (not currently used) */
592 objc_mutex_lock (__objc_runtime_mutex);
593 __objc_module_list = list_cons (module, __objc_module_list);
595 /* Replace referenced selectors from names to SEL's. */
596 if (selectors)
598 for (i = 0; selectors[i].sel_id; ++i)
600 const char *name, *type;
601 name = (char *) selectors[i].sel_id;
602 type = (char *) selectors[i].sel_types;
603 /* Constructors are constant static data so we can safely store
604 pointers to them in the runtime structures. is_const == YES */
605 __sel_register_typed_name (name, type,
606 (struct objc_selector *) &(selectors[i]),
607 YES);
611 /* Parse the classes in the load module and gather selector information. */
612 DEBUG_PRINTF ("gathering selectors from module: %s\n", module->name);
613 for (i = 0; i < symtab->cls_def_cnt; ++i)
615 Class class = (Class) symtab->defs[i];
616 const char *superclass = (char *) class->super_class;
618 /* Make sure we have what we think. */
619 assert (CLS_ISCLASS (class));
620 assert (CLS_ISMETA (class->class_pointer));
621 DEBUG_PRINTF ("phase 1, processing class: %s\n", class->name);
623 /* Initialize the subclass list to be NULL.
624 In some cases it isn't and this crashes the program. */
625 class->subclass_list = NULL;
627 __objc_init_class (class);
629 /* Check to see if the superclass is known in this point. If it's not
630 add the class to the unresolved_classes list. */
631 if (superclass && ! objc_lookup_class (superclass))
632 unresolved_classes = list_cons (class, unresolved_classes);
635 /* Process category information from the module. */
636 for (i = 0; i < symtab->cat_def_cnt; ++i)
638 Category_t category = symtab->defs[i + symtab->cls_def_cnt];
639 Class class = objc_lookup_class (category->class_name);
641 /* If the class for the category exists then append its methods. */
642 if (class)
645 DEBUG_PRINTF ("processing categories from (module,object): %s, %s\n",
646 module->name,
647 class->name);
649 /* Do instance methods. */
650 if (category->instance_methods)
651 class_add_method_list (class, category->instance_methods);
653 /* Do class methods. */
654 if (category->class_methods)
655 class_add_method_list ((Class) class->class_pointer,
656 category->class_methods);
658 if (category->protocols)
660 __objc_init_protocols (category->protocols);
661 __objc_class_add_protocols (class, category->protocols);
664 /* Register the instance methods as class methods, this is
665 only done for root classes. */
666 __objc_register_instance_methods_to_class (class);
668 else
670 /* The object to which the category methods belong can't be found.
671 Save the information. */
672 unclaimed_categories = list_cons (category, unclaimed_categories);
676 if (statics)
677 uninitialized_statics = list_cons (statics, uninitialized_statics);
678 if (uninitialized_statics)
679 objc_init_statics ();
681 /* Scan the unclaimed category hash. Attempt to attach any unclaimed
682 categories to objects. */
683 for (cell = &unclaimed_categories; *cell; )
685 Category_t category = (*cell)->head;
686 Class class = objc_lookup_class (category->class_name);
688 if (class)
690 DEBUG_PRINTF ("attaching stored categories to object: %s\n",
691 class->name);
693 list_remove_head (cell);
695 if (category->instance_methods)
696 class_add_method_list (class, category->instance_methods);
698 if (category->class_methods)
699 class_add_method_list ((Class) class->class_pointer,
700 category->class_methods);
702 if (category->protocols)
704 __objc_init_protocols (category->protocols);
705 __objc_class_add_protocols (class, category->protocols);
708 /* Register the instance methods as class methods, this is
709 only done for root classes. */
710 __objc_register_instance_methods_to_class (class);
712 else
713 cell = &(*cell)->tail;
716 if (unclaimed_proto_list && objc_lookup_class ("Protocol"))
718 list_mapcar (unclaimed_proto_list,
719 (void (*) (void *))__objc_init_protocols);
720 list_free (unclaimed_proto_list);
721 unclaimed_proto_list = 0;
724 objc_send_load ();
726 objc_mutex_unlock (__objc_runtime_mutex);
729 static void
730 objc_send_load (void)
732 if (! __objc_module_list)
733 return;
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)
741 Class class = unresolved_classes->head;
743 while (objc_lookup_class ((char *) class->super_class))
745 list_remove_head (&unresolved_classes);
746 if (unresolved_classes)
747 class = unresolved_classes->head;
748 else
749 break;
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;
759 /* Special check. If 'Object', which is used by meta-classes, has
760 not been loaded yet, delay sending of +load. */
761 if (! objc_lookup_class ("Object"))
762 return;
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);
770 while (__objc_class_tree_list)
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);
783 list_mapcar (__objc_module_list, (void (*) (void *)) __objc_call_callback);
784 list_free (__objc_module_list);
785 __objc_module_list = NULL;
788 static void
789 __objc_create_classes_tree (Module_t module)
791 /* The runtime mutex is locked in this point */
793 Symtab_t symtab = module->symtab;
794 int i;
796 /* Iterate thru classes defined in this module and insert them in
797 the classes tree hierarchy. */
798 for (i = 0; i < symtab->cls_def_cnt; i++)
800 Class class = (Class) symtab->defs[i];
802 objc_tree_insert_class (class);
806 static void
807 __objc_call_callback (Module_t module)
809 /* The runtime mutex is locked in this point. */
811 Symtab_t symtab = module->symtab;
812 int i;
814 /* Iterate thru classes defined in this module and call the callback
815 for each one. */
816 for (i = 0; i < symtab->cls_def_cnt; i++)
818 Class class = (Class) symtab->defs[i];
820 /* Call the _objc_load_callback for this class. */
821 if (_objc_load_callback)
822 _objc_load_callback (class, 0);
825 /* Call the _objc_load_callback for categories. Don't register the
826 instance methods as class methods for categories to root classes
827 since they were already added in the class. */
828 for (i = 0; i < symtab->cat_def_cnt; i++)
830 Category_t category = symtab->defs[i + symtab->cls_def_cnt];
831 Class class = objc_lookup_class (category->class_name);
833 if (_objc_load_callback)
834 _objc_load_callback (class, category);
838 /* Sanity check the version of gcc used to compile `module'. */
840 static void
841 init_check_module_version (Module_t module)
843 if ((module->version != OBJC_VERSION) || (module->size != sizeof (Module)))
845 _objc_abort ("Module %s version %d doesn't match runtime %d\n",
846 module->name, (int)module->version, OBJC_VERSION);
850 /* __objc_init_class must be called with __objc_runtime_mutex already locked. */
851 void
852 __objc_init_class (Class class)
854 /* Store the class in the class table and assign class numbers. */
855 __objc_add_class_to_hash (class);
857 /* Register all of the selectors in the class and meta class. */
858 __objc_register_selectors_from_class (class);
859 __objc_register_selectors_from_class ((Class) class->class_pointer);
861 /* Install the fake dispatch tables */
862 __objc_install_premature_dtable (class);
863 __objc_install_premature_dtable (class->class_pointer);
865 /* Register the instance methods as class methods, this is only done
866 for root classes. */
867 __objc_register_instance_methods_to_class (class);
869 if (class->protocols)
870 __objc_init_protocols (class->protocols);
873 /* __objc_init_protocol must be called with __objc_runtime_mutex
874 already locked, and the "Protocol" class already registered. */
875 static void
876 __objc_init_protocol (struct objc_protocol *protocol)
878 static Class proto_class = 0;
880 if (! proto_class)
881 proto_class = objc_get_class ("Protocol");
883 if (((size_t)protocol->class_pointer) == PROTOCOL_VERSION)
885 /* Assign class pointer */
886 protocol->class_pointer = proto_class;
888 /* Register all the selectors in the protocol with the runtime.
889 This both registers the selectors with the right types, and
890 it also fixes up the 'struct objc_method' structures inside
891 the protocol so that each method_name (a char * as compiled
892 by the compiler) is replaced with the appropriate runtime
893 SEL. */
894 if (protocol->class_methods)
895 __objc_register_selectors_from_description_list (protocol->class_methods);
897 if (protocol->instance_methods)
898 __objc_register_selectors_from_description_list (protocol->instance_methods);
900 /* Register the protocol in the hashtable or protocols by
901 name. */
902 __objc_protocols_add_protocol (protocol->protocol_name, protocol);
904 /* Init super protocols */
905 __objc_init_protocols (protocol->protocol_list);
907 else if (protocol->class_pointer != proto_class)
909 _objc_abort ("Version %d doesn't match runtime protocol version %d\n",
910 (int) ((char *) protocol->class_pointer
911 - (char *) 0),
912 PROTOCOL_VERSION);
916 static void
917 __objc_init_protocols (struct objc_protocol_list *protos)
919 size_t i;
920 static Class proto_class = 0;
922 if (! protos)
923 return;
925 objc_mutex_lock (__objc_runtime_mutex);
927 if (! proto_class)
928 proto_class = objc_lookup_class ("Protocol");
930 if (! proto_class)
932 unclaimed_proto_list = list_cons (protos, unclaimed_proto_list);
933 objc_mutex_unlock (__objc_runtime_mutex);
934 return;
937 #if 0
938 assert (protos->next == 0); /* only single ones allowed */
939 #endif
941 for (i = 0; i < protos->count; i++)
943 struct objc_protocol *aProto = protos->list[i];
944 __objc_init_protocol (aProto);
947 objc_mutex_unlock (__objc_runtime_mutex);
950 static void
951 __objc_class_add_protocols (Class class, struct objc_protocol_list *protos)
953 /* Well... */
954 if (! protos)
955 return;
957 /* Add it... */
958 protos->next = class->protocols;
959 class->protocols = protos;