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 runtime. */
47 static struct objc_list *__objc_module_list = 0; /* !T:MUTEX */
49 /* This list contains all proto_list's not yet assigned class links. */
50 static struct objc_list *unclaimed_proto_list = 0; /* !T:MUTEX */
52 /* List of unresolved static instances. */
53 static struct objc_list *uninitialized_statics = 0; /* !T:MUTEX */
55 /* Global runtime "write" mutex. Having a single mutex prevents
56 deadlocks, but reduces concurrency. To improve concurrency, some
57 groups of functions in the runtime have their own separate mutex
58 (eg, __class_table_lock in class.c); to avoid deadlocks, these
59 routines must make sure that they never acquire any other lock
60 while holding their own local lock. Ie, they should lock, execute
61 some C code that does not perform any calls to other runtime
62 functions which may potentially lock different locks, then unlock.
63 If they need to perform any calls to other runtime functions that
64 may potentially lock other locks, then they should use the global
65 __objc_runtime_mutex. */
66 objc_mutex_t __objc_runtime_mutex = 0;
68 /* Number of threads that are alive. */
69 int __objc_runtime_threads_alive = 1; /* !T:MUTEX */
71 /* Check compiler vs runtime version. */
72 static void init_check_module_version (struct objc_module *);
74 /* Assign isa links to protos. */
75 static void __objc_init_protocols (struct objc_protocol_list *protos);
77 /* Assign isa link to a protocol, and register it. */
78 static void __objc_init_protocol (struct objc_protocol *protocol);
80 /* Add protocol to class. */
81 static void __objc_class_add_protocols (Class, struct objc_protocol_list *);
83 /* This is a hook which is called by __objc_exec_class every time a
84 class or a category is loaded into the runtime. This may e.g. help
85 a dynamic loader determine the classes that have been loaded when
86 an object file is dynamically linked in. */
87 /* TODO: This needs to be declared in a public file with the new API. */
88 void (*_objc_load_callback) (Class class, struct objc_category *category); /* !T:SAFE */
90 /* Are all categories/classes resolved? */
91 BOOL __objc_dangling_categories = NO; /* !T:UNUSED */
93 /* TODO: This needs to go into objc-private/selector.h. */
95 __sel_register_typed_name (const char *name, const char *types,
96 struct objc_selector *orig, BOOL is_const);
98 /* Sends +load to all classes and categories in certain situations. */
99 static void objc_send_load (void);
101 /* Inserts all the classes defined in module in a tree of classes that
102 resembles the class hierarchy. This tree is traversed in preorder
103 and the classes in its nodes receive the +load message if these
104 methods were not executed before. The algorithm ensures that when
105 the +load method of a class is executed all the superclasses have
106 been already received the +load message. */
107 static void __objc_create_classes_tree (struct objc_module *module);
109 static void __objc_call_callback (struct objc_module *module);
111 /* A special version that works only before the classes are completely
112 installed in the runtime. */
113 static BOOL class_is_subclass_of_class (Class class, Class superclass);
115 typedef struct objc_class_tree {
117 struct objc_list *subclasses; /* `head' is pointer to an objc_class_tree */
120 /* This is a linked list of objc_class_tree trees. The head of these
121 trees are root classes (their super class is Nil). These different
122 trees represent different class hierarchies. */
123 static struct objc_list *__objc_class_tree_list = NULL;
125 /* Keeps the +load methods who have been already executed. This hash
126 should not be destroyed during the execution of the program. */
127 static cache_ptr __objc_load_methods = NULL;
129 /* This function is used when building the class tree used to send
130 ordinately the +load message to all classes needing it. The tree
131 is really needed so that superclasses will get the message before
134 This tree will contain classes which are being loaded (or have just
135 being loaded), and whose super_class pointers have not yet been
136 resolved. This implies that their super_class pointers point to a
137 string with the name of the superclass; when the first message is
138 sent to the class (/an object of that class) the class links will
139 be resolved, which will replace the super_class pointers with
140 pointers to the actual superclasses.
142 Unfortunately, the tree might also contain classes which had been
143 loaded previously, and whose class links have already been
146 This function returns the superclass of a class in both cases, and
147 can be used to build the determine the class relationships while
150 static Class class_superclass_of_class (Class class)
152 char *super_class_name;
154 /* If the class links have been resolved, use the resolved
156 if (CLS_ISRESOLV (class))
157 return class->super_class;
159 /* Else, 'class' has not yet been resolved. This means that its
160 * super_class pointer is really the name of the super class (rather
161 * than a pointer to the actual superclass). */
162 super_class_name = (char *)class->super_class;
164 /* Return Nil for a root class. */
165 if (super_class_name == NULL)
168 /* Lookup the superclass of non-root classes. */
169 return objc_getClass (super_class_name);
173 /* Creates a tree of classes whose topmost class is directly inherited
174 from `upper' and the bottom class in this tree is
175 `bottom_class'. The classes in this tree are super classes of
176 `bottom_class'. `subclasses' member of each tree node point to the
177 next subclass tree node. */
179 static objc_class_tree *
180 create_tree_of_subclasses_inherited_from (Class bottom_class, Class upper)
183 objc_class_tree *tree, *prev;
185 if (bottom_class->super_class)
186 superclass = objc_getClass ((char *) bottom_class->super_class);
190 DEBUG_PRINTF ("create_tree_of_subclasses_inherited_from:");
191 DEBUG_PRINTF ("bottom_class = %s, upper = %s\n",
192 (bottom_class ? bottom_class->name : NULL),
193 (upper ? upper->name : NULL));
195 tree = prev = objc_calloc (1, sizeof (objc_class_tree));
196 prev->class = bottom_class;
198 while (superclass != upper)
200 tree = objc_calloc (1, sizeof (objc_class_tree));
201 tree->class = superclass;
202 tree->subclasses = list_cons (prev, tree->subclasses);
203 superclass = class_superclass_of_class (superclass);
210 /* Insert the `class' into the proper place in the `tree' class
211 hierarchy. This function returns a new tree if the class has been
212 successfully inserted into the tree or NULL if the class is not
213 part of the classes hierarchy described by `tree'. This function is
214 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 to the
234 list of subclasses. First check to see if it wasn't already
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 subclasses */
253 node = objc_calloc (1, sizeof (objc_class_tree));
255 tree->subclasses = list_cons (node, tree->subclasses);
256 DEBUG_PRINTF ("3. class %s inserted\n", class->name);
261 /* The class is not a direct subclass of tree->class. Search for
262 class's superclasses in the list of subclasses. */
263 struct objc_list *subclasses = tree->subclasses;
265 /* Precondition: the class must be a subclass of tree->class;
266 otherwise return NULL to indicate our caller that it must
267 take the next tree. */
268 if (! class_is_subclass_of_class (class, tree->class))
271 for (; subclasses != NULL; subclasses = subclasses->tail)
273 Class aClass = ((objc_class_tree *) (subclasses->head))->class;
275 if (class_is_subclass_of_class (class, aClass))
277 /* If we found one of class's superclasses we insert the
278 class into its subtree and return the original tree
279 since nothing has been changed. */
281 = __objc_tree_insert_class (subclasses->head, class);
282 DEBUG_PRINTF ("4. class %s inserted\n", class->name);
287 /* We haven't found a subclass of `class' in the `subclasses'
288 list. Create a new tree of classes whose topmost class is a
289 direct subclass of tree->class. */
291 objc_class_tree *new_tree
292 = create_tree_of_subclasses_inherited_from (class, tree->class);
293 tree->subclasses = list_cons (new_tree, tree->subclasses);
294 DEBUG_PRINTF ("5. class %s inserted\n", class->name);
300 /* 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. */
333 objc_preorder_traverse (objc_class_tree *tree,
335 void (*function) (objc_class_tree *, int))
337 struct objc_list *node;
339 (*function) (tree, level);
340 for (node = tree->subclasses; node; node = node->tail)
341 objc_preorder_traverse (node->head, level + 1, function);
344 /* Traverse tree in postorder. Used to destroy a tree. */
347 objc_postorder_traverse (objc_class_tree *tree,
349 void (*function) (objc_class_tree *, int))
351 struct objc_list *node;
353 for (node = tree->subclasses; node; node = node->tail)
354 objc_postorder_traverse (node->head, level + 1, function);
355 (*function) (tree, level);
358 /* Used to print a tree class hierarchy. */
362 __objc_tree_print (objc_class_tree *tree, int level)
366 for (i = 0; i < level; i++)
368 printf ("%s\n", tree->class->name);
372 /* Walks on a linked list of methods in the reverse order and executes
373 all the methods corresponding to `op' selector. Walking in the
374 reverse order assures the +load of class is executed first and then
375 +load of categories because of the way in which categories are
376 added to the class methods. */
379 __objc_send_message_in_list (struct objc_method_list *method_list, Class class, SEL op)
386 /* First execute the `op' message in the following method lists */
387 __objc_send_message_in_list (method_list->method_next, class, op);
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 if (mth->method_name && sel_eq (mth->method_name, op)
395 && ! objc_hash_is_key_in_hash (__objc_load_methods, mth->method_imp))
397 /* Add this method into the +load hash table */
398 objc_hash_add (&__objc_load_methods,
402 DEBUG_PRINTF ("sending +load in class: %s\n", class->name);
404 /* The method was found and wasn't previously executed. */
405 (*mth->method_imp) ((id)class, mth->method_name);
413 __objc_send_load (objc_class_tree *tree,
414 int level __attribute__ ((__unused__)))
416 static SEL load_sel = 0;
417 Class class = tree->class;
418 struct objc_method_list *method_list = class->class_pointer->methods;
421 load_sel = sel_registerName ("load");
423 __objc_send_message_in_list (method_list, class, load_sel);
427 __objc_destroy_class_tree_node (objc_class_tree *tree,
428 int level __attribute__ ((__unused__)))
433 /* This is used to check if the relationship between two classes
434 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. */
455 extern void __objc_force_linking (void);
458 __objc_force_linking (void)
460 extern void __objc_linking (void);
464 /* Run through the statics list, removing modules as soon as all its
465 statics have been initialized. */
468 objc_init_statics (void)
470 struct objc_list **cell = &uninitialized_statics;
471 struct objc_static_instances **statics_in_module;
473 objc_mutex_lock (__objc_runtime_mutex);
477 int module_initialized = 1;
479 for (statics_in_module = (*cell)->head;
480 *statics_in_module; statics_in_module++)
482 struct objc_static_instances *statics = *statics_in_module;
483 Class class = objc_getClass (statics->class_name);
487 /* It is unfortunate that this will cause all the
488 statics initialization to be done again (eg, if we
489 already initialized constant strings, and are now
490 initializing protocols, setting module_initialized to
491 0 would cause constant strings to be initialized
492 again). It would be good to be able to track if we
493 have already initialized some of them. */
494 module_initialized = 0;
498 /* Note that if this is a list of Protocol objects, some
499 of them may have been initialized already (because
500 they were attached to classes or categories, and the
501 class/category loading code automatically fixes them
502 up), and some of them may not. We really need to go
503 through the whole list to be sure! Protocols are
504 also special because we want to register them and
505 register all their selectors. */
508 if (strcmp (statics->class_name, "Protocol") == 0)
510 /* Protocols are special, because not only we want
511 to fix up their class pointers, but we also want
512 to register them and their selectors with the
514 for (inst = &statics->instances[0]; *inst; inst++)
515 __objc_init_protocol ((struct objc_protocol *)*inst);
519 /* Other static instances (typically constant strings) are
520 easier as we just fix up their class pointers. */
521 for (inst = &statics->instances[0]; *inst; inst++)
522 (*inst)->class_pointer = class;
526 if (module_initialized)
528 /* Remove this module from the uninitialized list. */
529 struct objc_list *this = *cell;
534 cell = &(*cell)->tail;
537 objc_mutex_unlock (__objc_runtime_mutex);
538 } /* objc_init_statics */
540 /* This function is called by constructor functions generated for each
541 module compiled. (_GLOBAL_$I$...) The purpose of this function is
542 to gather the module pointers so that they may be processed by the
543 initialization routines as soon as possible. */
545 __objc_exec_class (struct objc_module *module)
547 /* Have we processed any constructors previously? This flag is used
548 to indicate that some global data structures need to be
550 static BOOL previous_constructors = 0;
552 static struct objc_list *unclaimed_categories = 0;
554 /* The symbol table (defined in objc-private/module-abi-8.h)
556 struct objc_symtab *symtab = module->symtab;
558 /* The statics in this module. */
559 struct objc_static_instances **statics
560 = symtab->defs[symtab->cls_def_cnt + symtab->cat_def_cnt];
562 /* Entry used to traverse hash lists. */
563 struct objc_list **cell;
565 /* The table of selector references for this module. */
566 SEL selectors = symtab->refs;
571 DEBUG_PRINTF ("received module: %s\n", module->name);
573 /* check gcc version */
574 init_check_module_version (module);
576 /* On the first call of this routine, initialize some data structures. */
577 if (! previous_constructors)
579 /* Initialize thread-safe system */
580 __objc_init_thread_system ();
581 __objc_runtime_threads_alive = 1;
582 __objc_runtime_mutex = objc_mutex_allocate ();
584 __objc_init_selector_tables ();
585 __objc_init_class_tables ();
586 __objc_init_dispatch_tables ();
587 __objc_class_tree_list = list_cons (NULL, __objc_class_tree_list);
588 __objc_load_methods = objc_hash_new (128,
589 (hash_func_type)objc_hash_ptr,
591 __objc_protocols_init ();
592 __objc_accessors_init ();
594 previous_constructors = 1;
597 /* Save the module pointer for later processing. (not currently used) */
598 objc_mutex_lock (__objc_runtime_mutex);
599 __objc_module_list = list_cons (module, __objc_module_list);
601 /* Replace referenced selectors from names to SEL's. */
604 for (i = 0; selectors[i].sel_id; ++i)
606 const char *name, *type;
607 name = (char *) selectors[i].sel_id;
608 type = (char *) selectors[i].sel_types;
609 /* Constructors are constant static data so we can safely store
610 pointers to them in the runtime structures. is_const == YES */
611 __sel_register_typed_name (name, type,
612 (struct objc_selector *) &(selectors[i]),
617 /* Parse the classes in the load module and gather selector information. */
618 DEBUG_PRINTF ("gathering selectors from module: %s\n", module->name);
619 for (i = 0; i < symtab->cls_def_cnt; ++i)
621 Class class = (Class) symtab->defs[i];
622 const char *superclass = (char *) class->super_class;
624 /* Make sure we have what we think. */
625 assert (CLS_ISCLASS (class));
626 assert (CLS_ISMETA (class->class_pointer));
627 DEBUG_PRINTF ("phase 1, processing class: %s\n", class->name);
629 /* Initialize the subclass list to be NULL.
630 In some cases it isn't and this crashes the program. */
631 class->subclass_list = NULL;
633 __objc_init_class (class);
635 /* Check to see if the superclass is known in this point. If it's not
636 add the class to the unresolved_classes list. */
637 if (superclass && ! objc_getClass (superclass))
638 unresolved_classes = list_cons (class, unresolved_classes);
641 /* Process category information from the module. */
642 for (i = 0; i < symtab->cat_def_cnt; ++i)
644 struct objc_category *category = symtab->defs[i + symtab->cls_def_cnt];
645 Class class = objc_getClass (category->class_name);
647 /* If the class for the category exists then append its methods. */
651 DEBUG_PRINTF ("processing categories from (module,object): %s, %s\n",
655 /* Do instance methods. */
656 if (category->instance_methods)
657 class_add_method_list (class, category->instance_methods);
659 /* Do class methods. */
660 if (category->class_methods)
661 class_add_method_list ((Class) class->class_pointer,
662 category->class_methods);
664 if (category->protocols)
666 __objc_init_protocols (category->protocols);
667 __objc_class_add_protocols (class, category->protocols);
670 /* Register the instance methods as class methods, this is
671 only done for root classes. */
672 __objc_register_instance_methods_to_class (class);
676 /* The object to which the category methods belong can't be found.
677 Save the information. */
678 unclaimed_categories = list_cons (category, unclaimed_categories);
683 uninitialized_statics = list_cons (statics, uninitialized_statics);
684 if (uninitialized_statics)
685 objc_init_statics ();
687 /* Scan the unclaimed category hash. Attempt to attach any unclaimed
688 categories to objects. */
689 for (cell = &unclaimed_categories; *cell; )
691 struct objc_category *category = (*cell)->head;
692 Class class = objc_getClass (category->class_name);
696 DEBUG_PRINTF ("attaching stored categories to object: %s\n",
699 list_remove_head (cell);
701 if (category->instance_methods)
702 class_add_method_list (class, category->instance_methods);
704 if (category->class_methods)
705 class_add_method_list ((Class) class->class_pointer,
706 category->class_methods);
708 if (category->protocols)
710 __objc_init_protocols (category->protocols);
711 __objc_class_add_protocols (class, category->protocols);
714 /* Register the instance methods as class methods, this is
715 only done for root classes. */
716 __objc_register_instance_methods_to_class (class);
719 cell = &(*cell)->tail;
722 if (unclaimed_proto_list && objc_getClass ("Protocol"))
724 list_mapcar (unclaimed_proto_list,
725 (void (*) (void *))__objc_init_protocols);
726 list_free (unclaimed_proto_list);
727 unclaimed_proto_list = 0;
732 objc_mutex_unlock (__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
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 list_mapcar (__objc_module_list, (void (*) (void *)) __objc_call_callback);
790 list_free (__objc_module_list);
791 __objc_module_list = NULL;
795 __objc_create_classes_tree (struct objc_module *module)
797 /* The runtime mutex is locked in this point */
799 struct objc_symtab *symtab = module->symtab;
802 /* Iterate thru classes defined in this module and insert them in
803 the classes tree hierarchy. */
804 for (i = 0; i < symtab->cls_def_cnt; i++)
806 Class class = (Class) symtab->defs[i];
808 objc_tree_insert_class (class);
813 __objc_call_callback (struct objc_module *module)
815 /* The runtime mutex is locked in this point. */
817 struct objc_symtab *symtab = module->symtab;
820 /* Iterate thru classes defined in this module and call the callback
822 for (i = 0; i < symtab->cls_def_cnt; i++)
824 Class class = (Class) symtab->defs[i];
826 /* Call the _objc_load_callback for this class. */
827 if (_objc_load_callback)
828 _objc_load_callback (class, 0);
831 /* Call the _objc_load_callback for categories. Don't register the
832 instance methods as class methods for categories to root classes
833 since they were already added in the class. */
834 for (i = 0; i < symtab->cat_def_cnt; i++)
836 struct objc_category *category = symtab->defs[i + symtab->cls_def_cnt];
837 Class class = objc_getClass (category->class_name);
839 if (_objc_load_callback)
840 _objc_load_callback (class, category);
844 /* Sanity check the version of gcc used to compile `module'. */
847 init_check_module_version (struct objc_module *module)
849 if ((module->version != OBJC_VERSION) || (module->size != sizeof (struct objc_module)))
851 _objc_abort ("Module %s version %d doesn't match runtime %d\n",
852 module->name, (int)module->version, OBJC_VERSION);
856 /* __objc_init_class must be called with __objc_runtime_mutex already locked. */
858 __objc_init_class (Class class)
860 /* Store the class in the class table and assign class numbers. */
861 __objc_add_class_to_hash (class);
863 /* Register all of the selectors in the class and meta class. */
864 __objc_register_selectors_from_class (class);
865 __objc_register_selectors_from_class ((Class) class->class_pointer);
867 /* Install the fake dispatch tables */
868 __objc_install_premature_dtable (class);
869 __objc_install_premature_dtable (class->class_pointer);
871 /* Register the instance methods as class methods, this is only done
873 __objc_register_instance_methods_to_class (class);
875 if (class->protocols)
876 __objc_init_protocols (class->protocols);
879 /* __objc_init_protocol must be called with __objc_runtime_mutex
880 already locked, and the "Protocol" class already registered. */
882 __objc_init_protocol (struct objc_protocol *protocol)
884 static Class proto_class = 0;
887 proto_class = objc_getClass ("Protocol");
889 if (((size_t)protocol->class_pointer) == PROTOCOL_VERSION)
891 /* Assign class pointer */
892 protocol->class_pointer = proto_class;
894 /* Register all the selectors in the protocol with the runtime.
895 This both registers the selectors with the right types, and
896 it also fixes up the 'struct objc_method' structures inside
897 the protocol so that each method_name (a char * as compiled
898 by the compiler) is replaced with the appropriate runtime
900 if (protocol->class_methods)
901 __objc_register_selectors_from_description_list (protocol->class_methods);
903 if (protocol->instance_methods)
904 __objc_register_selectors_from_description_list (protocol->instance_methods);
906 /* Register the protocol in the hashtable or protocols by
908 __objc_protocols_add_protocol (protocol->protocol_name, protocol);
910 /* Init super protocols */
911 __objc_init_protocols (protocol->protocol_list);
913 else if (protocol->class_pointer != proto_class)
915 _objc_abort ("Version %d doesn't match runtime protocol version %d\n",
916 (int) ((char *) protocol->class_pointer
923 __objc_init_protocols (struct objc_protocol_list *protos)
926 static Class proto_class = 0;
931 objc_mutex_lock (__objc_runtime_mutex);
934 proto_class = objc_getClass ("Protocol");
938 unclaimed_proto_list = list_cons (protos, unclaimed_proto_list);
939 objc_mutex_unlock (__objc_runtime_mutex);
944 assert (protos->next == 0); /* only single ones allowed */
947 for (i = 0; i < protos->count; i++)
949 struct objc_protocol *aProto = protos->list[i];
950 __objc_init_protocol (aProto);
953 objc_mutex_unlock (__objc_runtime_mutex);
957 __objc_class_add_protocols (Class class, struct objc_protocol_list *protos)
964 protos->next = class->protocols;
965 class->protocols = protos;