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
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"
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 modules currently loaded into the runtime and
48 for which the +load method (and the load callback, if any) has not
50 static struct objc_list *__objc_module_list = 0; /* !T:MUTEX */
52 /* This list contains all proto_list's not yet assigned class
54 static struct objc_list *unclaimed_proto_list = 0; /* !T:MUTEX */
56 /* List of unresolved static instances. */
57 static struct objc_list *uninitialized_statics = 0; /* !T:MUTEX */
59 /* Global runtime "write" mutex. Having a single mutex prevents
60 deadlocks, but reduces concurrency. To improve concurrency, some
61 groups of functions in the runtime have their own separate mutex
62 (eg, __class_table_lock in class.c); to avoid deadlocks, these
63 routines must make sure that they never acquire any other lock
64 while holding their own local lock. Ie, they should lock, execute
65 some C code that does not perform any calls to other runtime
66 functions which may potentially lock different locks, then unlock.
67 If they need to perform any calls to other runtime functions that
68 may potentially lock other locks, then they should use the global
69 __objc_runtime_mutex. */
70 objc_mutex_t __objc_runtime_mutex = 0;
72 /* Number of threads that are alive. */
73 int __objc_runtime_threads_alive = 1; /* !T:MUTEX */
75 /* Check compiler vs runtime version. */
76 static void init_check_module_version (struct objc_module *);
78 /* Assign isa links to protos. */
79 static void __objc_init_protocols (struct objc_protocol_list *protos);
81 /* Assign isa link to a protocol, and register it. */
82 static void __objc_init_protocol (struct objc_protocol *protocol);
84 /* Add protocol to class. */
85 static void __objc_class_add_protocols (Class, struct objc_protocol_list *);
87 /* Load callback hook. */
88 void (*_objc_load_callback) (Class class, struct objc_category *category) = 0; /* !T:SAFE */
90 /* Are all categories/classes resolved? */
91 BOOL __objc_dangling_categories = NO; /* !T:UNUSED */
93 /* Sends +load to all classes and categories in certain
95 static void objc_send_load (void);
97 /* Inserts all the classes defined in module in a tree of classes that
98 resembles the class hierarchy. This tree is traversed in preorder
99 and the classes in its nodes receive the +load message if these
100 methods were not executed before. The algorithm ensures that when
101 the +load method of a class is executed all the superclasses have
102 been already received the +load message. */
103 static void __objc_create_classes_tree (struct objc_module *module);
105 /* Calls the _objc_load_callback for each class and category in the
106 module (if _objc_load_callback is not NULL). */
107 static void __objc_call_load_callback (struct objc_module *module);
109 /* A special version that works only before the classes are completely
110 installed in the runtime. */
111 static BOOL class_is_subclass_of_class (Class class, Class superclass);
113 typedef struct objc_class_tree {
115 struct objc_list *subclasses; /* `head' is pointer to an objc_class_tree */
118 /* This is a linked list of objc_class_tree trees. The head of these
119 trees are root classes (their super class is Nil). These different
120 trees represent different class hierarchies. */
121 static struct objc_list *__objc_class_tree_list = NULL;
123 /* Keeps the +load methods who have been already executed. This hash
124 should not be destroyed during the execution of the program. */
125 static cache_ptr __objc_load_methods = NULL;
127 /* This function is used when building the class tree used to send
128 ordinately the +load message to all classes needing it. The tree
129 is really needed so that superclasses will get the message before
132 This tree will contain classes which are being loaded (or have just
133 being loaded), and whose super_class pointers have not yet been
134 resolved. This implies that their super_class pointers point to a
135 string with the name of the superclass; when the first message is
136 sent to the class (/an object of that class) the class links will
137 be resolved, which will replace the super_class pointers with
138 pointers to the actual superclasses.
140 Unfortunately, the tree might also contain classes which had been
141 loaded previously, and whose class links have already been
144 This function returns the superclass of a class in both cases, and
145 can be used to build the determine the class relationships while
146 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
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)
165 /* Lookup the superclass of non-root classes. */
166 return objc_getClass (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. */
175 static objc_class_tree *
176 create_tree_of_subclasses_inherited_from (Class bottom_class, Class upper)
179 objc_class_tree *tree, *prev;
181 if (bottom_class->super_class)
182 superclass = objc_getClass ((char *) bottom_class->super_class);
186 DEBUG_PRINTF ("create_tree_of_subclasses_inherited_from:");
187 DEBUG_PRINTF ("bottom_class = %s, upper = %s\n",
188 (bottom_class ? bottom_class->name : NULL),
189 (upper ? upper->name : NULL));
191 tree = prev = objc_calloc (1, sizeof (objc_class_tree));
192 prev->class = bottom_class;
194 while (superclass != upper)
196 tree = objc_calloc (1, sizeof (objc_class_tree));
197 tree->class = superclass;
198 tree->subclasses = list_cons (prev, tree->subclasses);
199 superclass = class_superclass_of_class (superclass);
206 /* Insert the `class' into the proper place in the `tree' class
207 hierarchy. This function returns a new tree if the class has been
208 successfully inserted into the tree or NULL if the class is not
209 part of the classes hierarchy described by `tree'. This function is
210 private to objc_tree_insert_class (), you should not call it
212 static objc_class_tree *
213 __objc_tree_insert_class (objc_class_tree *tree, Class class)
215 DEBUG_PRINTF ("__objc_tree_insert_class: tree = %p, class = %s\n",
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);
226 else if (class_superclass_of_class (class) == tree->class)
228 /* If class is a direct subclass of tree->class then add class
229 to the list of subclasses. First check to see if it wasn't
231 struct objc_list *list = tree->subclasses;
232 objc_class_tree *node;
236 /* Class has been already inserted; do nothing just return
238 if (((objc_class_tree *) list->head)->class == class)
240 DEBUG_PRINTF ("2. class %s was previously inserted\n",
247 /* Create a new node class and insert it into the list of
249 node = objc_calloc (1, sizeof (objc_class_tree));
251 tree->subclasses = list_cons (node, tree->subclasses);
252 DEBUG_PRINTF ("3. class %s inserted\n", class->name);
257 /* The class is not a direct subclass of tree->class. Search
258 for class's superclasses in the list of subclasses. */
259 struct objc_list *subclasses = tree->subclasses;
261 /* Precondition: the class must be a subclass of tree->class;
262 otherwise return NULL to indicate our caller that it must
263 take the next tree. */
264 if (! class_is_subclass_of_class (class, tree->class))
267 for (; subclasses != NULL; subclasses = subclasses->tail)
269 Class aClass = ((objc_class_tree *) (subclasses->head))->class;
271 if (class_is_subclass_of_class (class, aClass))
273 /* If we found one of class's superclasses we insert the
274 class into its subtree and return the original tree
275 since nothing has been changed. */
277 = __objc_tree_insert_class (subclasses->head, class);
278 DEBUG_PRINTF ("4. class %s inserted\n", class->name);
283 /* We haven't found a subclass of `class' in the `subclasses'
284 list. Create a new tree of classes whose topmost class is a
285 direct subclass of tree->class. */
287 objc_class_tree *new_tree
288 = create_tree_of_subclasses_inherited_from (class, tree->class);
289 tree->subclasses = list_cons (new_tree, tree->subclasses);
290 DEBUG_PRINTF ("5. class %s inserted\n", class->name);
296 /* This function inserts `class' in the right tree hierarchy classes. */
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;
306 tree = __objc_tree_insert_class (list_node->head, class);
309 list_node->head = tree;
313 list_node = list_node->tail;
316 /* If the list was finished but the class hasn't been inserted,
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 objc_preorder_traverse (objc_class_tree *tree,
329 void (*function) (objc_class_tree *, int))
331 struct objc_list *node;
333 (*function) (tree, level);
334 for (node = tree->subclasses; node; node = node->tail)
335 objc_preorder_traverse (node->head, level + 1, function);
338 /* Traverse tree in postorder. Used to destroy a tree. */
340 objc_postorder_traverse (objc_class_tree *tree,
342 void (*function) (objc_class_tree *, int))
344 struct objc_list *node;
346 for (node = tree->subclasses; node; node = node->tail)
347 objc_postorder_traverse (node->head, level + 1, function);
348 (*function) (tree, level);
351 /* Used to print a tree class hierarchy. */
354 __objc_tree_print (objc_class_tree *tree, int level)
358 for (i = 0; i < level; i++)
360 printf ("%s\n", tree->class->name);
364 /* Walks on a linked list of methods in the reverse order and executes
365 all the methods corresponding to the `+load' selector. Walking in
366 the reverse order assures the +load of class is executed first and
367 then +load of categories because of the way in which categories are
368 added to the class methods. This function needs to be called with
369 the objc_runtime_mutex locked. */
371 __objc_send_load_using_method_list (struct objc_method_list *method_list, Class class)
373 static SEL load_selector = 0;
379 /* This needs no lock protection because we are called with the
380 objc_runtime_mutex locked. */
382 load_selector = sel_registerName ("load");
384 /* method_list is a linked list of method lists; since we're
385 executing in reverse order, we need to do the next list before we
387 __objc_send_load_using_method_list (method_list->method_next, class);
389 /* Search the method list. */
390 for (i = 0; i < method_list->method_count; i++)
392 struct objc_method *mth = &method_list->method_list[i];
394 /* We are searching for +load methods that we haven't executed
396 if (mth->method_name && sel_eq (mth->method_name, load_selector)
397 && ! objc_hash_is_key_in_hash (__objc_load_methods, mth->method_imp))
399 /* Add this method into the +load hash table, so we won't
400 execute it again next time. */
401 objc_hash_add (&__objc_load_methods,
405 DEBUG_PRINTF ("sending +load in class: %s\n", class->name);
408 (*mth->method_imp) ((id)class, mth->method_name);
415 /* This function needs to be called with the objc_runtime_mutex
418 __objc_send_load (objc_class_tree *tree,
419 int level __attribute__ ((__unused__)))
421 Class class = tree->class;
422 struct objc_method_list *method_list = class->class_pointer->methods;
424 __objc_send_load_using_method_list (method_list, class);
428 __objc_destroy_class_tree_node (objc_class_tree *tree,
429 int level __attribute__ ((__unused__)))
434 /* This is used to check if the relationship between two classes
435 before the runtime completely installs the classes. */
437 class_is_subclass_of_class (Class class, Class superclass)
439 for (; class != Nil;)
441 if (class == superclass)
443 class = class_superclass_of_class (class);
449 /* This list contains all the classes in the runtime system for whom
450 their superclasses are not yet known to the runtime. */
451 static struct objc_list *unresolved_classes = 0;
453 /* Extern function used to reference the Object class. */
454 extern void __objc_force_linking (void);
457 __objc_force_linking (void)
459 extern void __objc_linking (void);
463 /* Run through the statics list, removing modules as soon as all its
464 statics have been initialized. */
466 objc_init_statics (void)
468 struct objc_list **cell = &uninitialized_statics;
469 struct objc_static_instances **statics_in_module;
471 objc_mutex_lock (__objc_runtime_mutex);
475 int module_initialized = 1;
477 for (statics_in_module = (*cell)->head;
478 *statics_in_module; statics_in_module++)
480 struct objc_static_instances *statics = *statics_in_module;
481 Class class = objc_getClass (statics->class_name);
485 /* It is unfortunate that this will cause all the
486 statics initialization to be done again (eg, if we
487 already initialized constant strings, and are now
488 initializing protocols, setting module_initialized to
489 0 would cause constant strings to be initialized
490 again). It would be good to be able to track if we
491 have already initialized some of them. */
492 module_initialized = 0;
496 /* Note that if this is a list of Protocol objects, some
497 of them may have been initialized already (because
498 they were attached to classes or categories, and the
499 class/category loading code automatically fixes them
500 up), and some of them may not. We really need to go
501 through the whole list to be sure! Protocols are
502 also special because we want to register them and
503 register all their selectors. */
506 if (strcmp (statics->class_name, "Protocol") == 0)
508 /* Protocols are special, because not only we want
509 to fix up their class pointers, but we also want
510 to register them and their selectors with the
512 for (inst = &statics->instances[0]; *inst; inst++)
513 __objc_init_protocol ((struct objc_protocol *)*inst);
517 /* Other static instances (typically constant
518 strings) are easier as we just fix up their class
520 for (inst = &statics->instances[0]; *inst; inst++)
521 (*inst)->class_pointer = class;
525 if (module_initialized)
527 /* Remove this module from the uninitialized list. */
528 struct objc_list *this = *cell;
533 cell = &(*cell)->tail;
536 objc_mutex_unlock (__objc_runtime_mutex);
539 /* This function is called by constructor functions generated for each
540 module compiled. (_GLOBAL_$I$...) The purpose of this function is
541 to gather the module pointers so that they may be processed by the
542 initialization routines as soon as possible. */
544 __objc_exec_class (struct objc_module *module)
546 /* Have we processed any constructors previously? This flag is used
547 to indicate that some global data structures need to be
549 static BOOL previous_constructors = 0;
551 static struct objc_list *unclaimed_categories = 0;
553 /* The symbol table (defined in objc-private/module-abi-8.h)
555 struct objc_symtab *symtab = module->symtab;
557 /* The statics in this module. */
558 struct objc_static_instances **statics
559 = symtab->defs[symtab->cls_def_cnt + symtab->cat_def_cnt];
561 /* Entry used to traverse hash lists. */
562 struct objc_list **cell;
564 /* The table of selector references for this module. */
565 struct objc_selector *selectors = symtab->refs;
569 DEBUG_PRINTF ("received module: %s\n", module->name);
571 /* Check gcc version. */
572 init_check_module_version (module);
574 /* On the first call of this routine, initialize some data
576 if (! previous_constructors)
578 /* Initialize thread-safe system. */
579 __objc_init_thread_system ();
580 __objc_runtime_threads_alive = 1;
581 __objc_runtime_mutex = objc_mutex_allocate ();
583 __objc_init_selector_tables ();
584 __objc_init_class_tables ();
585 __objc_init_dispatch_tables ();
586 __objc_class_tree_list = list_cons (NULL, __objc_class_tree_list);
587 __objc_load_methods = objc_hash_new (128,
588 (hash_func_type)objc_hash_ptr,
590 __objc_protocols_init ();
591 __objc_accessors_init ();
593 previous_constructors = 1;
596 /* Save the module pointer so that later we remember to call +load
597 on all classes and categories on it. */
598 objc_mutex_lock (__objc_runtime_mutex);
599 __objc_module_list = list_cons (module, __objc_module_list);
601 /* Replace referenced selectors from names to SELs. */
603 __objc_register_selectors_from_module (selectors);
605 /* Parse the classes in the load module and gather selector
607 DEBUG_PRINTF ("gathering selectors from module: %s\n", module->name);
608 for (i = 0; i < symtab->cls_def_cnt; ++i)
610 Class class = (Class) symtab->defs[i];
611 const char *superclass = (char *) class->super_class;
613 /* Make sure we have what we think. */
614 assert (CLS_ISCLASS (class));
615 assert (CLS_ISMETA (class->class_pointer));
616 DEBUG_PRINTF ("phase 1, processing class: %s\n", class->name);
618 /* Initialize the subclass list to be NULL. In some cases it
619 isn't and this crashes the program. */
620 class->subclass_list = NULL;
622 __objc_init_class (class);
624 /* Check to see if the superclass is known in this point. If
625 it's not add the class to the unresolved_classes list. */
626 if (superclass && ! objc_getClass (superclass))
627 unresolved_classes = list_cons (class, unresolved_classes);
630 /* Process category information from the module. */
631 for (i = 0; i < symtab->cat_def_cnt; ++i)
633 struct objc_category *category = symtab->defs[i + symtab->cls_def_cnt];
634 Class class = objc_getClass (category->class_name);
636 /* If the class for the category exists then append its
641 DEBUG_PRINTF ("processing categories from (module,object): %s, %s\n",
645 /* Do instance methods. */
646 if (category->instance_methods)
647 class_add_method_list (class, category->instance_methods);
649 /* Do class methods. */
650 if (category->class_methods)
651 class_add_method_list ((Class) class->class_pointer,
652 category->class_methods);
654 if (category->protocols)
656 __objc_init_protocols (category->protocols);
657 __objc_class_add_protocols (class, category->protocols);
660 /* Register the instance methods as class methods, this is
661 only done for root classes. */
662 __objc_register_instance_methods_to_class (class);
666 /* The object to which the category methods belong can't be
667 found. Save the information. */
668 unclaimed_categories = list_cons (category, unclaimed_categories);
673 uninitialized_statics = list_cons (statics, uninitialized_statics);
674 if (uninitialized_statics)
675 objc_init_statics ();
677 /* Scan the unclaimed category hash. Attempt to attach any
678 unclaimed categories to objects. */
679 for (cell = &unclaimed_categories; *cell; )
681 struct objc_category *category = (*cell)->head;
682 Class class = objc_getClass (category->class_name);
686 DEBUG_PRINTF ("attaching stored categories to object: %s\n",
689 list_remove_head (cell);
691 if (category->instance_methods)
692 class_add_method_list (class, category->instance_methods);
694 if (category->class_methods)
695 class_add_method_list ((Class) class->class_pointer,
696 category->class_methods);
698 if (category->protocols)
700 __objc_init_protocols (category->protocols);
701 __objc_class_add_protocols (class, category->protocols);
704 /* Register the instance methods as class methods, this is
705 only done for root classes. */
706 __objc_register_instance_methods_to_class (class);
709 cell = &(*cell)->tail;
712 if (unclaimed_proto_list && objc_getClass ("Protocol"))
714 list_mapcar (unclaimed_proto_list,
715 (void (*) (void *))__objc_init_protocols);
716 list_free (unclaimed_proto_list);
717 unclaimed_proto_list = 0;
722 /* Check if there are no unresolved classes (ie, classes whose
723 superclass has not been loaded yet) and that the 'Object' class,
724 used as the class of classes, exist. If so, it is worth
725 "resolving the class links" at this point, which will setup all
726 the class/superclass pointers. */
727 if (!unresolved_classes && objc_getClass ("Object"))
728 __objc_resolve_class_links ();
730 objc_mutex_unlock (__objc_runtime_mutex);
733 /* This function needs to be called with the objc_runtime_mutex
736 objc_send_load (void)
738 if (!__objc_module_list)
741 /* Try to find out if all the classes loaded so far also have their
742 superclasses known to the runtime. We suppose that the objects
743 that are allocated in the +load method are in general of a class
744 declared in the same module. */
745 if (unresolved_classes)
747 Class class = unresolved_classes->head;
749 while (objc_getClass ((char *) class->super_class))
751 list_remove_head (&unresolved_classes);
752 if (unresolved_classes)
753 class = unresolved_classes->head;
758 /* If we still have classes for whom we don't have yet their
759 super classes known to the runtime we don't send the +load
760 messages (and call the load callback) yet. */
761 if (unresolved_classes)
765 /* Special check. If 'Object', which is used by meta-classes, has
766 not been loaded yet, delay sending of +load. */
767 if (! objc_getClass ("Object"))
770 /* Iterate over all modules in the __objc_module_list and call on
771 them the __objc_create_classes_tree function. This function
772 creates a tree of classes that resembles the class hierarchy. */
773 list_mapcar (__objc_module_list,
774 (void (*) (void *)) __objc_create_classes_tree);
776 while (__objc_class_tree_list)
779 objc_preorder_traverse (__objc_class_tree_list->head,
780 0, __objc_tree_print);
782 objc_preorder_traverse (__objc_class_tree_list->head,
783 0, __objc_send_load);
784 objc_postorder_traverse (__objc_class_tree_list->head,
785 0, __objc_destroy_class_tree_node);
786 list_remove_head (&__objc_class_tree_list);
789 /* For each module, call the _objc_load_callback if any is
791 list_mapcar (__objc_module_list, (void (*) (void *)) __objc_call_load_callback);
793 /* Empty the list of modules. */
794 list_free (__objc_module_list);
795 __objc_module_list = NULL;
799 __objc_create_classes_tree (struct objc_module *module)
801 /* The runtime mutex is locked at this point */
802 struct objc_symtab *symtab = module->symtab;
805 /* Iterate thru classes defined in this module and insert them in
806 the classes tree hierarchy. */
807 for (i = 0; i < symtab->cls_def_cnt; i++)
809 Class class = (Class) symtab->defs[i];
811 objc_tree_insert_class (class);
814 /* Now iterate over "claimed" categories too (ie, categories that
815 extend a class that has already been loaded by the runtime), and
816 insert them in the classes tree hiearchy too. Otherwise, if you
817 add a category, its +load method would not be called if the class
818 is already loaded in the runtime. It the category is
819 "unclaimed", ie, we haven't loaded the main class yet, postpone
820 sending +load as we want to execute +load from the class before
821 we execute the one from the category. */
822 for (i = 0; i < symtab->cat_def_cnt; ++i)
824 struct objc_category *category = symtab->defs[i + symtab->cls_def_cnt];
825 Class class = objc_getClass (category->class_name);
827 /* If the class for the category exists then append its
830 objc_tree_insert_class (class);
835 __objc_call_load_callback (struct objc_module *module)
837 if (_objc_load_callback)
839 /* The runtime mutex is locked at this point. */
840 struct objc_symtab *symtab = module->symtab;
843 /* Iterate thru classes defined in this module and call the callback
845 for (i = 0; i < symtab->cls_def_cnt; i++)
847 Class class = (Class) symtab->defs[i];
849 /* Call the _objc_load_callback for this class. */
850 _objc_load_callback (class, 0);
853 /* Call the _objc_load_callback for categories. Don't register
854 the instance methods as class methods for categories to root
855 classes since they were already added in the class. */
856 for (i = 0; i < symtab->cat_def_cnt; i++)
858 struct objc_category *category = symtab->defs[i + symtab->cls_def_cnt];
859 Class class = objc_getClass (category->class_name);
861 _objc_load_callback (class, category);
866 /* Sanity check the version of gcc used to compile `module'. */
868 init_check_module_version (struct objc_module *module)
870 if ((module->version != OBJC_VERSION) || (module->size != sizeof (struct objc_module)))
872 _objc_abort ("Module %s version %d doesn't match runtime %d\n",
873 module->name, (int)module->version, OBJC_VERSION);
877 /* __objc_init_class must be called with __objc_runtime_mutex already locked. */
879 __objc_init_class (Class class)
881 /* Store the class in the class table and assign class numbers. */
882 if (__objc_add_class_to_hash (class))
884 /* Register all of the selectors in the class and meta class. */
885 __objc_register_selectors_from_class (class);
886 __objc_register_selectors_from_class ((Class) class->class_pointer);
888 /* Install the fake dispatch tables. */
889 __objc_install_premature_dtable (class);
890 __objc_install_premature_dtable (class->class_pointer);
892 /* Register the instance methods as class methods, this is only
893 done for root classes. */
894 __objc_register_instance_methods_to_class (class);
896 if (class->protocols)
897 __objc_init_protocols (class->protocols);
900 _objc_abort ("Module contains duplicate class '%s'\n",
904 /* __objc_init_protocol must be called with __objc_runtime_mutex
905 already locked, and the "Protocol" class already registered. */
907 __objc_init_protocol (struct objc_protocol *protocol)
909 static Class proto_class = 0;
912 proto_class = objc_getClass ("Protocol");
914 if (((size_t)protocol->class_pointer) == PROTOCOL_VERSION)
916 /* Assign class pointer. */
917 protocol->class_pointer = proto_class;
919 /* Register all the selectors in the protocol with the runtime.
920 This both registers the selectors with the right types, and
921 it also fixes up the 'struct objc_method' structures inside
922 the protocol so that each method_name (a char * as compiled
923 by the compiler) is replaced with the appropriate runtime
925 if (protocol->class_methods)
926 __objc_register_selectors_from_description_list (protocol->class_methods);
928 if (protocol->instance_methods)
929 __objc_register_selectors_from_description_list (protocol->instance_methods);
931 /* Register the protocol in the hashtable or protocols by
933 __objc_protocols_add_protocol (protocol->protocol_name, protocol);
935 /* Init super protocols. */
936 __objc_init_protocols (protocol->protocol_list);
938 else if (protocol->class_pointer != proto_class)
940 _objc_abort ("Version %d doesn't match runtime protocol version %d\n",
941 (int) ((char *) protocol->class_pointer
948 __objc_init_protocols (struct objc_protocol_list *protos)
951 static Class proto_class = 0;
956 objc_mutex_lock (__objc_runtime_mutex);
959 proto_class = objc_getClass ("Protocol");
963 unclaimed_proto_list = list_cons (protos, unclaimed_proto_list);
964 objc_mutex_unlock (__objc_runtime_mutex);
969 assert (protos->next == 0); /* Only single ones allowed. */
972 for (i = 0; i < protos->count; i++)
974 struct objc_protocol *aProto = protos->list[i];
975 __objc_init_protocol (aProto);
978 objc_mutex_unlock (__objc_runtime_mutex);
982 __objc_class_add_protocols (Class class, struct objc_protocol_list *protos)
987 protos->next = class->protocols;
988 class->protocols = protos;