]> git.ipfire.org Git - thirdparty/gcc.git/blob - libobjc/init.c
f1eb83ab1d2ba0044325c628c4c29dc2006220db
[thirdparty/gcc.git] / libobjc / init.c
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>
6
7 This file is part of GCC.
8
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.
12
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
16 details.
17
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.
21
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/>. */
26
27 #include "objc-private/common.h"
28 #include "objc-private/error.h"
29 #include "objc/runtime.h"
30 #include "objc/thr.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() */
41
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
46
47 /* This list contains all modules currently loaded into the
48 runtime. */
49 static struct objc_list *__objc_module_list = 0; /* !T:MUTEX */
50
51 /* This list contains all proto_list's not yet assigned class
52 links. */
53 static struct objc_list *unclaimed_proto_list = 0; /* !T:MUTEX */
54
55 /* List of unresolved static instances. */
56 static struct objc_list *uninitialized_statics = 0; /* !T:MUTEX */
57
58 /* Global runtime "write" mutex. Having a single mutex prevents
59 deadlocks, but reduces concurrency. To improve concurrency, some
60 groups of functions in the runtime have their own separate mutex
61 (eg, __class_table_lock in class.c); to avoid deadlocks, these
62 routines must make sure that they never acquire any other lock
63 while holding their own local lock. Ie, they should lock, execute
64 some C code that does not perform any calls to other runtime
65 functions which may potentially lock different locks, then unlock.
66 If they need to perform any calls to other runtime functions that
67 may potentially lock other locks, then they should use the global
68 __objc_runtime_mutex. */
69 objc_mutex_t __objc_runtime_mutex = 0;
70
71 /* Number of threads that are alive. */
72 int __objc_runtime_threads_alive = 1; /* !T:MUTEX */
73
74 /* Check compiler vs runtime version. */
75 static void init_check_module_version (struct objc_module *);
76
77 /* Assign isa links to protos. */
78 static void __objc_init_protocols (struct objc_protocol_list *protos);
79
80 /* Assign isa link to a protocol, and register it. */
81 static void __objc_init_protocol (struct objc_protocol *protocol);
82
83 /* Add protocol to class. */
84 static void __objc_class_add_protocols (Class, struct objc_protocol_list *);
85
86 /* Load callback hook. */
87 void (*_objc_load_callback) (Class class, struct objc_category *category); /* !T:SAFE */
88
89 /* Are all categories/classes resolved? */
90 BOOL __objc_dangling_categories = NO; /* !T:UNUSED */
91
92 /* Sends +load to all classes and categories in certain
93 situations. */
94 static void objc_send_load (void);
95
96 /* Inserts all the classes defined in module in a tree of classes that
97 resembles the class hierarchy. This tree is traversed in preorder
98 and the classes in its nodes receive the +load message if these
99 methods were not executed before. The algorithm ensures that when
100 the +load method of a class is executed all the superclasses have
101 been already received the +load message. */
102 static void __objc_create_classes_tree (struct objc_module *module);
103
104 static void __objc_call_callback (struct objc_module *module);
105
106 /* A special version that works only before the classes are completely
107 installed in the runtime. */
108 static BOOL class_is_subclass_of_class (Class class, Class superclass);
109
110 typedef struct objc_class_tree {
111 Class class;
112 struct objc_list *subclasses; /* `head' is pointer to an objc_class_tree */
113 } objc_class_tree;
114
115 /* This is a linked list of objc_class_tree trees. The head of these
116 trees are root classes (their super class is Nil). These different
117 trees represent different class hierarchies. */
118 static struct objc_list *__objc_class_tree_list = NULL;
119
120 /* Keeps the +load methods who have been already executed. This hash
121 should not be destroyed during the execution of the program. */
122 static cache_ptr __objc_load_methods = NULL;
123
124 /* This function is used when building the class tree used to send
125 ordinately the +load message to all classes needing it. The tree
126 is really needed so that superclasses will get the message before
127 subclasses.
128
129 This tree will contain classes which are being loaded (or have just
130 being loaded), and whose super_class pointers have not yet been
131 resolved. This implies that their super_class pointers point to a
132 string with the name of the superclass; when the first message is
133 sent to the class (/an object of that class) the class links will
134 be resolved, which will replace the super_class pointers with
135 pointers to the actual superclasses.
136
137 Unfortunately, the tree might also contain classes which had been
138 loaded previously, and whose class links have already been
139 resolved.
140
141 This function returns the superclass of a class in both cases, and
142 can be used to build the determine the class relationships while
143 building the tree. */
144 static Class class_superclass_of_class (Class class)
145 {
146 char *super_class_name;
147
148 /* If the class links have been resolved, use the resolved
149 links. */
150 if (CLS_ISRESOLV (class))
151 return class->super_class;
152
153 /* Else, 'class' has not yet been resolved. This means that its
154 super_class pointer is really the name of the super class (rather
155 than a pointer to the actual superclass). */
156 super_class_name = (char *)class->super_class;
157
158 /* Return Nil for a root class. */
159 if (super_class_name == NULL)
160 return Nil;
161
162 /* Lookup the superclass of non-root classes. */
163 return objc_getClass (super_class_name);
164 }
165
166
167 /* Creates a tree of classes whose topmost class is directly inherited
168 from `upper' and the bottom class in this tree is
169 `bottom_class'. The classes in this tree are super classes of
170 `bottom_class'. `subclasses' member of each tree node point to the
171 next subclass tree node. */
172 static objc_class_tree *
173 create_tree_of_subclasses_inherited_from (Class bottom_class, Class upper)
174 {
175 Class superclass;
176 objc_class_tree *tree, *prev;
177
178 if (bottom_class->super_class)
179 superclass = objc_getClass ((char *) bottom_class->super_class);
180 else
181 superclass = Nil;
182
183 DEBUG_PRINTF ("create_tree_of_subclasses_inherited_from:");
184 DEBUG_PRINTF ("bottom_class = %s, upper = %s\n",
185 (bottom_class ? bottom_class->name : NULL),
186 (upper ? upper->name : NULL));
187
188 tree = prev = objc_calloc (1, sizeof (objc_class_tree));
189 prev->class = bottom_class;
190
191 while (superclass != upper)
192 {
193 tree = objc_calloc (1, sizeof (objc_class_tree));
194 tree->class = superclass;
195 tree->subclasses = list_cons (prev, tree->subclasses);
196 superclass = class_superclass_of_class (superclass);
197 prev = tree;
198 }
199
200 return tree;
201 }
202
203 /* Insert the `class' into the proper place in the `tree' class
204 hierarchy. This function returns a new tree if the class has been
205 successfully inserted into the tree or NULL if the class is not
206 part of the classes hierarchy described by `tree'. This function is
207 private to objc_tree_insert_class (), you should not call it
208 directly. */
209 static objc_class_tree *
210 __objc_tree_insert_class (objc_class_tree *tree, Class class)
211 {
212 DEBUG_PRINTF ("__objc_tree_insert_class: tree = %x, class = %s\n",
213 tree, class->name);
214
215 if (tree == NULL)
216 return create_tree_of_subclasses_inherited_from (class, NULL);
217 else if (class == tree->class)
218 {
219 /* `class' has been already inserted. */
220 DEBUG_PRINTF ("1. class %s was previously inserted\n", class->name);
221 return tree;
222 }
223 else if (class_superclass_of_class (class) == tree->class)
224 {
225 /* If class is a direct subclass of tree->class then add class
226 to the list of subclasses. First check to see if it wasn't
227 already inserted. */
228 struct objc_list *list = tree->subclasses;
229 objc_class_tree *node;
230
231 while (list)
232 {
233 /* Class has been already inserted; do nothing just return
234 the tree. */
235 if (((objc_class_tree *) list->head)->class == class)
236 {
237 DEBUG_PRINTF ("2. class %s was previously inserted\n",
238 class->name);
239 return tree;
240 }
241 list = list->tail;
242 }
243
244 /* Create a new node class and insert it into the list of
245 subclasses. */
246 node = objc_calloc (1, sizeof (objc_class_tree));
247 node->class = class;
248 tree->subclasses = list_cons (node, tree->subclasses);
249 DEBUG_PRINTF ("3. class %s inserted\n", class->name);
250 return tree;
251 }
252 else
253 {
254 /* The class is not a direct subclass of tree->class. Search
255 for class's superclasses in the list of subclasses. */
256 struct objc_list *subclasses = tree->subclasses;
257
258 /* Precondition: the class must be a subclass of tree->class;
259 otherwise return NULL to indicate our caller that it must
260 take the next tree. */
261 if (! class_is_subclass_of_class (class, tree->class))
262 return NULL;
263
264 for (; subclasses != NULL; subclasses = subclasses->tail)
265 {
266 Class aClass = ((objc_class_tree *) (subclasses->head))->class;
267
268 if (class_is_subclass_of_class (class, aClass))
269 {
270 /* If we found one of class's superclasses we insert the
271 class into its subtree and return the original tree
272 since nothing has been changed. */
273 subclasses->head
274 = __objc_tree_insert_class (subclasses->head, class);
275 DEBUG_PRINTF ("4. class %s inserted\n", class->name);
276 return tree;
277 }
278 }
279
280 /* We haven't found a subclass of `class' in the `subclasses'
281 list. Create a new tree of classes whose topmost class is a
282 direct subclass of tree->class. */
283 {
284 objc_class_tree *new_tree
285 = create_tree_of_subclasses_inherited_from (class, tree->class);
286 tree->subclasses = list_cons (new_tree, tree->subclasses);
287 DEBUG_PRINTF ("5. class %s inserted\n", class->name);
288 return tree;
289 }
290 }
291 }
292
293 /* This function inserts `class' in the right tree hierarchy classes. */
294 static void
295 objc_tree_insert_class (Class class)
296 {
297 struct objc_list *list_node;
298 objc_class_tree *tree;
299
300 list_node = __objc_class_tree_list;
301 while (list_node)
302 {
303 tree = __objc_tree_insert_class (list_node->head, class);
304 if (tree)
305 {
306 list_node->head = tree;
307 break;
308 }
309 else
310 list_node = list_node->tail;
311 }
312
313 /* If the list was finished but the class hasn't been inserted,
314 insert it here. */
315 if (! list_node)
316 {
317 __objc_class_tree_list = list_cons (NULL, __objc_class_tree_list);
318 __objc_class_tree_list->head = __objc_tree_insert_class (NULL, class);
319 }
320 }
321
322 /* Traverse tree in preorder. Used to send +load. */
323 static void
324 objc_preorder_traverse (objc_class_tree *tree,
325 int level,
326 void (*function) (objc_class_tree *, int))
327 {
328 struct objc_list *node;
329
330 (*function) (tree, level);
331 for (node = tree->subclasses; node; node = node->tail)
332 objc_preorder_traverse (node->head, level + 1, function);
333 }
334
335 /* Traverse tree in postorder. Used to destroy a tree. */
336 static void
337 objc_postorder_traverse (objc_class_tree *tree,
338 int level,
339 void (*function) (objc_class_tree *, int))
340 {
341 struct objc_list *node;
342
343 for (node = tree->subclasses; node; node = node->tail)
344 objc_postorder_traverse (node->head, level + 1, function);
345 (*function) (tree, level);
346 }
347
348 /* Used to print a tree class hierarchy. */
349 #ifdef DEBUG
350 static void
351 __objc_tree_print (objc_class_tree *tree, int level)
352 {
353 int i;
354
355 for (i = 0; i < level; i++)
356 printf (" ");
357 printf ("%s\n", tree->class->name);
358 }
359 #endif
360
361 /* Walks on a linked list of methods in the reverse order and executes
362 all the methods corresponding to `op' selector. Walking in the
363 reverse order assures the +load of class is executed first and then
364 +load of categories because of the way in which categories are
365 added to the class methods. */
366 static void
367 __objc_send_message_in_list (struct objc_method_list *method_list, Class class, SEL op)
368 {
369 int i;
370
371 if (! method_list)
372 return;
373
374 /* First execute the `op' message in the following method lists. */
375 __objc_send_message_in_list (method_list->method_next, class, op);
376
377 /* Search the method list. */
378 for (i = 0; i < method_list->method_count; i++)
379 {
380 struct objc_method *mth = &method_list->method_list[i];
381
382 if (mth->method_name && sel_eq (mth->method_name, op)
383 && ! objc_hash_is_key_in_hash (__objc_load_methods, mth->method_imp))
384 {
385 /* Add this method into the +load hash table. */
386 objc_hash_add (&__objc_load_methods,
387 mth->method_imp,
388 mth->method_imp);
389
390 DEBUG_PRINTF ("sending +load in class: %s\n", class->name);
391
392 /* The method was found and wasn't previously executed. */
393 (*mth->method_imp) ((id)class, mth->method_name);
394
395 break;
396 }
397 }
398 }
399
400 static void
401 __objc_send_load (objc_class_tree *tree,
402 int level __attribute__ ((__unused__)))
403 {
404 static SEL load_sel = 0;
405 Class class = tree->class;
406 struct objc_method_list *method_list = class->class_pointer->methods;
407
408 if (! load_sel)
409 load_sel = sel_registerName ("load");
410
411 __objc_send_message_in_list (method_list, class, load_sel);
412 }
413
414 static void
415 __objc_destroy_class_tree_node (objc_class_tree *tree,
416 int level __attribute__ ((__unused__)))
417 {
418 objc_free (tree);
419 }
420
421 /* This is used to check if the relationship between two classes
422 before the runtime completely installs the classes. */
423 static BOOL
424 class_is_subclass_of_class (Class class, Class superclass)
425 {
426 for (; class != Nil;)
427 {
428 if (class == superclass)
429 return YES;
430 class = class_superclass_of_class (class);
431 }
432
433 return NO;
434 }
435
436 /* This list contains all the classes in the runtime system for whom
437 their superclasses are not yet known to the runtime. */
438 static struct objc_list *unresolved_classes = 0;
439
440 /* Extern function used to reference the Object class. */
441 extern void __objc_force_linking (void);
442
443 void
444 __objc_force_linking (void)
445 {
446 extern void __objc_linking (void);
447 __objc_linking ();
448 }
449
450 /* Run through the statics list, removing modules as soon as all its
451 statics have been initialized. */
452 static void
453 objc_init_statics (void)
454 {
455 struct objc_list **cell = &uninitialized_statics;
456 struct objc_static_instances **statics_in_module;
457
458 objc_mutex_lock (__objc_runtime_mutex);
459
460 while (*cell)
461 {
462 int module_initialized = 1;
463
464 for (statics_in_module = (*cell)->head;
465 *statics_in_module; statics_in_module++)
466 {
467 struct objc_static_instances *statics = *statics_in_module;
468 Class class = objc_getClass (statics->class_name);
469
470 if (! class)
471 {
472 /* It is unfortunate that this will cause all the
473 statics initialization to be done again (eg, if we
474 already initialized constant strings, and are now
475 initializing protocols, setting module_initialized to
476 0 would cause constant strings to be initialized
477 again). It would be good to be able to track if we
478 have already initialized some of them. */
479 module_initialized = 0;
480 }
481 else
482 {
483 /* Note that if this is a list of Protocol objects, some
484 of them may have been initialized already (because
485 they were attached to classes or categories, and the
486 class/category loading code automatically fixes them
487 up), and some of them may not. We really need to go
488 through the whole list to be sure! Protocols are
489 also special because we want to register them and
490 register all their selectors. */
491 id *inst;
492
493 if (strcmp (statics->class_name, "Protocol") == 0)
494 {
495 /* Protocols are special, because not only we want
496 to fix up their class pointers, but we also want
497 to register them and their selectors with the
498 runtime. */
499 for (inst = &statics->instances[0]; *inst; inst++)
500 __objc_init_protocol ((struct objc_protocol *)*inst);
501 }
502 else
503 {
504 /* Other static instances (typically constant
505 strings) are easier as we just fix up their class
506 pointers. */
507 for (inst = &statics->instances[0]; *inst; inst++)
508 (*inst)->class_pointer = class;
509 }
510 }
511 }
512 if (module_initialized)
513 {
514 /* Remove this module from the uninitialized list. */
515 struct objc_list *this = *cell;
516 *cell = this->tail;
517 objc_free (this);
518 }
519 else
520 cell = &(*cell)->tail;
521 }
522
523 objc_mutex_unlock (__objc_runtime_mutex);
524 }
525
526 /* This function is called by constructor functions generated for each
527 module compiled. (_GLOBAL_$I$...) The purpose of this function is
528 to gather the module pointers so that they may be processed by the
529 initialization routines as soon as possible. */
530 void
531 __objc_exec_class (struct objc_module *module)
532 {
533 /* Have we processed any constructors previously? This flag is used
534 to indicate that some global data structures need to be
535 built. */
536 static BOOL previous_constructors = 0;
537
538 static struct objc_list *unclaimed_categories = 0;
539
540 /* The symbol table (defined in objc-private/module-abi-8.h)
541 generated by gcc. */
542 struct objc_symtab *symtab = module->symtab;
543
544 /* The statics in this module. */
545 struct objc_static_instances **statics
546 = symtab->defs[symtab->cls_def_cnt + symtab->cat_def_cnt];
547
548 /* Entry used to traverse hash lists. */
549 struct objc_list **cell;
550
551 /* The table of selector references for this module. */
552 SEL selectors = symtab->refs;
553
554 int i;
555
556 DEBUG_PRINTF ("received module: %s\n", module->name);
557
558 /* Check gcc version. */
559 init_check_module_version (module);
560
561 /* On the first call of this routine, initialize some data
562 structures. */
563 if (! previous_constructors)
564 {
565 /* Initialize thread-safe system. */
566 __objc_init_thread_system ();
567 __objc_runtime_threads_alive = 1;
568 __objc_runtime_mutex = objc_mutex_allocate ();
569
570 __objc_init_selector_tables ();
571 __objc_init_class_tables ();
572 __objc_init_dispatch_tables ();
573 __objc_class_tree_list = list_cons (NULL, __objc_class_tree_list);
574 __objc_load_methods = objc_hash_new (128,
575 (hash_func_type)objc_hash_ptr,
576 objc_compare_ptrs);
577 __objc_protocols_init ();
578 __objc_accessors_init ();
579 __objc_sync_init ();
580 previous_constructors = 1;
581 }
582
583 /* Save the module pointer for later processing. (not currently
584 used). */
585 objc_mutex_lock (__objc_runtime_mutex);
586 __objc_module_list = list_cons (module, __objc_module_list);
587
588 /* Replace referenced selectors from names to SEL's. */
589 if (selectors)
590 {
591 for (i = 0; selectors[i].sel_id; ++i)
592 {
593 const char *name, *type;
594 name = (char *) selectors[i].sel_id;
595 type = (char *) selectors[i].sel_types;
596 /* Constructors are constant static data so we can safely
597 store pointers to them in the runtime
598 structures. is_const == YES. */
599 __sel_register_typed_name (name, type,
600 (struct objc_selector *) &(selectors[i]),
601 YES);
602 }
603 }
604
605 /* Parse the classes in the load module and gather selector
606 information. */
607 DEBUG_PRINTF ("gathering selectors from module: %s\n", module->name);
608 for (i = 0; i < symtab->cls_def_cnt; ++i)
609 {
610 Class class = (Class) symtab->defs[i];
611 const char *superclass = (char *) class->super_class;
612
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);
617
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;
621
622 __objc_init_class (class);
623
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);
628 }
629
630 /* Process category information from the module. */
631 for (i = 0; i < symtab->cat_def_cnt; ++i)
632 {
633 struct objc_category *category = symtab->defs[i + symtab->cls_def_cnt];
634 Class class = objc_getClass (category->class_name);
635
636 /* If the class for the category exists then append its
637 methods. */
638 if (class)
639 {
640
641 DEBUG_PRINTF ("processing categories from (module,object): %s, %s\n",
642 module->name,
643 class->name);
644
645 /* Do instance methods. */
646 if (category->instance_methods)
647 class_add_method_list (class, category->instance_methods);
648
649 /* Do class methods. */
650 if (category->class_methods)
651 class_add_method_list ((Class) class->class_pointer,
652 category->class_methods);
653
654 if (category->protocols)
655 {
656 __objc_init_protocols (category->protocols);
657 __objc_class_add_protocols (class, category->protocols);
658 }
659
660 /* Register the instance methods as class methods, this is
661 only done for root classes. */
662 __objc_register_instance_methods_to_class (class);
663 }
664 else
665 {
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);
669 }
670 }
671
672 if (statics)
673 uninitialized_statics = list_cons (statics, uninitialized_statics);
674 if (uninitialized_statics)
675 objc_init_statics ();
676
677 /* Scan the unclaimed category hash. Attempt to attach any
678 unclaimed categories to objects. */
679 for (cell = &unclaimed_categories; *cell; )
680 {
681 struct objc_category *category = (*cell)->head;
682 Class class = objc_getClass (category->class_name);
683
684 if (class)
685 {
686 DEBUG_PRINTF ("attaching stored categories to object: %s\n",
687 class->name);
688
689 list_remove_head (cell);
690
691 if (category->instance_methods)
692 class_add_method_list (class, category->instance_methods);
693
694 if (category->class_methods)
695 class_add_method_list ((Class) class->class_pointer,
696 category->class_methods);
697
698 if (category->protocols)
699 {
700 __objc_init_protocols (category->protocols);
701 __objc_class_add_protocols (class, category->protocols);
702 }
703
704 /* Register the instance methods as class methods, this is
705 only done for root classes. */
706 __objc_register_instance_methods_to_class (class);
707 }
708 else
709 cell = &(*cell)->tail;
710 }
711
712 if (unclaimed_proto_list && objc_getClass ("Protocol"))
713 {
714 list_mapcar (unclaimed_proto_list,
715 (void (*) (void *))__objc_init_protocols);
716 list_free (unclaimed_proto_list);
717 unclaimed_proto_list = 0;
718 }
719
720 objc_send_load ();
721
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 ();
729
730 objc_mutex_unlock (__objc_runtime_mutex);
731 }
732
733 static void
734 objc_send_load (void)
735 {
736 if (! __objc_module_list)
737 return;
738
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)
744 {
745 Class class = unresolved_classes->head;
746
747 while (objc_getClass ((char *) class->super_class))
748 {
749 list_remove_head (&unresolved_classes);
750 if (unresolved_classes)
751 class = unresolved_classes->head;
752 else
753 break;
754 }
755
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
758 messages. */
759 if (unresolved_classes)
760 return;
761 }
762
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"))
766 return;
767
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);
773
774 while (__objc_class_tree_list)
775 {
776 #ifdef DEBUG
777 objc_preorder_traverse (__objc_class_tree_list->head,
778 0, __objc_tree_print);
779 #endif
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);
785 }
786
787 list_mapcar (__objc_module_list, (void (*) (void *)) __objc_call_callback);
788 list_free (__objc_module_list);
789 __objc_module_list = NULL;
790 }
791
792 static void
793 __objc_create_classes_tree (struct objc_module *module)
794 {
795 /* The runtime mutex is locked at this point */
796 struct objc_symtab *symtab = module->symtab;
797 int i;
798
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++)
802 {
803 Class class = (Class) symtab->defs[i];
804
805 objc_tree_insert_class (class);
806 }
807 }
808
809 static void
810 __objc_call_callback (struct objc_module *module)
811 {
812 /* The runtime mutex is locked at this point. */
813 struct objc_symtab *symtab = module->symtab;
814 int i;
815
816 /* Iterate thru classes defined in this module and call the callback
817 for each one. */
818 for (i = 0; i < symtab->cls_def_cnt; i++)
819 {
820 Class class = (Class) symtab->defs[i];
821
822 /* Call the _objc_load_callback for this class. */
823 if (_objc_load_callback)
824 _objc_load_callback (class, 0);
825 }
826
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++)
831 {
832 struct objc_category *category = symtab->defs[i + symtab->cls_def_cnt];
833 Class class = objc_getClass (category->class_name);
834
835 if (_objc_load_callback)
836 _objc_load_callback (class, category);
837 }
838 }
839
840 /* Sanity check the version of gcc used to compile `module'. */
841 static void
842 init_check_module_version (struct objc_module *module)
843 {
844 if ((module->version != OBJC_VERSION) || (module->size != sizeof (struct objc_module)))
845 {
846 _objc_abort ("Module %s version %d doesn't match runtime %d\n",
847 module->name, (int)module->version, OBJC_VERSION);
848 }
849 }
850
851 /* __objc_init_class must be called with __objc_runtime_mutex already locked. */
852 void
853 __objc_init_class (Class class)
854 {
855 /* Store the class in the class table and assign class numbers. */
856 __objc_add_class_to_hash (class);
857
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);
861
862 /* Install the fake dispatch tables. */
863 __objc_install_premature_dtable (class);
864 __objc_install_premature_dtable (class->class_pointer);
865
866 /* Register the instance methods as class methods, this is only done
867 for root classes. */
868 __objc_register_instance_methods_to_class (class);
869
870 if (class->protocols)
871 __objc_init_protocols (class->protocols);
872 }
873
874 /* __objc_init_protocol must be called with __objc_runtime_mutex
875 already locked, and the "Protocol" class already registered. */
876 static void
877 __objc_init_protocol (struct objc_protocol *protocol)
878 {
879 static Class proto_class = 0;
880
881 if (! proto_class)
882 proto_class = objc_getClass ("Protocol");
883
884 if (((size_t)protocol->class_pointer) == PROTOCOL_VERSION)
885 {
886 /* Assign class pointer. */
887 protocol->class_pointer = proto_class;
888
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
894 SEL. */
895 if (protocol->class_methods)
896 __objc_register_selectors_from_description_list (protocol->class_methods);
897
898 if (protocol->instance_methods)
899 __objc_register_selectors_from_description_list (protocol->instance_methods);
900
901 /* Register the protocol in the hashtable or protocols by
902 name. */
903 __objc_protocols_add_protocol (protocol->protocol_name, protocol);
904
905 /* Init super protocols. */
906 __objc_init_protocols (protocol->protocol_list);
907 }
908 else if (protocol->class_pointer != proto_class)
909 {
910 _objc_abort ("Version %d doesn't match runtime protocol version %d\n",
911 (int) ((char *) protocol->class_pointer
912 - (char *) 0),
913 PROTOCOL_VERSION);
914 }
915 }
916
917 static void
918 __objc_init_protocols (struct objc_protocol_list *protos)
919 {
920 size_t i;
921 static Class proto_class = 0;
922
923 if (! protos)
924 return;
925
926 objc_mutex_lock (__objc_runtime_mutex);
927
928 if (! proto_class)
929 proto_class = objc_getClass ("Protocol");
930
931 if (! proto_class)
932 {
933 unclaimed_proto_list = list_cons (protos, unclaimed_proto_list);
934 objc_mutex_unlock (__objc_runtime_mutex);
935 return;
936 }
937
938 #if 0
939 assert (protos->next == 0); /* Only single ones allowed. */
940 #endif
941
942 for (i = 0; i < protos->count; i++)
943 {
944 struct objc_protocol *aProto = protos->list[i];
945 __objc_init_protocol (aProto);
946 }
947
948 objc_mutex_unlock (__objc_runtime_mutex);
949 }
950
951 static void
952 __objc_class_add_protocols (Class class, struct objc_protocol_list *protos)
953 {
954 if (! protos)
955 return;
956
957 protos->next = class->protocols;
958 class->protocols = protos;
959 }