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"
35 #include "objc-private/objc-sync.h" /* For __objc_sync_init() */
36 #include "objc-private/protocols.h" /* For __objc_protocols_init(),
37 __objc_protocols_add_protocol()
38 __objc_protocols_register_selectors() */
39 #include "objc-private/accessors.h" /* For __objc_accessors_init() */
41 /* The version number of this runtime. This must match the number
42 defined in gcc (objc-act.c). */
43 #define OBJC_VERSION 8
44 #define PROTOCOL_VERSION 2
46 /* This list contains all modules currently loaded into the
48 static struct objc_list *__objc_module_list = 0; /* !T:MUTEX */
50 /* This list contains all proto_list's not yet assigned class
52 static struct objc_list *unclaimed_proto_list = 0; /* !T:MUTEX */
54 /* List of unresolved static instances. */
55 static struct objc_list *uninitialized_statics = 0; /* !T:MUTEX */
57 /* Global runtime "write" mutex. Having a single mutex prevents
58 deadlocks, but reduces concurrency. To improve concurrency, some
59 groups of functions in the runtime have their own separate mutex
60 (eg, __class_table_lock in class.c); to avoid deadlocks, these
61 routines must make sure that they never acquire any other lock
62 while holding their own local lock. Ie, they should lock, execute
63 some C code that does not perform any calls to other runtime
64 functions which may potentially lock different locks, then unlock.
65 If they need to perform any calls to other runtime functions that
66 may potentially lock other locks, then they should use the global
67 __objc_runtime_mutex. */
68 objc_mutex_t __objc_runtime_mutex = 0;
70 /* Number of threads that are alive. */
71 int __objc_runtime_threads_alive = 1; /* !T:MUTEX */
73 /* Check compiler vs runtime version. */
74 static void init_check_module_version (struct objc_module *);
76 /* Assign isa links to protos. */
77 static void __objc_init_protocols (struct objc_protocol_list *protos);
79 /* Assign isa link to a protocol, and register it. */
80 static void __objc_init_protocol (struct objc_protocol *protocol);
82 /* Add protocol to class. */
83 static void __objc_class_add_protocols (Class, struct objc_protocol_list *);
85 /* This is a hook which is called by __objc_exec_class every time a
86 class or a category is loaded into the runtime. This may e.g. help
87 a dynamic loader determine the classes that have been loaded when
88 an object file is dynamically linked in. */
89 /* TODO: This needs to be declared in a public file with the new API. */
90 void (*_objc_load_callback) (Class class, struct objc_category *category); /* !T:SAFE */
92 /* Are all categories/classes resolved? */
93 BOOL __objc_dangling_categories = NO; /* !T:UNUSED */
95 /* TODO: This needs to go into objc-private/selector.h. */
97 __sel_register_typed_name (const char *name, const char *types,
98 struct objc_selector *orig, BOOL is_const);
100 /* Sends +load to all classes and categories in certain
102 static void objc_send_load (void);
104 /* Inserts all the classes defined in module in a tree of classes that
105 resembles the class hierarchy. This tree is traversed in preorder
106 and the classes in its nodes receive the +load message if these
107 methods were not executed before. The algorithm ensures that when
108 the +load method of a class is executed all the superclasses have
109 been already received the +load message. */
110 static void __objc_create_classes_tree (struct objc_module *module);
112 static void __objc_call_callback (struct objc_module *module);
114 /* A special version that works only before the classes are completely
115 installed in the runtime. */
116 static BOOL class_is_subclass_of_class (Class class, Class superclass);
118 typedef struct objc_class_tree {
120 struct objc_list *subclasses; /* `head' is pointer to an objc_class_tree */
123 /* This is a linked list of objc_class_tree trees. The head of these
124 trees are root classes (their super class is Nil). These different
125 trees represent different class hierarchies. */
126 static struct objc_list *__objc_class_tree_list = NULL;
128 /* Keeps the +load methods who have been already executed. This hash
129 should not be destroyed during the execution of the program. */
130 static cache_ptr __objc_load_methods = NULL;
132 /* This function is used when building the class tree used to send
133 ordinately the +load message to all classes needing it. The tree
134 is really needed so that superclasses will get the message before
137 This tree will contain classes which are being loaded (or have just
138 being loaded), and whose super_class pointers have not yet been
139 resolved. This implies that their super_class pointers point to a
140 string with the name of the superclass; when the first message is
141 sent to the class (/an object of that class) the class links will
142 be resolved, which will replace the super_class pointers with
143 pointers to the actual superclasses.
145 Unfortunately, the tree might also contain classes which had been
146 loaded previously, and whose class links have already been
149 This function returns the superclass of a class in both cases, and
150 can be used to build the determine the class relationships while
151 building the tree. */
152 static Class class_superclass_of_class (Class class)
154 char *super_class_name;
156 /* If the class links have been resolved, use the resolved
158 if (CLS_ISRESOLV (class))
159 return class->super_class;
161 /* Else, 'class' has not yet been resolved. This means that its
162 super_class pointer is really the name of the super class (rather
163 than a pointer to the actual superclass). */
164 super_class_name = (char *)class->super_class;
166 /* Return Nil for a root class. */
167 if (super_class_name == NULL)
170 /* Lookup the superclass of non-root classes. */
171 return objc_getClass (super_class_name);
175 /* Creates a tree of classes whose topmost class is directly inherited
176 from `upper' and the bottom class in this tree is
177 `bottom_class'. The classes in this tree are super classes of
178 `bottom_class'. `subclasses' member of each tree node point to the
179 next subclass tree node. */
180 static objc_class_tree *
181 create_tree_of_subclasses_inherited_from (Class bottom_class, Class upper)
184 objc_class_tree *tree, *prev;
186 if (bottom_class->super_class)
187 superclass = objc_getClass ((char *) bottom_class->super_class);
191 DEBUG_PRINTF ("create_tree_of_subclasses_inherited_from:");
192 DEBUG_PRINTF ("bottom_class = %s, upper = %s\n",
193 (bottom_class ? bottom_class->name : NULL),
194 (upper ? upper->name : NULL));
196 tree = prev = objc_calloc (1, sizeof (objc_class_tree));
197 prev->class = bottom_class;
199 while (superclass != upper)
201 tree = objc_calloc (1, sizeof (objc_class_tree));
202 tree->class = superclass;
203 tree->subclasses = list_cons (prev, tree->subclasses);
204 superclass = class_superclass_of_class (superclass);
211 /* Insert the `class' into the proper place in the `tree' class
212 hierarchy. This function returns a new tree if the class has been
213 successfully inserted into the tree or NULL if the class is not
214 part of the classes hierarchy described by `tree'. This function is
215 private to objc_tree_insert_class (), you should not call it
217 static objc_class_tree *
218 __objc_tree_insert_class (objc_class_tree *tree, Class class)
220 DEBUG_PRINTF ("__objc_tree_insert_class: tree = %x, class = %s\n",
224 return create_tree_of_subclasses_inherited_from (class, NULL);
225 else if (class == tree->class)
227 /* `class' has been already inserted. */
228 DEBUG_PRINTF ("1. class %s was previously inserted\n", class->name);
231 else if (class_superclass_of_class (class) == tree->class)
233 /* If class is a direct subclass of tree->class then add class
234 to the list of subclasses. First check to see if it wasn't
236 struct objc_list *list = tree->subclasses;
237 objc_class_tree *node;
241 /* Class has been already inserted; do nothing just return
243 if (((objc_class_tree *) list->head)->class == class)
245 DEBUG_PRINTF ("2. class %s was previously inserted\n",
252 /* Create a new node class and insert it into the list of
254 node = objc_calloc (1, sizeof (objc_class_tree));
256 tree->subclasses = list_cons (node, tree->subclasses);
257 DEBUG_PRINTF ("3. class %s inserted\n", class->name);
262 /* The class is not a direct subclass of tree->class. Search
263 for class's superclasses in the list of subclasses. */
264 struct objc_list *subclasses = tree->subclasses;
266 /* Precondition: the class must be a subclass of tree->class;
267 otherwise return NULL to indicate our caller that it must
268 take the next tree. */
269 if (! class_is_subclass_of_class (class, tree->class))
272 for (; subclasses != NULL; subclasses = subclasses->tail)
274 Class aClass = ((objc_class_tree *) (subclasses->head))->class;
276 if (class_is_subclass_of_class (class, aClass))
278 /* If we found one of class's superclasses we insert the
279 class into its subtree and return the original tree
280 since nothing has been changed. */
282 = __objc_tree_insert_class (subclasses->head, class);
283 DEBUG_PRINTF ("4. class %s inserted\n", class->name);
288 /* We haven't found a subclass of `class' in the `subclasses'
289 list. Create a new tree of classes whose topmost class is a
290 direct subclass of tree->class. */
292 objc_class_tree *new_tree
293 = create_tree_of_subclasses_inherited_from (class, tree->class);
294 tree->subclasses = list_cons (new_tree, tree->subclasses);
295 DEBUG_PRINTF ("5. class %s inserted\n", class->name);
301 /* This function inserts `class' in the right tree hierarchy classes. */
303 objc_tree_insert_class (Class class)
305 struct objc_list *list_node;
306 objc_class_tree *tree;
308 list_node = __objc_class_tree_list;
311 tree = __objc_tree_insert_class (list_node->head, class);
314 list_node->head = tree;
318 list_node = list_node->tail;
321 /* If the list was finished but the class hasn't been inserted,
325 __objc_class_tree_list = list_cons (NULL, __objc_class_tree_list);
326 __objc_class_tree_list->head = __objc_tree_insert_class (NULL, class);
330 /* Traverse tree in preorder. Used to send +load. */
332 objc_preorder_traverse (objc_class_tree *tree,
334 void (*function) (objc_class_tree *, int))
336 struct objc_list *node;
338 (*function) (tree, level);
339 for (node = tree->subclasses; node; node = node->tail)
340 objc_preorder_traverse (node->head, level + 1, function);
343 /* Traverse tree in postorder. Used to destroy a tree. */
345 objc_postorder_traverse (objc_class_tree *tree,
347 void (*function) (objc_class_tree *, int))
349 struct objc_list *node;
351 for (node = tree->subclasses; node; node = node->tail)
352 objc_postorder_traverse (node->head, level + 1, function);
353 (*function) (tree, level);
356 /* Used to print a tree class hierarchy. */
359 __objc_tree_print (objc_class_tree *tree, int level)
363 for (i = 0; i < level; i++)
365 printf ("%s\n", tree->class->name);
369 /* Walks on a linked list of methods in the reverse order and executes
370 all the methods corresponding to `op' selector. Walking in the
371 reverse order assures the +load of class is executed first and then
372 +load of categories because of the way in which categories are
373 added to the class methods. */
375 __objc_send_message_in_list (struct objc_method_list *method_list, Class class, SEL op)
382 /* First execute the `op' message in the following method lists. */
383 __objc_send_message_in_list (method_list->method_next, class, op);
385 /* Search the method list. */
386 for (i = 0; i < method_list->method_count; i++)
388 struct objc_method *mth = &method_list->method_list[i];
390 if (mth->method_name && sel_eq (mth->method_name, op)
391 && ! objc_hash_is_key_in_hash (__objc_load_methods, mth->method_imp))
393 /* Add this method into the +load hash table. */
394 objc_hash_add (&__objc_load_methods,
398 DEBUG_PRINTF ("sending +load in class: %s\n", class->name);
400 /* The method was found and wasn't previously executed. */
401 (*mth->method_imp) ((id)class, mth->method_name);
409 __objc_send_load (objc_class_tree *tree,
410 int level __attribute__ ((__unused__)))
412 static SEL load_sel = 0;
413 Class class = tree->class;
414 struct objc_method_list *method_list = class->class_pointer->methods;
417 load_sel = sel_registerName ("load");
419 __objc_send_message_in_list (method_list, class, load_sel);
423 __objc_destroy_class_tree_node (objc_class_tree *tree,
424 int level __attribute__ ((__unused__)))
429 /* This is used to check if the relationship between two classes
430 before the runtime completely installs the classes. */
432 class_is_subclass_of_class (Class class, Class superclass)
434 for (; class != Nil;)
436 if (class == superclass)
438 class = class_superclass_of_class (class);
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. */
449 extern void __objc_force_linking (void);
452 __objc_force_linking (void)
454 extern void __objc_linking (void);
458 /* Run through the statics list, removing modules as soon as all its
459 statics have been initialized. */
461 objc_init_statics (void)
463 struct objc_list **cell = &uninitialized_statics;
464 struct objc_static_instances **statics_in_module;
466 objc_mutex_lock (__objc_runtime_mutex);
470 int module_initialized = 1;
472 for (statics_in_module = (*cell)->head;
473 *statics_in_module; statics_in_module++)
475 struct objc_static_instances *statics = *statics_in_module;
476 Class class = objc_getClass (statics->class_name);
480 /* It is unfortunate that this will cause all the
481 statics initialization to be done again (eg, if we
482 already initialized constant strings, and are now
483 initializing protocols, setting module_initialized to
484 0 would cause constant strings to be initialized
485 again). It would be good to be able to track if we
486 have already initialized some of them. */
487 module_initialized = 0;
491 /* Note that if this is a list of Protocol objects, some
492 of them may have been initialized already (because
493 they were attached to classes or categories, and the
494 class/category loading code automatically fixes them
495 up), and some of them may not. We really need to go
496 through the whole list to be sure! Protocols are
497 also special because we want to register them and
498 register all their selectors. */
501 if (strcmp (statics->class_name, "Protocol") == 0)
503 /* Protocols are special, because not only we want
504 to fix up their class pointers, but we also want
505 to register them and their selectors with the
507 for (inst = &statics->instances[0]; *inst; inst++)
508 __objc_init_protocol ((struct objc_protocol *)*inst);
512 /* Other static instances (typically constant
513 strings) are easier as we just fix up their class
515 for (inst = &statics->instances[0]; *inst; inst++)
516 (*inst)->class_pointer = class;
520 if (module_initialized)
522 /* Remove this module from the uninitialized list. */
523 struct objc_list *this = *cell;
528 cell = &(*cell)->tail;
531 objc_mutex_unlock (__objc_runtime_mutex);
534 /* This function is called by constructor functions generated for each
535 module compiled. (_GLOBAL_$I$...) The purpose of this function is
536 to gather the module pointers so that they may be processed by the
537 initialization routines as soon as possible. */
539 __objc_exec_class (struct objc_module *module)
541 /* Have we processed any constructors previously? This flag is used
542 to indicate that some global data structures need to be
544 static BOOL previous_constructors = 0;
546 static struct objc_list *unclaimed_categories = 0;
548 /* The symbol table (defined in objc-private/module-abi-8.h)
550 struct objc_symtab *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;
564 DEBUG_PRINTF ("received module: %s\n", module->name);
566 /* Check gcc version. */
567 init_check_module_version (module);
569 /* On the first call of this routine, initialize some data
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,
585 __objc_protocols_init ();
586 __objc_accessors_init ();
588 previous_constructors = 1;
591 /* Save the module pointer for later processing. (not currently
593 objc_mutex_lock (__objc_runtime_mutex);
594 __objc_module_list = list_cons (module, __objc_module_list);
596 /* Replace referenced selectors from names to SEL's. */
599 for (i = 0; selectors[i].sel_id; ++i)
601 const char *name, *type;
602 name = (char *) selectors[i].sel_id;
603 type = (char *) selectors[i].sel_types;
604 /* Constructors are constant static data so we can safely
605 store pointers to them in the runtime
606 structures. is_const == YES. */
607 __sel_register_typed_name (name, type,
608 (struct objc_selector *) &(selectors[i]),
613 /* Parse the classes in the load module and gather selector
615 DEBUG_PRINTF ("gathering selectors from module: %s\n", module->name);
616 for (i = 0; i < symtab->cls_def_cnt; ++i)
618 Class class = (Class) symtab->defs[i];
619 const char *superclass = (char *) class->super_class;
621 /* Make sure we have what we think. */
622 assert (CLS_ISCLASS (class));
623 assert (CLS_ISMETA (class->class_pointer));
624 DEBUG_PRINTF ("phase 1, processing class: %s\n", class->name);
626 /* Initialize the subclass list to be NULL. In some cases it
627 isn't and this crashes the program. */
628 class->subclass_list = NULL;
630 __objc_init_class (class);
632 /* Check to see if the superclass is known in this point. If
633 it's not add the class to the unresolved_classes list. */
634 if (superclass && ! objc_getClass (superclass))
635 unresolved_classes = list_cons (class, unresolved_classes);
638 /* Process category information from the module. */
639 for (i = 0; i < symtab->cat_def_cnt; ++i)
641 struct objc_category *category = symtab->defs[i + symtab->cls_def_cnt];
642 Class class = objc_getClass (category->class_name);
644 /* If the class for the category exists then append its
649 DEBUG_PRINTF ("processing categories from (module,object): %s, %s\n",
653 /* Do instance methods. */
654 if (category->instance_methods)
655 class_add_method_list (class, category->instance_methods);
657 /* Do class methods. */
658 if (category->class_methods)
659 class_add_method_list ((Class) class->class_pointer,
660 category->class_methods);
662 if (category->protocols)
664 __objc_init_protocols (category->protocols);
665 __objc_class_add_protocols (class, category->protocols);
668 /* Register the instance methods as class methods, this is
669 only done for root classes. */
670 __objc_register_instance_methods_to_class (class);
674 /* The object to which the category methods belong can't be
675 found. Save the information. */
676 unclaimed_categories = list_cons (category, unclaimed_categories);
681 uninitialized_statics = list_cons (statics, uninitialized_statics);
682 if (uninitialized_statics)
683 objc_init_statics ();
685 /* Scan the unclaimed category hash. Attempt to attach any
686 unclaimed categories to objects. */
687 for (cell = &unclaimed_categories; *cell; )
689 struct objc_category *category = (*cell)->head;
690 Class class = objc_getClass (category->class_name);
694 DEBUG_PRINTF ("attaching stored categories to object: %s\n",
697 list_remove_head (cell);
699 if (category->instance_methods)
700 class_add_method_list (class, category->instance_methods);
702 if (category->class_methods)
703 class_add_method_list ((Class) class->class_pointer,
704 category->class_methods);
706 if (category->protocols)
708 __objc_init_protocols (category->protocols);
709 __objc_class_add_protocols (class, category->protocols);
712 /* Register the instance methods as class methods, this is
713 only done for root classes. */
714 __objc_register_instance_methods_to_class (class);
717 cell = &(*cell)->tail;
720 if (unclaimed_proto_list && objc_getClass ("Protocol"))
722 list_mapcar (unclaimed_proto_list,
723 (void (*) (void *))__objc_init_protocols);
724 list_free (unclaimed_proto_list);
725 unclaimed_proto_list = 0;
730 objc_mutex_unlock (__objc_runtime_mutex);
734 objc_send_load (void)
736 if (! __objc_module_list)
739 /* Try to find out if all the classes loaded so far also have their
740 superclasses known to the runtime. We suppose that the objects
741 that are allocated in the +load method are in general of a class
742 declared in the same module. */
743 if (unresolved_classes)
745 Class class = unresolved_classes->head;
747 while (objc_getClass ((char *) class->super_class))
749 list_remove_head (&unresolved_classes);
750 if (unresolved_classes)
751 class = unresolved_classes->head;
756 /* If we still have classes for whom we don't have yet their
757 super classes known to the runtime we don't send the +load
759 if (unresolved_classes)
763 /* Special check. If 'Object', which is used by meta-classes, has
764 not been loaded yet, delay sending of +load. */
765 if (! objc_getClass ("Object"))
768 /* Iterate over all modules in the __objc_module_list and call on
769 them the __objc_create_classes_tree function. This function
770 creates a tree of classes that resembles the class hierarchy. */
771 list_mapcar (__objc_module_list,
772 (void (*) (void *)) __objc_create_classes_tree);
774 while (__objc_class_tree_list)
777 objc_preorder_traverse (__objc_class_tree_list->head,
778 0, __objc_tree_print);
780 objc_preorder_traverse (__objc_class_tree_list->head,
781 0, __objc_send_load);
782 objc_postorder_traverse (__objc_class_tree_list->head,
783 0, __objc_destroy_class_tree_node);
784 list_remove_head (&__objc_class_tree_list);
787 list_mapcar (__objc_module_list, (void (*) (void *)) __objc_call_callback);
788 list_free (__objc_module_list);
789 __objc_module_list = NULL;
793 __objc_create_classes_tree (struct objc_module *module)
795 /* The runtime mutex is locked at this point */
796 struct objc_symtab *symtab = module->symtab;
799 /* Iterate thru classes defined in this module and insert them in
800 the classes tree hierarchy. */
801 for (i = 0; i < symtab->cls_def_cnt; i++)
803 Class class = (Class) symtab->defs[i];
805 objc_tree_insert_class (class);
810 __objc_call_callback (struct objc_module *module)
812 /* The runtime mutex is locked at this point. */
813 struct objc_symtab *symtab = module->symtab;
816 /* Iterate thru classes defined in this module and call the callback
818 for (i = 0; i < symtab->cls_def_cnt; i++)
820 Class class = (Class) symtab->defs[i];
822 /* Call the _objc_load_callback for this class. */
823 if (_objc_load_callback)
824 _objc_load_callback (class, 0);
827 /* Call the _objc_load_callback for categories. Don't register the
828 instance methods as class methods for categories to root classes
829 since they were already added in the class. */
830 for (i = 0; i < symtab->cat_def_cnt; i++)
832 struct objc_category *category = symtab->defs[i + symtab->cls_def_cnt];
833 Class class = objc_getClass (category->class_name);
835 if (_objc_load_callback)
836 _objc_load_callback (class, category);
840 /* Sanity check the version of gcc used to compile `module'. */
842 init_check_module_version (struct objc_module *module)
844 if ((module->version != OBJC_VERSION) || (module->size != sizeof (struct objc_module)))
846 _objc_abort ("Module %s version %d doesn't match runtime %d\n",
847 module->name, (int)module->version, OBJC_VERSION);
851 /* __objc_init_class must be called with __objc_runtime_mutex already locked. */
853 __objc_init_class (Class class)
855 /* Store the class in the class table and assign class numbers. */
856 __objc_add_class_to_hash (class);
858 /* Register all of the selectors in the class and meta class. */
859 __objc_register_selectors_from_class (class);
860 __objc_register_selectors_from_class ((Class) class->class_pointer);
862 /* Install the fake dispatch tables. */
863 __objc_install_premature_dtable (class);
864 __objc_install_premature_dtable (class->class_pointer);
866 /* Register the instance methods as class methods, this is only done
868 __objc_register_instance_methods_to_class (class);
870 if (class->protocols)
871 __objc_init_protocols (class->protocols);
874 /* __objc_init_protocol must be called with __objc_runtime_mutex
875 already locked, and the "Protocol" class already registered. */
877 __objc_init_protocol (struct objc_protocol *protocol)
879 static Class proto_class = 0;
882 proto_class = objc_getClass ("Protocol");
884 if (((size_t)protocol->class_pointer) == PROTOCOL_VERSION)
886 /* Assign class pointer. */
887 protocol->class_pointer = proto_class;
889 /* Register all the selectors in the protocol with the runtime.
890 This both registers the selectors with the right types, and
891 it also fixes up the 'struct objc_method' structures inside
892 the protocol so that each method_name (a char * as compiled
893 by the compiler) is replaced with the appropriate runtime
895 if (protocol->class_methods)
896 __objc_register_selectors_from_description_list (protocol->class_methods);
898 if (protocol->instance_methods)
899 __objc_register_selectors_from_description_list (protocol->instance_methods);
901 /* Register the protocol in the hashtable or protocols by
903 __objc_protocols_add_protocol (protocol->protocol_name, protocol);
905 /* Init super protocols. */
906 __objc_init_protocols (protocol->protocol_list);
908 else if (protocol->class_pointer != proto_class)
910 _objc_abort ("Version %d doesn't match runtime protocol version %d\n",
911 (int) ((char *) protocol->class_pointer
918 __objc_init_protocols (struct objc_protocol_list *protos)
921 static Class proto_class = 0;
926 objc_mutex_lock (__objc_runtime_mutex);
929 proto_class = objc_getClass ("Protocol");
933 unclaimed_proto_list = list_cons (protos, unclaimed_proto_list);
934 objc_mutex_unlock (__objc_runtime_mutex);
939 assert (protos->next == 0); /* Only single ones allowed. */
942 for (i = 0; i < protos->count; i++)
944 struct objc_protocol *aProto = protos->list[i];
945 __objc_init_protocol (aProto);
948 objc_mutex_unlock (__objc_runtime_mutex);
952 __objc_class_add_protocols (Class class, struct objc_protocol_list *protos)
957 protos->next = class->protocols;
958 class->protocols = protos;