1 /* GNU Objective C Runtime initialization
2 Copyright (C) 1993, 1995, 1996, 1997 Free Software Foundation, Inc.
3 Contributed by Kresten Krab Thorup
4 +load support contributed by Ovidiu Predescu <ovidiu@net-community.com>
6 This file is part of GNU CC.
8 GNU CC is free software; you can redistribute it and/or modify it under the
9 terms of the GNU General Public License as published by the Free Software
10 Foundation; either version 2, or (at your option) any later version.
12 GNU CC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
17 You should have received a copy of the GNU General Public License along with
18 GNU CC; see the file COPYING. If not, write to the Free Software
19 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
21 /* As a special exception, if you link this library with files compiled with
22 GCC to produce an executable, this does not cause the resulting executable
23 to be covered by the GNU General Public License. This exception does not
24 however invalidate any other reasons why the executable file might be
25 covered by the GNU General Public License. */
30 /* The version number of this runtime. This must match the number
31 defined in gcc (objc-act.c) */
32 #define OBJC_VERSION 8 /* HH version 8 */
33 #define PROTOCOL_VERSION 2
35 /* Check compiler vs runtime version */
36 static void init_check_module_version (Module_t);
38 /* Assign isa links to protos */
39 static void __objc_init_protocols (struct objc_protocol_list* protos);
41 /* Add protocol to class */
42 static void __objc_class_add_protocols (Class, struct objc_protocol_list*);
45 __sel_register_typed_name (const char *name, const char *types,
46 struct objc_selector *orig, BOOL is_const);
48 /* Sends +load to all classes and categories in certain situations. */
49 static void objc_send_load (void);
51 /* Inserts all the classes defined in module in a tree of classes that
52 resembles the class hierarchy. This tree is traversed in preorder and the
53 classes in its nodes receive the +load message if these methods were not
54 executed before. The algorithm ensures that when the +load method of a class
55 is executed all the superclasses have been already received the +load
57 static void __objc_create_classes_tree (Module_t module);
59 static void __objc_call_callback (Module_t module);
61 /* A special version that works only before the classes are completely
62 installed in the runtime. */
63 static BOOL class_is_subclass_of_class (Class class, Class superclass);
65 typedef struct objc_class_tree {
67 struct objc_list *subclasses; /* `head' is pointer to an objc_class_tree */
70 /* Creates a tree of classes whose topmost class is directly inherited from
71 `upper' and the bottom class in this tree is `bottom_class'. The classes
72 in this tree are super classes of `bottom_class'. `subclasses' member
73 of each tree node point to the next subclass tree node. */
74 static objc_class_tree *
75 create_tree_of_subclasses_inherited_from (Class bottom_class, Class upper)
77 Class superclass = bottom_class->super_class ?
78 objc_lookup_class ((char*)bottom_class->super_class)
81 objc_class_tree *tree, *prev;
83 DEBUG_PRINTF ("create_tree_of_subclasses_inherited_from:");
84 DEBUG_PRINTF ("bottom_class = %s, upper = %s\n",
85 (bottom_class ? bottom_class->name : "<Nil>"),
86 (upper ? upper->name : "<Nil>"));
88 tree = prev = objc_calloc (1, sizeof (objc_class_tree));
89 prev->class = bottom_class;
91 while (superclass != upper)
93 tree = objc_calloc (1, sizeof (objc_class_tree));
94 tree->class = superclass;
95 tree->subclasses = list_cons (prev, tree->subclasses);
96 superclass = (superclass->super_class ?
97 objc_lookup_class ((char*)superclass->super_class)
105 /* Insert the `class' into the proper place in the `tree' class hierarchy. This
106 function returns a new tree if the class has been successfully inserted into
107 the tree or NULL if the class is not part of the classes hierarchy described
108 by `tree'. This function is private to objc_tree_insert_class(), you should
109 not call it directly. */
110 static objc_class_tree *
111 __objc_tree_insert_class (objc_class_tree *tree, Class class)
113 DEBUG_PRINTF ("__objc_tree_insert_class: tree = 0x%08X, class = %s\n",
114 (unsigned int)tree, class->name ? class->name : "<NoName>");
117 return create_tree_of_subclasses_inherited_from (class, NULL);
118 else if (class == tree->class)
120 /* `class' has been already inserted */
121 DEBUG_PRINTF ("1. class %s was previously inserted\n",
122 class->name ? class->name : "<NoName>");
125 else if ((class->super_class ?
126 objc_lookup_class ((char*)class->super_class)
130 /* If class is a direct subclass of tree->class then add class to the
131 list of subclasses. First check to see if it wasn't already
133 struct objc_list *list = tree->subclasses;
134 objc_class_tree *node;
138 /* Class has been already inserted; do nothing just return
140 if (((objc_class_tree*)list->head)->class == class)
142 DEBUG_PRINTF ("2. class %s was previously inserted\n",
143 class->name ? class->name : "<NoName>");
149 /* Create a new node class and insert it into the list of subclasses */
150 node = objc_calloc (1, sizeof (objc_class_tree));
152 tree->subclasses = list_cons (node, tree->subclasses);
153 DEBUG_PRINTF ("3. class %s inserted\n",
154 class->name ? class->name : "<NoName>");
159 /* The class is not a direct subclass of tree->class. Search for class's
160 superclasses in the list of subclasses. */
161 struct objc_list *subclasses = tree->subclasses;
163 /* Precondition: the class must be a subclass of tree->class; otherwise
164 return NULL to indicate our caller that it must take the next tree. */
165 if (!class_is_subclass_of_class (class, tree->class))
168 for (; subclasses != NULL; subclasses = subclasses->tail)
170 Class aClass = ((objc_class_tree*)(subclasses->head))->class;
172 if (class_is_subclass_of_class (class, aClass))
174 /* If we found one of class's superclasses we insert the class
175 into its subtree and return the original tree since nothing
178 = __objc_tree_insert_class (subclasses->head, class);
179 DEBUG_PRINTF ("4. class %s inserted\n",
180 class->name ? class->name : "<NoName>");
185 /* We haven't found a subclass of `class' in the `subclasses' list.
186 Create a new tree of classes whose topmost class is a direct subclass
189 objc_class_tree *new_tree
190 = create_tree_of_subclasses_inherited_from (class, tree->class);
191 tree->subclasses = list_cons (new_tree, tree->subclasses);
192 DEBUG_PRINTF ("5. class %s inserted\n",
193 class->name ? class->name : "<NoName>");
199 /* This function inserts `class' in the right tree hierarchy classes. */
201 objc_tree_insert_class (Class class)
203 struct objc_list *list_node;
204 objc_class_tree *tree;
206 list_node = __objc_class_tree_list;
209 tree = __objc_tree_insert_class (list_node->head, class);
212 list_node->head = tree;
216 list_node = list_node->tail;
219 /* If the list was finished but the class hasn't been inserted, insert it
223 __objc_class_tree_list = list_cons (NULL, __objc_class_tree_list);
224 __objc_class_tree_list->head = __objc_tree_insert_class (NULL, class);
228 /* Traverse tree in preorder. Used to send +load. */
230 objc_preorder_traverse (objc_class_tree *tree,
232 void (*function)(objc_class_tree*, int))
234 struct objc_list *node;
236 (*function) (tree, level);
237 for (node = tree->subclasses; node; node = node->tail)
238 objc_preorder_traverse (node->head, level + 1, function);
241 /* Traverse tree in postorder. Used to destroy a tree. */
243 objc_postorder_traverse (objc_class_tree *tree,
245 void (*function)(objc_class_tree*, int))
247 struct objc_list *node;
249 for (node = tree->subclasses; node; node = node->tail)
250 objc_postorder_traverse (node->head, level + 1, function);
251 (*function) (tree, level);
254 /* Used to print a tree class hierarchy. */
256 static void __objc_tree_print (objc_class_tree *tree, int level) {
259 for (i = 0; i < level; i++)
264 ? (tree->class->name ? tree->class->name : "<No Name>")
270 /* Walks on a linked list of methods in the reverse order and executes all
271 the methods corresponding to `op' selector. Walking in the reverse order
272 assures the +load of class is executed first and then +load of categories
273 because of the way in which categories are added to the class methods. */
275 __objc_send_message_in_list (MethodList_t method_list, Class class, SEL op)
282 /* First execute the `op' message in the following method lists */
283 __objc_send_message_in_list (method_list->method_next, class, op);
285 /* Search the method list. */
286 for (i = 0; i < method_list->method_count; i++) {
287 Method_t mth = &method_list->method_list[i];
289 if (mth->method_name && sel_eq (mth->method_name, op)
290 && !hash_is_key_in_hash (__objc_load_methods, mth->method_name))
292 /* The method was found and wasn't previously executed. */
293 (*mth->method_imp) ((id)class, mth->method_name);
295 /* Add this method into the +load hash table */
296 hash_add (&__objc_load_methods, mth->method_name, mth->method_imp);
298 DEBUG_PRINTF ("sending +load in class: %s\n",
299 class->name ? class->name : "<NoName>");
307 __objc_send_load (objc_class_tree *tree, int level)
309 static SEL load_sel = 0;
310 Class class = tree->class;
311 MethodList_t method_list = class->class_pointer->methods;
314 load_sel = sel_register_name ("load");
316 __objc_send_message_in_list (method_list, class, load_sel);
320 __objc_destroy_class_tree_node (objc_class_tree *tree, int level)
325 /* This is used to check if the relationship between two classes before the
326 runtime completely installs the classes. */
328 class_is_subclass_of_class (Class class, Class superclass)
330 for (; class != Nil;)
332 if (class == superclass)
334 class = (class->super_class ?
335 objc_lookup_class ((char*)class->super_class)
342 /* This list contains all the classes in the runtime system for whom their
343 superclasses are not yet know to the runtime. */
344 static struct objc_list* unresolved_classes = 0;
346 /* Static function used to reference the Object and NXConstantString classes.
349 __objc_force_linking (void)
351 extern void __objc_linking (void);
354 /* Call the function to avoid compiler warning */
355 __objc_force_linking ();
358 /* Run through the statics list, removing modules as soon as all its statics
359 have been initialized. */
361 objc_init_statics (void)
363 struct objc_list **cell = &__objc_uninitialized_statics;
364 struct objc_static_instances **statics_in_module;
370 int module_initialized = 1;
372 for (statics_in_module = (*cell)->head;
373 *statics_in_module; statics_in_module++)
375 struct objc_static_instances *statics = *statics_in_module;
376 Class class = objc_lookup_class (statics->class_name);
379 module_initialized = 0;
380 /* Actually, the static's class_pointer will be NULL when we
381 haven't been here before. However, the comparison is to be
382 reminded of taking into account class posing and to think about
383 possible semantics... */
384 else if (class != statics->instances[0]->class_pointer)
388 for (inst = &statics->instances[0]; *inst; inst++)
390 (*inst)->class_pointer = class;
392 /* ??? Make sure the object will not be freed. With
393 refcounting, invoke `-retain'. Without refcounting, do
394 nothing and hope that `-free' will never be invoked. */
396 /* ??? Send the object an `-initStatic' or something to
397 that effect now or later on? What are the semantics of
398 statically allocated instances, besides the trivial
399 NXConstantString, anyway? */
403 if (module_initialized)
405 /* Remove this module from the uninitialized list. */
406 struct objc_list *this = *cell;
411 cell = &(*cell)->tail;
415 } /* objc_init_statics */
417 /* This function is called by constructor functions generated for each
418 module compiled. (_GLOBAL_$I$...) The purpose of this function is to
419 gather the module pointers so that they may be processed by the
420 initialization routines as soon as possible */
422 int objc_moduleCount = 0;
423 int objc_classCount = 0;
424 int objc_categoryCount = 0;
426 objc_DECLARE void __objc_exec_module(Module_t module)
428 /* Have we processed any constructors previously? This flag is used to
429 indicate that some global data structures need to be built. */
430 static BOOL previous_constructors = 0;
432 static struct objc_list* unclaimed_categories = 0;
434 /* The symbol table (defined in objc-api.h) generated by gcc */
435 Symtab_t symtab = module->symtab;
437 /* The statics in this module */
438 struct objc_static_instances **statics
439 = symtab->defs[symtab->cls_def_cnt + symtab->cat_def_cnt];
441 /* Entry used to traverse hash lists */
442 struct objc_list** cell;
444 /* The table of selector references for this module */
445 SEL selectors = symtab->refs;
450 DEBUG_PRINTF ("received module: %s\n",
451 module->name ? module->name : "<NoName>");
453 /* check gcc version */
454 init_check_module_version(module);
456 /* On the first call of this routine, initialize some data structures. */
457 if (!previous_constructors)
459 /* Initialize thread-safe system */
460 __objc_init_thread_system();
461 __objc_runtime_threads_alive = 1;
462 __objc_runtime_mutex = objc_mutex_allocate();
463 if (__objc_runtime_mutex == NULL)
464 fprintf(stderr, "Could not allocate Objective-C runtime mutex.\n");
466 __objc_init_selector_tables();
467 __objc_init_class_tables();
468 __objc_init_dispatch_tables();
469 __objc_class_tree_list = list_cons (NULL, __objc_class_tree_list);
470 __objc_load_methods = ptrhash_new(128);
471 previous_constructors = 1;
476 /* Take a look whether module is already loaded. If a module is contained
477 in a shared library it can happen that the module constructor is executed
478 multiple times. Multiple execution of modules won't work since the runtime
479 replaces static information in the module (like selector names) with
480 dynamic one (eg dynamic selector ids ). */
482 register struct objc_list *l;
484 for (l = __objc_module_list; l; l = l->tail) {
485 if (l->head == module)
490 /* l is defined if module is already loaded */
491 fprintf(stderr, "module %s is already loaded !\n",
492 module->name ? module->name : "<no module name>");
498 __objc_module_list = list_cons(module, __objc_module_list);
501 /* Replace referenced selectors from names to SEL's. */
503 for (i = 0; selectors[i].sel_id; ++i) {
504 register const char *name, *type;
506 name = (char*)selectors[i].sel_id;
507 type = (char*)selectors[i].sel_types;
509 /* Constructors are constant static data so we can safely store
510 pointers to them in the runtime structures. is_const == YES */
511 __sel_register_typed_name(name, type,
512 (struct objc_selector*)&(selectors[i]),
517 /* Parse the classes in the load module and gather selector information. */
519 DEBUG_PRINTF ("gathering selectors from module: %s (#-of modules=%i)\n",
520 module->name ? module->name : "<NoName>", objc_moduleCount);
522 for (i = 0; i < symtab->cls_def_cnt; ++i) {
523 Class class = (Class) symtab->defs[i];
524 const char *superclass = (char *)class->super_class;
526 /* Make sure we have what we think. */
527 assert (CLS_ISCLASS(class));
528 assert (CLS_ISMETA(class->class_pointer));
529 DEBUG_PRINTF ("phase 1, processing class: %s (super=%s)\n",
530 class->name ? class->name : "<NoName>",
531 superclass ? superclass : "<Nil>");
533 /* Initialize the subclass list to be NULL.
534 In some cases it isn't and this crashes the program. */
535 class->subclass_list = NULL;
537 /* Store the class in the class table and assign class numbers. */
538 __objc_add_class_to_hash (class);
541 /* Register all of the selectors in the class and meta class. */
542 __objc_register_selectors_from_class (class);
543 __objc_register_selectors_from_class ((Class) class->class_pointer);
545 /* Install the fake dispatch tables */
546 class->dtable = NULL;
547 class->class_pointer->dtable = NULL;
549 /* Register the instance methods as class methods, this is
550 only done for root classes. */
551 __objc_register_instance_methods_to_class(class);
553 if (class->protocols)
554 __objc_init_protocols (class->protocols);
556 /* Check to see if the superclass is known in this point. If it's not
557 add the class to the unresolved_classes list. */
558 if ((superclass != NULL) && !objc_lookup_class (superclass)) {
559 assert(superclass != NULL);
561 DEBUG_PRINTF("inserting unresolved class %s (super=%s) ..\n",
562 class->name ? class->name : "<NoName>",
563 superclass ? superclass : "<Nil>");
565 unresolved_classes = list_cons (class, unresolved_classes);
569 /* Process category information from the module. */
570 for (i = 0; i < symtab->cat_def_cnt; ++i) {
571 Category_t category = symtab->defs[i + symtab->cls_def_cnt];
572 Class class = objc_lookup_class (category->class_name);
574 objc_categoryCount++;
576 /* If the class for the category exists then append its methods. */
578 DEBUG_PRINTF ("processing categories from (module %s, object %s)\n",
579 module->name ? module->name : "<NoName>",
580 class->name ? class->name : "<NoName>");
582 /* Do instance methods. */
583 if (category->instance_methods)
584 class_add_method_list (class, category->instance_methods);
586 /* Do class methods. */
587 if (category->class_methods)
588 class_add_method_list ((Class) class->class_pointer,
589 category->class_methods);
591 if (category->protocols) {
592 __objc_init_protocols (category->protocols);
593 __objc_class_add_protocols (class, category->protocols);
596 /* Register the instance methods as class methods, this is
597 only done for root classes. */
598 __objc_register_instance_methods_to_class(class);
601 /* The object to which the category methods belong can't be found.
602 Save the information. */
603 unclaimed_categories = list_cons(category, unclaimed_categories);
608 __objc_uninitialized_statics =
609 list_cons (statics, __objc_uninitialized_statics);
611 if (__objc_uninitialized_statics)
612 objc_init_statics ();
614 /* Scan the unclaimed category hash. Attempt to attach any unclaimed
615 categories to objects. */
616 cell = &unclaimed_categories;
621 category = (*cell)->head;
622 class = objc_lookup_class (category->class_name);
625 DEBUG_PRINTF ("attaching stored categories to object: %s\n",
626 class->name ? class->name : "<NoName>");
628 list_remove_head (cell);
630 if (category->instance_methods)
631 class_add_method_list (class, category->instance_methods);
633 if (category->class_methods)
634 class_add_method_list ((Class) class->class_pointer,
635 category->class_methods);
637 if (category->protocols) {
638 __objc_init_protocols (category->protocols);
639 __objc_class_add_protocols (class, category->protocols);
642 /* Register the instance methods as class methods, this is
643 only done for root classes. */
644 __objc_register_instance_methods_to_class(class);
646 if (*cell) cell = &(*cell)->tail;
649 if (__objc_unclaimed_proto_list && objc_lookup_class ("Protocol")) {
650 list_mapcar (__objc_unclaimed_proto_list,
651 (void(*)(void*))__objc_init_protocols);
652 list_free (__objc_unclaimed_proto_list);
653 __objc_unclaimed_proto_list = 0;
661 objc_DECLARE void __objc_exec_class (Module_t module)
663 __objc_exec_module(module);
666 static void objc_send_load (void)
668 if (!__objc_module_list)
671 /* Try to find out if all the classes loaded so far also have their
672 superclasses known to the runtime. We suppose that the objects that are
673 allocated in the +load method are in general of a class declared in the
675 if (unresolved_classes) {
676 Class class = unresolved_classes->head;
678 assert(class != Nil);
680 DEBUG_PRINTF("check unresolved class %s, super is %s\n",
681 class->name ? class->name : "<NoName>",
682 class->super_class ? (char*)class->super_class : "<Nil>");
684 while (objc_lookup_class ((char*)class->super_class)) {
685 list_remove_head (&unresolved_classes);
687 if (unresolved_classes)
688 class = unresolved_classes->head;
694 * If we still have classes for whom we don't have yet their super
695 * classes known to the runtime we don't send the +load messages.
697 if (unresolved_classes)
701 /* Special check to allow creating and sending messages to constant strings
702 in +load methods. If these classes are not yet known, even if all the
703 other classes are known, delay sending of +load. */
704 if (!objc_lookup_class ("NXConstantString") ||
705 !objc_lookup_class ("Object"))
708 /* Iterate over all modules in the __objc_module_list and call on them the
709 __objc_create_classes_tree function. This function creates a tree of
710 classes that resembles the class hierarchy. */
711 list_mapcar (__objc_module_list, (void(*)(void*))__objc_create_classes_tree);
713 while (__objc_class_tree_list) {
715 objc_preorder_traverse (__objc_class_tree_list->head,
716 0, __objc_tree_print);
718 objc_preorder_traverse (__objc_class_tree_list->head,
719 0, __objc_send_load);
720 objc_postorder_traverse (__objc_class_tree_list->head,
721 0, __objc_destroy_class_tree_node);
722 list_remove_head (&__objc_class_tree_list);
725 list_mapcar (__objc_module_list, (void(*)(void*))__objc_call_callback);
727 list_free (__objc_module_list);
728 __objc_module_list = NULL;
731 static void __objc_create_classes_tree (Module_t module)
733 /* The runtime mutex is locked in this point */
735 Symtab_t symtab = module->symtab;
738 /* Iterate thru classes defined in this module and insert them in the classes
740 for (i = 0; i < symtab->cls_def_cnt; i++) {
741 Class class = (Class) symtab->defs[i];
743 objc_tree_insert_class (class);
747 static void __objc_call_callback (Module_t module)
749 /* The runtime mutex is locked in this point */
750 Symtab_t symtab = module->symtab;
753 /* Iterate thru classes defined in this module and call the callback for
755 for (i = 0; i < symtab->cls_def_cnt; i++) {
756 Class class = (Class) symtab->defs[i];
758 /* Call the _objc_load_callback for this class. */
759 if (_objc_load_callback)
760 _objc_load_callback(class, 0);
763 /* Call the _objc_load_callback for categories. Don't register the instance
764 methods as class methods for categories to root classes since they were
765 already added in the class. */
766 for (i = 0; i < symtab->cat_def_cnt; i++) {
767 register Category_t category;
768 register Class class;
770 category = symtab->defs[i + symtab->cls_def_cnt];
771 class = objc_lookup_class (category->class_name);
773 if (_objc_load_callback)
774 _objc_load_callback(class, category);
778 /* Sanity check the version of gcc used to compile `module'*/
779 static void init_check_module_version(Module_t module)
781 if ((module->version != OBJC_VERSION) || (module->size != sizeof (Module))) {
784 if(module->version > OBJC_VERSION)
785 code = OBJC_ERR_OBJC_VERSION;
786 else if (module->version < OBJC_VERSION)
787 code = OBJC_ERR_GCC_VERSION;
789 code = OBJC_ERR_MODULE_SIZE;
791 objc_error(nil, code, "Module %s version %d doesn't match runtime %d\n",
792 module->name, (int)module->version, OBJC_VERSION);
797 __objc_init_protocols (struct objc_protocol_list* protos)
800 static Class proto_class = 0;
807 if (proto_class == Nil)
808 proto_class = objc_lookup_class("Protocol");
810 if (proto_class == Nil) {
811 __objc_unclaimed_proto_list =
812 list_cons (protos, __objc_unclaimed_proto_list);
818 assert (protos->next == 0); /* only single ones allowed */
821 for(i = 0; i < protos->count; i++) {
822 struct objc_protocol* aProto = protos->list[i];
824 if (((size_t)aProto->class_pointer) == PROTOCOL_VERSION) {
825 /* assign class pointer */
826 aProto->class_pointer = proto_class;
828 /* init super protocols */
829 __objc_init_protocols (aProto->protocol_list);
831 else if (protos->list[i]->class_pointer != proto_class) {
832 objc_error(nil, OBJC_ERR_PROTOCOL_VERSION,
833 "Version %d doesn't match runtime protocol version %d\n",
834 (int)((char*)protos->list[i]->class_pointer-(char*)0),
842 static void __objc_class_add_protocols (Class class,
843 struct objc_protocol_list* protos)
850 protos->next = class->protocols;
851 class->protocols = protos;