]> git.ipfire.org Git - thirdparty/gcc.git/blame - libobjc/init.c
Forgotten ChangeLog entries.
[thirdparty/gcc.git] / libobjc / init.c
CommitLineData
88e17b57 1/* GNU Objective C Runtime initialization
fed2b101 2 Copyright (C) 1993, 1995, 1996, 1997, 2002, 2009, 2010
748086b7 3 Free Software Foundation, Inc.
88e17b57
BE
4 Contributed by Kresten Krab Thorup
5 +load support contributed by Ovidiu Predescu <ovidiu@net-community.com>
6
38709cad 7This file is part of GCC.
88e17b57 8
38709cad 9GCC is free software; you can redistribute it and/or modify it under the
88e17b57 10terms of the GNU General Public License as published by the Free Software
748086b7 11Foundation; either version 3, or (at your option) any later version.
88e17b57 12
38709cad 13GCC is distributed in the hope that it will be useful, but WITHOUT ANY
88e17b57
BE
14WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
16details.
17
748086b7
JJ
18Under Section 7 of GPL version 3, you are granted additional
19permissions described in the GCC Runtime Library Exception, version
203.1, as published by the Free Software Foundation.
88e17b57 21
748086b7
JJ
22You should have received a copy of the GNU General Public License and
23a copy of the GCC Runtime Library Exception along with this program;
24see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
25<http://www.gnu.org/licenses/>. */
88e17b57 26
6dead247 27#include "objc-private/common.h"
7b869986 28#include "objc-private/error.h"
fed2b101 29#include "objc/runtime.h"
a19fac96 30#include "objc/thr.h"
5be9cdc1
NP
31#include "objc-private/hash.h"
32#include "objc-private/objc-list.h"
fed2b101 33#include "objc-private/module-abi-8.h"
41720477 34#include "objc-private/runtime.h" /* For __objc_resolve_class_links(). */
1af5b8f5 35#include "objc-private/selector.h" /* For __sel_register_typed_name(). */
fd312537 36#include "objc-private/objc-sync.h" /* For __objc_sync_init() */
f7185d47
NP
37#include "objc-private/protocols.h" /* For __objc_protocols_init(),
38 __objc_protocols_add_protocol()
39 __objc_protocols_register_selectors() */
682e805a 40#include "objc-private/accessors.h" /* For __objc_accessors_init() */
88e17b57 41
575584a9 42/* The version number of this runtime. This must match the number
40165636 43 defined in gcc (objc-act.c). */
88e17b57
BE
44#define OBJC_VERSION 8
45#define PROTOCOL_VERSION 2
46
575584a9
NP
47/* This list contains all modules currently loaded into the
48 runtime. */
40165636 49static struct objc_list *__objc_module_list = 0; /* !T:MUTEX */
88e17b57 50
575584a9
NP
51/* This list contains all proto_list's not yet assigned class
52 links. */
40165636 53static struct objc_list *unclaimed_proto_list = 0; /* !T:MUTEX */
88e17b57
BE
54
55/* List of unresolved static instances. */
56static struct objc_list *uninitialized_statics = 0; /* !T:MUTEX */
57
debfbfee
NP
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. */
88e17b57
BE
69objc_mutex_t __objc_runtime_mutex = 0;
70
40165636 71/* Number of threads that are alive. */
88e17b57
BE
72int __objc_runtime_threads_alive = 1; /* !T:MUTEX */
73
40165636 74/* Check compiler vs runtime version. */
fed2b101 75static void init_check_module_version (struct objc_module *);
88e17b57 76
40165636
RB
77/* Assign isa links to protos. */
78static void __objc_init_protocols (struct objc_protocol_list *protos);
88e17b57 79
f7185d47
NP
80/* Assign isa link to a protocol, and register it. */
81static void __objc_init_protocol (struct objc_protocol *protocol);
82
40165636
RB
83/* Add protocol to class. */
84static void __objc_class_add_protocols (Class, struct objc_protocol_list *);
88e17b57 85
120d5f8e 86/* Load callback hook. */
fed2b101 87void (*_objc_load_callback) (Class class, struct objc_category *category); /* !T:SAFE */
88e17b57 88
fed2b101 89/* Are all categories/classes resolved? */
88e17b57
BE
90BOOL __objc_dangling_categories = NO; /* !T:UNUSED */
91
575584a9
NP
92/* Sends +load to all classes and categories in certain
93 situations. */
88e17b57
BE
94static void objc_send_load (void);
95
96/* Inserts all the classes defined in module in a tree of classes that
40165636
RB
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. */
fed2b101 102static void __objc_create_classes_tree (struct objc_module *module);
88e17b57 103
fed2b101 104static void __objc_call_callback (struct objc_module *module);
88e17b57
BE
105
106/* A special version that works only before the classes are completely
40165636 107 installed in the runtime. */
88e17b57
BE
108static BOOL class_is_subclass_of_class (Class class, Class superclass);
109
110typedef 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
40165636
RB
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. */
88e17b57
BE
118static struct objc_list *__objc_class_tree_list = NULL;
119
40165636
RB
120/* Keeps the +load methods who have been already executed. This hash
121 should not be destroyed during the execution of the program. */
88e17b57
BE
122static cache_ptr __objc_load_methods = NULL;
123
e083f3f9
RFM
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
575584a9 143 building the tree. */
e083f3f9
RFM
144static 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
575584a9 149 links. */
e083f3f9
RFM
150 if (CLS_ISRESOLV (class))
151 return class->super_class;
152
153 /* Else, 'class' has not yet been resolved. This means that its
575584a9
NP
154 super_class pointer is really the name of the super class (rather
155 than a pointer to the actual superclass). */
e083f3f9
RFM
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. */
fed2b101 163 return objc_getClass (super_class_name);
e083f3f9
RFM
164}
165
166
40165636
RB
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. */
88e17b57
BE
172static objc_class_tree *
173create_tree_of_subclasses_inherited_from (Class bottom_class, Class upper)
174{
fed2b101 175 Class superclass;
88e17b57
BE
176 objc_class_tree *tree, *prev;
177
fed2b101
NP
178 if (bottom_class->super_class)
179 superclass = objc_getClass ((char *) bottom_class->super_class);
180 else
181 superclass = Nil;
182
88e17b57
BE
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);
e083f3f9 196 superclass = class_superclass_of_class (superclass);
88e17b57
BE
197 prev = tree;
198 }
199
200 return tree;
201}
202
40165636
RB
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. */
88e17b57
BE
209static objc_class_tree *
210__objc_tree_insert_class (objc_class_tree *tree, Class class)
211{
df0820da 212 DEBUG_PRINTF ("__objc_tree_insert_class: tree = %p, class = %s\n",
88e17b57
BE
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 {
575584a9 219 /* `class' has been already inserted. */
88e17b57
BE
220 DEBUG_PRINTF ("1. class %s was previously inserted\n", class->name);
221 return tree;
222 }
e083f3f9 223 else if (class_superclass_of_class (class) == tree->class)
88e17b57 224 {
575584a9
NP
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. */
88e17b57
BE
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
40165636
RB
234 the tree. */
235 if (((objc_class_tree *) list->head)->class == class)
88e17b57
BE
236 {
237 DEBUG_PRINTF ("2. class %s was previously inserted\n",
238 class->name);
239 return tree;
240 }
241 list = list->tail;
242 }
243
575584a9
NP
244 /* Create a new node class and insert it into the list of
245 subclasses. */
88e17b57
BE
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 {
575584a9
NP
254 /* The class is not a direct subclass of tree->class. Search
255 for class's superclasses in the list of subclasses. */
88e17b57
BE
256 struct objc_list *subclasses = tree->subclasses;
257
40165636
RB
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))
88e17b57
BE
262 return NULL;
263
264 for (; subclasses != NULL; subclasses = subclasses->tail)
265 {
40165636 266 Class aClass = ((objc_class_tree *) (subclasses->head))->class;
88e17b57
BE
267
268 if (class_is_subclass_of_class (class, aClass))
269 {
40165636
RB
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. */
88e17b57
BE
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
40165636
RB
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. */
88e17b57
BE
283 {
284 objc_class_tree *new_tree
40165636 285 = create_tree_of_subclasses_inherited_from (class, tree->class);
88e17b57
BE
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
40165636 293/* This function inserts `class' in the right tree hierarchy classes. */
88e17b57
BE
294static void
295objc_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
40165636
RB
313 /* If the list was finished but the class hasn't been inserted,
314 insert it here. */
315 if (! list_node)
88e17b57
BE
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
40165636 322/* Traverse tree in preorder. Used to send +load. */
88e17b57
BE
323static void
324objc_preorder_traverse (objc_class_tree *tree,
325 int level,
40165636 326 void (*function) (objc_class_tree *, int))
88e17b57
BE
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
40165636 335/* Traverse tree in postorder. Used to destroy a tree. */
88e17b57
BE
336static void
337objc_postorder_traverse (objc_class_tree *tree,
40165636
RB
338 int level,
339 void (*function) (objc_class_tree *, int))
88e17b57
BE
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
40165636 348/* Used to print a tree class hierarchy. */
88e17b57
BE
349#ifdef DEBUG
350static 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
40165636
RB
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. */
88e17b57 366static void
fed2b101 367__objc_send_message_in_list (struct objc_method_list *method_list, Class class, SEL op)
88e17b57
BE
368{
369 int i;
370
40165636 371 if (! method_list)
88e17b57
BE
372 return;
373
575584a9 374 /* First execute the `op' message in the following method lists. */
88e17b57
BE
375 __objc_send_message_in_list (method_list->method_next, class, op);
376
40165636 377 /* Search the method list. */
88e17b57
BE
378 for (i = 0; i < method_list->method_count; i++)
379 {
fed2b101 380 struct objc_method *mth = &method_list->method_list[i];
88e17b57
BE
381
382 if (mth->method_name && sel_eq (mth->method_name, op)
270a1283 383 && ! objc_hash_is_key_in_hash (__objc_load_methods, mth->method_imp))
88e17b57 384 {
575584a9 385 /* Add this method into the +load hash table. */
270a1283
DA
386 objc_hash_add (&__objc_load_methods,
387 mth->method_imp,
388 mth->method_imp);
575584a9 389
88e17b57 390 DEBUG_PRINTF ("sending +load in class: %s\n", class->name);
575584a9 391
40165636 392 /* The method was found and wasn't previously executed. */
e6be21fe
RFM
393 (*mth->method_imp) ((id)class, mth->method_name);
394
88e17b57
BE
395 break;
396 }
397 }
398}
399
400static void
8f8c44cb
KG
401__objc_send_load (objc_class_tree *tree,
402 int level __attribute__ ((__unused__)))
88e17b57
BE
403{
404 static SEL load_sel = 0;
405 Class class = tree->class;
fed2b101 406 struct objc_method_list *method_list = class->class_pointer->methods;
88e17b57 407
40165636 408 if (! load_sel)
fed2b101 409 load_sel = sel_registerName ("load");
88e17b57
BE
410
411 __objc_send_message_in_list (method_list, class, load_sel);
412}
413
414static void
8f8c44cb
KG
415__objc_destroy_class_tree_node (objc_class_tree *tree,
416 int level __attribute__ ((__unused__)))
88e17b57
BE
417{
418 objc_free (tree);
419}
420
40165636
RB
421/* This is used to check if the relationship between two classes
422 before the runtime completely installs the classes. */
88e17b57
BE
423static BOOL
424class_is_subclass_of_class (Class class, Class superclass)
425{
426 for (; class != Nil;)
427 {
428 if (class == superclass)
429 return YES;
e083f3f9 430 class = class_superclass_of_class (class);
88e17b57
BE
431 }
432
433 return NO;
434}
435
40165636
RB
436/* This list contains all the classes in the runtime system for whom
437 their superclasses are not yet known to the runtime. */
438static struct objc_list *unresolved_classes = 0;
88e17b57 439
1501d094 440/* Extern function used to reference the Object class. */
6000b42b
JDA
441extern void __objc_force_linking (void);
442
443void
88e17b57
BE
444__objc_force_linking (void)
445{
446 extern void __objc_linking (void);
447 __objc_linking ();
88e17b57
BE
448}
449
40165636
RB
450/* Run through the statics list, removing modules as soon as all its
451 statics have been initialized. */
88e17b57
BE
452static void
453objc_init_statics (void)
454{
455 struct objc_list **cell = &uninitialized_statics;
456 struct objc_static_instances **statics_in_module;
457
40165636 458 objc_mutex_lock (__objc_runtime_mutex);
88e17b57
BE
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;
fed2b101 468 Class class = objc_getClass (statics->class_name);
88e17b57 469
40165636 470 if (! class)
88e17b57 471 {
5254c66b
NP
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
f7185d47
NP
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. */
88e17b57
BE
491 id *inst;
492
f7185d47
NP
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 {
575584a9
NP
504 /* Other static instances (typically constant
505 strings) are easier as we just fix up their class
506 pointers. */
f7185d47
NP
507 for (inst = &statics->instances[0]; *inst; inst++)
508 (*inst)->class_pointer = class;
509 }
88e17b57
BE
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;
40165636 517 objc_free (this);
88e17b57
BE
518 }
519 else
520 cell = &(*cell)->tail;
521 }
522
40165636 523 objc_mutex_unlock (__objc_runtime_mutex);
575584a9 524}
88e17b57
BE
525
526/* This function is called by constructor functions generated for each
40165636
RB
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. */
88e17b57 530void
fed2b101 531__objc_exec_class (struct objc_module *module)
88e17b57 532{
fed2b101
NP
533 /* Have we processed any constructors previously? This flag is used
534 to indicate that some global data structures need to be
535 built. */
88e17b57
BE
536 static BOOL previous_constructors = 0;
537
40165636 538 static struct objc_list *unclaimed_categories = 0;
88e17b57 539
fed2b101
NP
540 /* The symbol table (defined in objc-private/module-abi-8.h)
541 generated by gcc. */
542 struct objc_symtab *symtab = module->symtab;
88e17b57 543
fed2b101 544 /* The statics in this module. */
88e17b57
BE
545 struct objc_static_instances **statics
546 = symtab->defs[symtab->cls_def_cnt + symtab->cat_def_cnt];
547
fed2b101 548 /* Entry used to traverse hash lists. */
40165636 549 struct objc_list **cell;
88e17b57 550
fed2b101 551 /* The table of selector references for this module. */
600cbba2 552 struct objc_selector *selectors = symtab->refs;
88e17b57 553
88e17b57
BE
554 int i;
555
556 DEBUG_PRINTF ("received module: %s\n", module->name);
557
575584a9 558 /* Check gcc version. */
40165636 559 init_check_module_version (module);
88e17b57 560
575584a9
NP
561 /* On the first call of this routine, initialize some data
562 structures. */
40165636 563 if (! previous_constructors)
88e17b57 564 {
575584a9 565 /* Initialize thread-safe system. */
40165636 566 __objc_init_thread_system ();
88e17b57 567 __objc_runtime_threads_alive = 1;
40165636 568 __objc_runtime_mutex = objc_mutex_allocate ();
88e17b57 569
40165636
RB
570 __objc_init_selector_tables ();
571 __objc_init_class_tables ();
572 __objc_init_dispatch_tables ();
88e17b57 573 __objc_class_tree_list = list_cons (NULL, __objc_class_tree_list);
270a1283
DA
574 __objc_load_methods = objc_hash_new (128,
575 (hash_func_type)objc_hash_ptr,
576 objc_compare_ptrs);
debfbfee 577 __objc_protocols_init ();
682e805a 578 __objc_accessors_init ();
fd312537 579 __objc_sync_init ();
88e17b57
BE
580 previous_constructors = 1;
581 }
582
575584a9
NP
583 /* Save the module pointer for later processing. (not currently
584 used). */
40165636
RB
585 objc_mutex_lock (__objc_runtime_mutex);
586 __objc_module_list = list_cons (module, __objc_module_list);
88e17b57 587
600cbba2 588 /* Replace referenced selectors from names to SELs. */
88e17b57 589 if (selectors)
600cbba2 590 __objc_register_selectors_from_module (selectors);
88e17b57 591
575584a9
NP
592 /* Parse the classes in the load module and gather selector
593 information. */
88e17b57
BE
594 DEBUG_PRINTF ("gathering selectors from module: %s\n", module->name);
595 for (i = 0; i < symtab->cls_def_cnt; ++i)
596 {
597 Class class = (Class) symtab->defs[i];
40165636 598 const char *superclass = (char *) class->super_class;
88e17b57
BE
599
600 /* Make sure we have what we think. */
40165636
RB
601 assert (CLS_ISCLASS (class));
602 assert (CLS_ISMETA (class->class_pointer));
88e17b57
BE
603 DEBUG_PRINTF ("phase 1, processing class: %s\n", class->name);
604
575584a9
NP
605 /* Initialize the subclass list to be NULL. In some cases it
606 isn't and this crashes the program. */
88e17b57
BE
607 class->subclass_list = NULL;
608
6c5c7efd 609 __objc_init_class (class);
88e17b57 610
575584a9
NP
611 /* Check to see if the superclass is known in this point. If
612 it's not add the class to the unresolved_classes list. */
fed2b101 613 if (superclass && ! objc_getClass (superclass))
88e17b57
BE
614 unresolved_classes = list_cons (class, unresolved_classes);
615 }
616
617 /* Process category information from the module. */
618 for (i = 0; i < symtab->cat_def_cnt; ++i)
619 {
fed2b101
NP
620 struct objc_category *category = symtab->defs[i + symtab->cls_def_cnt];
621 Class class = objc_getClass (category->class_name);
88e17b57 622
575584a9
NP
623 /* If the class for the category exists then append its
624 methods. */
88e17b57
BE
625 if (class)
626 {
627
628 DEBUG_PRINTF ("processing categories from (module,object): %s, %s\n",
629 module->name,
630 class->name);
631
632 /* Do instance methods. */
633 if (category->instance_methods)
634 class_add_method_list (class, category->instance_methods);
635
636 /* Do class methods. */
637 if (category->class_methods)
638 class_add_method_list ((Class) class->class_pointer,
639 category->class_methods);
640
641 if (category->protocols)
642 {
643 __objc_init_protocols (category->protocols);
644 __objc_class_add_protocols (class, category->protocols);
645 }
646
647 /* Register the instance methods as class methods, this is
40165636
RB
648 only done for root classes. */
649 __objc_register_instance_methods_to_class (class);
88e17b57
BE
650 }
651 else
652 {
575584a9
NP
653 /* The object to which the category methods belong can't be
654 found. Save the information. */
40165636 655 unclaimed_categories = list_cons (category, unclaimed_categories);
88e17b57
BE
656 }
657 }
658
659 if (statics)
660 uninitialized_statics = list_cons (statics, uninitialized_statics);
661 if (uninitialized_statics)
662 objc_init_statics ();
663
575584a9
NP
664 /* Scan the unclaimed category hash. Attempt to attach any
665 unclaimed categories to objects. */
e5e0f6f5 666 for (cell = &unclaimed_categories; *cell; )
88e17b57 667 {
fed2b101
NP
668 struct objc_category *category = (*cell)->head;
669 Class class = objc_getClass (category->class_name);
88e17b57
BE
670
671 if (class)
672 {
673 DEBUG_PRINTF ("attaching stored categories to object: %s\n",
674 class->name);
675
676 list_remove_head (cell);
677
678 if (category->instance_methods)
679 class_add_method_list (class, category->instance_methods);
680
681 if (category->class_methods)
682 class_add_method_list ((Class) class->class_pointer,
683 category->class_methods);
684
685 if (category->protocols)
686 {
687 __objc_init_protocols (category->protocols);
688 __objc_class_add_protocols (class, category->protocols);
689 }
690
691 /* Register the instance methods as class methods, this is
40165636
RB
692 only done for root classes. */
693 __objc_register_instance_methods_to_class (class);
88e17b57 694 }
e5e0f6f5
NP
695 else
696 cell = &(*cell)->tail;
88e17b57
BE
697 }
698
fed2b101 699 if (unclaimed_proto_list && objc_getClass ("Protocol"))
88e17b57 700 {
40165636
RB
701 list_mapcar (unclaimed_proto_list,
702 (void (*) (void *))__objc_init_protocols);
88e17b57
BE
703 list_free (unclaimed_proto_list);
704 unclaimed_proto_list = 0;
705 }
706
707 objc_send_load ();
708
41720477
NP
709 /* Check if there are no unresolved classes (ie, classes whose
710 superclass has not been loaded yet) and that the 'Object' class,
711 used as the class of classes, exist. If so, it is worth
712 "resolving the class links" at this point, which will setup all
713 the class/superclass pointers. */
714 if (!unresolved_classes && objc_getClass ("Object"))
715 __objc_resolve_class_links ();
120d5f8e 716
41720477 717 objc_mutex_unlock (__objc_runtime_mutex);
88e17b57
BE
718}
719
40165636
RB
720static void
721objc_send_load (void)
88e17b57 722{
40165636 723 if (! __objc_module_list)
88e17b57
BE
724 return;
725
726 /* Try to find out if all the classes loaded so far also have their
40165636
RB
727 superclasses known to the runtime. We suppose that the objects
728 that are allocated in the +load method are in general of a class
729 declared in the same module. */
88e17b57
BE
730 if (unresolved_classes)
731 {
732 Class class = unresolved_classes->head;
733
fed2b101 734 while (objc_getClass ((char *) class->super_class))
88e17b57
BE
735 {
736 list_remove_head (&unresolved_classes);
737 if (unresolved_classes)
738 class = unresolved_classes->head;
739 else
740 break;
741 }
742
40165636
RB
743 /* If we still have classes for whom we don't have yet their
744 super classes known to the runtime we don't send the +load
745 messages. */
88e17b57
BE
746 if (unresolved_classes)
747 return;
748 }
749
1501d094
NP
750 /* Special check. If 'Object', which is used by meta-classes, has
751 not been loaded yet, delay sending of +load. */
fed2b101 752 if (! objc_getClass ("Object"))
88e17b57
BE
753 return;
754
40165636
RB
755 /* Iterate over all modules in the __objc_module_list and call on
756 them the __objc_create_classes_tree function. This function
757 creates a tree of classes that resembles the class hierarchy. */
758 list_mapcar (__objc_module_list,
759 (void (*) (void *)) __objc_create_classes_tree);
88e17b57
BE
760
761 while (__objc_class_tree_list)
762 {
763#ifdef DEBUG
764 objc_preorder_traverse (__objc_class_tree_list->head,
765 0, __objc_tree_print);
766#endif
767 objc_preorder_traverse (__objc_class_tree_list->head,
768 0, __objc_send_load);
769 objc_postorder_traverse (__objc_class_tree_list->head,
770 0, __objc_destroy_class_tree_node);
771 list_remove_head (&__objc_class_tree_list);
772 }
773
40165636 774 list_mapcar (__objc_module_list, (void (*) (void *)) __objc_call_callback);
88e17b57
BE
775 list_free (__objc_module_list);
776 __objc_module_list = NULL;
777}
778
779static void
fed2b101 780__objc_create_classes_tree (struct objc_module *module)
88e17b57 781{
575584a9 782 /* The runtime mutex is locked at this point */
fed2b101 783 struct objc_symtab *symtab = module->symtab;
88e17b57
BE
784 int i;
785
40165636
RB
786 /* Iterate thru classes defined in this module and insert them in
787 the classes tree hierarchy. */
88e17b57
BE
788 for (i = 0; i < symtab->cls_def_cnt; i++)
789 {
790 Class class = (Class) symtab->defs[i];
791
792 objc_tree_insert_class (class);
793 }
794}
795
796static void
fed2b101 797__objc_call_callback (struct objc_module *module)
88e17b57 798{
575584a9 799 /* The runtime mutex is locked at this point. */
fed2b101 800 struct objc_symtab *symtab = module->symtab;
88e17b57
BE
801 int i;
802
40165636
RB
803 /* Iterate thru classes defined in this module and call the callback
804 for each one. */
88e17b57
BE
805 for (i = 0; i < symtab->cls_def_cnt; i++)
806 {
807 Class class = (Class) symtab->defs[i];
808
40165636 809 /* Call the _objc_load_callback for this class. */
88e17b57 810 if (_objc_load_callback)
40165636 811 _objc_load_callback (class, 0);
88e17b57
BE
812 }
813
40165636
RB
814 /* Call the _objc_load_callback for categories. Don't register the
815 instance methods as class methods for categories to root classes
816 since they were already added in the class. */
88e17b57
BE
817 for (i = 0; i < symtab->cat_def_cnt; i++)
818 {
fed2b101
NP
819 struct objc_category *category = symtab->defs[i + symtab->cls_def_cnt];
820 Class class = objc_getClass (category->class_name);
821
88e17b57 822 if (_objc_load_callback)
40165636 823 _objc_load_callback (class, category);
88e17b57
BE
824 }
825}
826
40165636 827/* Sanity check the version of gcc used to compile `module'. */
40165636 828static void
fed2b101 829init_check_module_version (struct objc_module *module)
88e17b57 830{
fed2b101 831 if ((module->version != OBJC_VERSION) || (module->size != sizeof (struct objc_module)))
88e17b57 832 {
7b869986
NP
833 _objc_abort ("Module %s version %d doesn't match runtime %d\n",
834 module->name, (int)module->version, OBJC_VERSION);
88e17b57
BE
835 }
836}
837
6c5c7efd
NP
838/* __objc_init_class must be called with __objc_runtime_mutex already locked. */
839void
840__objc_init_class (Class class)
841{
842 /* Store the class in the class table and assign class numbers. */
843 __objc_add_class_to_hash (class);
844
845 /* Register all of the selectors in the class and meta class. */
846 __objc_register_selectors_from_class (class);
847 __objc_register_selectors_from_class ((Class) class->class_pointer);
848
575584a9 849 /* Install the fake dispatch tables. */
6c5c7efd
NP
850 __objc_install_premature_dtable (class);
851 __objc_install_premature_dtable (class->class_pointer);
852
853 /* Register the instance methods as class methods, this is only done
854 for root classes. */
855 __objc_register_instance_methods_to_class (class);
856
857 if (class->protocols)
858 __objc_init_protocols (class->protocols);
859}
860
f7185d47
NP
861/* __objc_init_protocol must be called with __objc_runtime_mutex
862 already locked, and the "Protocol" class already registered. */
863static void
864__objc_init_protocol (struct objc_protocol *protocol)
865{
866 static Class proto_class = 0;
867
868 if (! proto_class)
fed2b101 869 proto_class = objc_getClass ("Protocol");
f7185d47
NP
870
871 if (((size_t)protocol->class_pointer) == PROTOCOL_VERSION)
872 {
575584a9 873 /* Assign class pointer. */
f7185d47
NP
874 protocol->class_pointer = proto_class;
875
876 /* Register all the selectors in the protocol with the runtime.
877 This both registers the selectors with the right types, and
878 it also fixes up the 'struct objc_method' structures inside
879 the protocol so that each method_name (a char * as compiled
880 by the compiler) is replaced with the appropriate runtime
881 SEL. */
882 if (protocol->class_methods)
883 __objc_register_selectors_from_description_list (protocol->class_methods);
884
885 if (protocol->instance_methods)
886 __objc_register_selectors_from_description_list (protocol->instance_methods);
887
888 /* Register the protocol in the hashtable or protocols by
889 name. */
890 __objc_protocols_add_protocol (protocol->protocol_name, protocol);
891
575584a9 892 /* Init super protocols. */
f7185d47
NP
893 __objc_init_protocols (protocol->protocol_list);
894 }
895 else if (protocol->class_pointer != proto_class)
896 {
897 _objc_abort ("Version %d doesn't match runtime protocol version %d\n",
898 (int) ((char *) protocol->class_pointer
899 - (char *) 0),
900 PROTOCOL_VERSION);
901 }
902}
903
88e17b57 904static void
40165636 905__objc_init_protocols (struct objc_protocol_list *protos)
88e17b57 906{
8f8c44cb 907 size_t i;
88e17b57
BE
908 static Class proto_class = 0;
909
910 if (! protos)
911 return;
912
40165636 913 objc_mutex_lock (__objc_runtime_mutex);
88e17b57 914
40165636 915 if (! proto_class)
fed2b101 916 proto_class = objc_getClass ("Protocol");
88e17b57 917
40165636 918 if (! proto_class)
88e17b57
BE
919 {
920 unclaimed_proto_list = list_cons (protos, unclaimed_proto_list);
40165636 921 objc_mutex_unlock (__objc_runtime_mutex);
88e17b57
BE
922 return;
923 }
924
925#if 0
575584a9 926 assert (protos->next == 0); /* Only single ones allowed. */
88e17b57
BE
927#endif
928
40165636 929 for (i = 0; i < protos->count; i++)
88e17b57 930 {
40165636 931 struct objc_protocol *aProto = protos->list[i];
f7185d47 932 __objc_init_protocol (aProto);
88e17b57
BE
933 }
934
40165636 935 objc_mutex_unlock (__objc_runtime_mutex);
88e17b57
BE
936}
937
40165636
RB
938static void
939__objc_class_add_protocols (Class class, struct objc_protocol_list *protos)
88e17b57 940{
88e17b57
BE
941 if (! protos)
942 return;
943
88e17b57
BE
944 protos->next = class->protocols;
945 class->protocols = protos;
946}