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