]> gcc.gnu.org Git - gcc.git/blame - libobjc/init.c
archive.c, [...]: Include hash.h.
[gcc.git] / libobjc / init.c
CommitLineData
88e17b57 1/* GNU Objective C Runtime initialization
40165636 2 Copyright (C) 1993, 1995, 1996, 1997, 2002 Free Software Foundation, Inc.
88e17b57
BE
3 Contributed by Kresten Krab Thorup
4 +load support contributed by Ovidiu Predescu <ovidiu@net-community.com>
5
38709cad 6This file is part of GCC.
88e17b57 7
38709cad 8GCC is free software; you can redistribute it and/or modify it under the
88e17b57
BE
9terms of the GNU General Public License as published by the Free Software
10Foundation; either version 2, or (at your option) any later version.
11
38709cad 12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
88e17b57
BE
13WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
15details.
16
17You should have received a copy of the GNU General Public License along with
38709cad 18GCC; see the file COPYING. If not, write to the Free Software
88e17b57
BE
19Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
20
21/* As a special exception, if you link this library with files compiled with
22 GCC to produce an executable, this does not cause the resulting executable
23 to be covered by the GNU General Public License. This exception does not
24 however invalidate any other reasons why the executable file might be
25 covered by the GNU General Public License. */
26
348a3445 27#include "objc/runtime.h"
88e17b57
BE
28
29/* The version number of this runtime. This must match the number
40165636 30 defined in gcc (objc-act.c). */
88e17b57
BE
31#define OBJC_VERSION 8
32#define PROTOCOL_VERSION 2
33
40165636
RB
34/* This list contains all modules currently loaded into the runtime. */
35static struct objc_list *__objc_module_list = 0; /* !T:MUTEX */
88e17b57 36
40165636
RB
37/* This list contains all proto_list's not yet assigned class links. */
38static struct objc_list *unclaimed_proto_list = 0; /* !T:MUTEX */
88e17b57
BE
39
40/* List of unresolved static instances. */
41static struct objc_list *uninitialized_statics = 0; /* !T:MUTEX */
42
40165636 43/* Global runtime "write" mutex. */
88e17b57
BE
44objc_mutex_t __objc_runtime_mutex = 0;
45
40165636 46/* Number of threads that are alive. */
88e17b57
BE
47int __objc_runtime_threads_alive = 1; /* !T:MUTEX */
48
40165636 49/* Check compiler vs runtime version. */
88e17b57
BE
50static void init_check_module_version (Module_t);
51
40165636
RB
52/* Assign isa links to protos. */
53static void __objc_init_protocols (struct objc_protocol_list *protos);
88e17b57 54
40165636
RB
55/* Add protocol to class. */
56static void __objc_class_add_protocols (Class, struct objc_protocol_list *);
88e17b57 57
40165636
RB
58/* This is a hook which is called by __objc_exec_class every time a
59 class or a category is loaded into the runtime. This may e.g. help
60 a dynamic loader determine the classes that have been loaded when
61 an object file is dynamically linked in. */
62void (*_objc_load_callback) (Class class, Category *category); /* !T:SAFE */
88e17b57 63
40165636 64/* Is all categories/classes resolved? */
88e17b57
BE
65BOOL __objc_dangling_categories = NO; /* !T:UNUSED */
66
67extern SEL
68__sel_register_typed_name (const char *name, const char *types,
69 struct objc_selector *orig, BOOL is_const);
70
40165636 71/* Sends +load to all classes and categories in certain situations. */
88e17b57
BE
72static void objc_send_load (void);
73
74/* Inserts all the classes defined in module in a tree of classes that
40165636
RB
75 resembles the class hierarchy. This tree is traversed in preorder
76 and the classes in its nodes receive the +load message if these
77 methods were not executed before. The algorithm ensures that when
78 the +load method of a class is executed all the superclasses have
79 been already received the +load message. */
88e17b57
BE
80static void __objc_create_classes_tree (Module_t module);
81
82static void __objc_call_callback (Module_t module);
83
84/* A special version that works only before the classes are completely
40165636 85 installed in the runtime. */
88e17b57
BE
86static BOOL class_is_subclass_of_class (Class class, Class superclass);
87
88typedef struct objc_class_tree {
89 Class class;
90 struct objc_list *subclasses; /* `head' is pointer to an objc_class_tree */
91} objc_class_tree;
92
40165636
RB
93/* This is a linked list of objc_class_tree trees. The head of these
94 trees are root classes (their super class is Nil). These different
95 trees represent different class hierarchies. */
88e17b57
BE
96static struct objc_list *__objc_class_tree_list = NULL;
97
40165636
RB
98/* Keeps the +load methods who have been already executed. This hash
99 should not be destroyed during the execution of the program. */
88e17b57
BE
100static cache_ptr __objc_load_methods = NULL;
101
e083f3f9
RFM
102/* This function is used when building the class tree used to send
103 ordinately the +load message to all classes needing it. The tree
104 is really needed so that superclasses will get the message before
105 subclasses.
106
107 This tree will contain classes which are being loaded (or have just
108 being loaded), and whose super_class pointers have not yet been
109 resolved. This implies that their super_class pointers point to a
110 string with the name of the superclass; when the first message is
111 sent to the class (/an object of that class) the class links will
112 be resolved, which will replace the super_class pointers with
113 pointers to the actual superclasses.
114
115 Unfortunately, the tree might also contain classes which had been
116 loaded previously, and whose class links have already been
117 resolved.
118
119 This function returns the superclass of a class in both cases, and
120 can be used to build the determine the class relationships while
121 building the tree.
122*/
123static Class class_superclass_of_class (Class class)
124{
125 char *super_class_name;
126
127 /* If the class links have been resolved, use the resolved
128 * links. */
129 if (CLS_ISRESOLV (class))
130 return class->super_class;
131
132 /* Else, 'class' has not yet been resolved. This means that its
133 * super_class pointer is really the name of the super class (rather
134 * than a pointer to the actual superclass). */
135 super_class_name = (char *)class->super_class;
136
137 /* Return Nil for a root class. */
138 if (super_class_name == NULL)
139 return Nil;
140
141 /* Lookup the superclass of non-root classes. */
142 return objc_lookup_class (super_class_name);
143}
144
145
40165636
RB
146/* Creates a tree of classes whose topmost class is directly inherited
147 from `upper' and the bottom class in this tree is
148 `bottom_class'. The classes in this tree are super classes of
149 `bottom_class'. `subclasses' member of each tree node point to the
150 next subclass tree node. */
151
88e17b57
BE
152static objc_class_tree *
153create_tree_of_subclasses_inherited_from (Class bottom_class, Class upper)
154{
155 Class superclass = bottom_class->super_class ?
40165636 156 objc_lookup_class ((char *) bottom_class->super_class)
88e17b57
BE
157 : Nil;
158
159 objc_class_tree *tree, *prev;
160
161 DEBUG_PRINTF ("create_tree_of_subclasses_inherited_from:");
162 DEBUG_PRINTF ("bottom_class = %s, upper = %s\n",
163 (bottom_class ? bottom_class->name : NULL),
164 (upper ? upper->name : NULL));
165
166 tree = prev = objc_calloc (1, sizeof (objc_class_tree));
167 prev->class = bottom_class;
168
169 while (superclass != upper)
170 {
171 tree = objc_calloc (1, sizeof (objc_class_tree));
172 tree->class = superclass;
173 tree->subclasses = list_cons (prev, tree->subclasses);
e083f3f9 174 superclass = class_superclass_of_class (superclass);
88e17b57
BE
175 prev = tree;
176 }
177
178 return tree;
179}
180
40165636
RB
181/* Insert the `class' into the proper place in the `tree' class
182 hierarchy. This function returns a new tree if the class has been
183 successfully inserted into the tree or NULL if the class is not
184 part of the classes hierarchy described by `tree'. This function is
185 private to objc_tree_insert_class (), you should not call it
186 directly. */
187
88e17b57
BE
188static objc_class_tree *
189__objc_tree_insert_class (objc_class_tree *tree, Class class)
190{
191 DEBUG_PRINTF ("__objc_tree_insert_class: tree = %x, class = %s\n",
192 tree, class->name);
193
194 if (tree == NULL)
195 return create_tree_of_subclasses_inherited_from (class, NULL);
196 else if (class == tree->class)
197 {
198 /* `class' has been already inserted */
199 DEBUG_PRINTF ("1. class %s was previously inserted\n", class->name);
200 return tree;
201 }
e083f3f9 202 else if (class_superclass_of_class (class) == tree->class)
88e17b57
BE
203 {
204 /* If class is a direct subclass of tree->class then add class to the
205 list of subclasses. First check to see if it wasn't already
40165636 206 inserted. */
88e17b57
BE
207 struct objc_list *list = tree->subclasses;
208 objc_class_tree *node;
209
210 while (list)
211 {
212 /* Class has been already inserted; do nothing just return
40165636
RB
213 the tree. */
214 if (((objc_class_tree *) list->head)->class == class)
88e17b57
BE
215 {
216 DEBUG_PRINTF ("2. class %s was previously inserted\n",
217 class->name);
218 return tree;
219 }
220 list = list->tail;
221 }
222
223 /* Create a new node class and insert it into the list of subclasses */
224 node = objc_calloc (1, sizeof (objc_class_tree));
225 node->class = class;
226 tree->subclasses = list_cons (node, tree->subclasses);
227 DEBUG_PRINTF ("3. class %s inserted\n", class->name);
228 return tree;
229 }
230 else
231 {
40165636
RB
232 /* The class is not a direct subclass of tree->class. Search for
233 class's superclasses in the list of subclasses. */
88e17b57
BE
234 struct objc_list *subclasses = tree->subclasses;
235
40165636
RB
236 /* Precondition: the class must be a subclass of tree->class;
237 otherwise return NULL to indicate our caller that it must
238 take the next tree. */
239 if (! class_is_subclass_of_class (class, tree->class))
88e17b57
BE
240 return NULL;
241
242 for (; subclasses != NULL; subclasses = subclasses->tail)
243 {
40165636 244 Class aClass = ((objc_class_tree *) (subclasses->head))->class;
88e17b57
BE
245
246 if (class_is_subclass_of_class (class, aClass))
247 {
40165636
RB
248 /* If we found one of class's superclasses we insert the
249 class into its subtree and return the original tree
250 since nothing has been changed. */
88e17b57
BE
251 subclasses->head
252 = __objc_tree_insert_class (subclasses->head, class);
253 DEBUG_PRINTF ("4. class %s inserted\n", class->name);
254 return tree;
255 }
256 }
257
40165636
RB
258 /* We haven't found a subclass of `class' in the `subclasses'
259 list. Create a new tree of classes whose topmost class is a
260 direct subclass of tree->class. */
88e17b57
BE
261 {
262 objc_class_tree *new_tree
40165636 263 = create_tree_of_subclasses_inherited_from (class, tree->class);
88e17b57
BE
264 tree->subclasses = list_cons (new_tree, tree->subclasses);
265 DEBUG_PRINTF ("5. class %s inserted\n", class->name);
266 return tree;
267 }
268 }
269}
270
40165636
RB
271/* This function inserts `class' in the right tree hierarchy classes. */
272
88e17b57
BE
273static void
274objc_tree_insert_class (Class class)
275{
276 struct objc_list *list_node;
277 objc_class_tree *tree;
278
279 list_node = __objc_class_tree_list;
280 while (list_node)
281 {
282 tree = __objc_tree_insert_class (list_node->head, class);
283 if (tree)
284 {
285 list_node->head = tree;
286 break;
287 }
288 else
289 list_node = list_node->tail;
290 }
291
40165636
RB
292 /* If the list was finished but the class hasn't been inserted,
293 insert it here. */
294 if (! list_node)
88e17b57
BE
295 {
296 __objc_class_tree_list = list_cons (NULL, __objc_class_tree_list);
297 __objc_class_tree_list->head = __objc_tree_insert_class (NULL, class);
298 }
299}
300
40165636
RB
301/* Traverse tree in preorder. Used to send +load. */
302
88e17b57
BE
303static void
304objc_preorder_traverse (objc_class_tree *tree,
305 int level,
40165636 306 void (*function) (objc_class_tree *, int))
88e17b57
BE
307{
308 struct objc_list *node;
309
310 (*function) (tree, level);
311 for (node = tree->subclasses; node; node = node->tail)
312 objc_preorder_traverse (node->head, level + 1, function);
313}
314
40165636
RB
315/* Traverse tree in postorder. Used to destroy a tree. */
316
88e17b57
BE
317static void
318objc_postorder_traverse (objc_class_tree *tree,
40165636
RB
319 int level,
320 void (*function) (objc_class_tree *, int))
88e17b57
BE
321{
322 struct objc_list *node;
323
324 for (node = tree->subclasses; node; node = node->tail)
325 objc_postorder_traverse (node->head, level + 1, function);
326 (*function) (tree, level);
327}
328
40165636
RB
329/* Used to print a tree class hierarchy. */
330
88e17b57
BE
331#ifdef DEBUG
332static void
333__objc_tree_print (objc_class_tree *tree, int level)
334{
335 int i;
336
337 for (i = 0; i < level; i++)
338 printf (" ");
339 printf ("%s\n", tree->class->name);
340}
341#endif
342
40165636
RB
343/* Walks on a linked list of methods in the reverse order and executes
344 all the methods corresponding to `op' selector. Walking in the
345 reverse order assures the +load of class is executed first and then
346 +load of categories because of the way in which categories are
347 added to the class methods. */
348
88e17b57
BE
349static void
350__objc_send_message_in_list (MethodList_t method_list, Class class, SEL op)
351{
352 int i;
353
40165636 354 if (! method_list)
88e17b57
BE
355 return;
356
357 /* First execute the `op' message in the following method lists */
358 __objc_send_message_in_list (method_list->method_next, class, op);
359
40165636 360 /* Search the method list. */
88e17b57
BE
361 for (i = 0; i < method_list->method_count; i++)
362 {
363 Method_t mth = &method_list->method_list[i];
364
365 if (mth->method_name && sel_eq (mth->method_name, op)
270a1283 366 && ! objc_hash_is_key_in_hash (__objc_load_methods, mth->method_imp))
88e17b57 367 {
88e17b57 368 /* Add this method into the +load hash table */
270a1283
DA
369 objc_hash_add (&__objc_load_methods,
370 mth->method_imp,
371 mth->method_imp);
88e17b57
BE
372
373 DEBUG_PRINTF ("sending +load in class: %s\n", class->name);
374
40165636 375 /* The method was found and wasn't previously executed. */
e6be21fe
RFM
376 (*mth->method_imp) ((id)class, mth->method_name);
377
88e17b57
BE
378 break;
379 }
380 }
381}
382
383static void
8f8c44cb
KG
384__objc_send_load (objc_class_tree *tree,
385 int level __attribute__ ((__unused__)))
88e17b57
BE
386{
387 static SEL load_sel = 0;
388 Class class = tree->class;
389 MethodList_t method_list = class->class_pointer->methods;
390
40165636 391 if (! load_sel)
88e17b57
BE
392 load_sel = sel_register_name ("load");
393
394 __objc_send_message_in_list (method_list, class, load_sel);
395}
396
397static void
8f8c44cb
KG
398__objc_destroy_class_tree_node (objc_class_tree *tree,
399 int level __attribute__ ((__unused__)))
88e17b57
BE
400{
401 objc_free (tree);
402}
403
40165636
RB
404/* This is used to check if the relationship between two classes
405 before the runtime completely installs the classes. */
406
88e17b57
BE
407static BOOL
408class_is_subclass_of_class (Class class, Class superclass)
409{
410 for (; class != Nil;)
411 {
412 if (class == superclass)
413 return YES;
e083f3f9 414 class = class_superclass_of_class (class);
88e17b57
BE
415 }
416
417 return NO;
418}
419
40165636
RB
420/* This list contains all the classes in the runtime system for whom
421 their superclasses are not yet known to the runtime. */
422static struct objc_list *unresolved_classes = 0;
88e17b57 423
40165636
RB
424/* Extern function used to reference the Object and NXConstantString
425 classes. */
6000b42b
JDA
426
427extern void __objc_force_linking (void);
428
429void
88e17b57
BE
430__objc_force_linking (void)
431{
432 extern void __objc_linking (void);
433 __objc_linking ();
88e17b57
BE
434}
435
40165636
RB
436/* Run through the statics list, removing modules as soon as all its
437 statics have been initialized. */
438
88e17b57
BE
439static void
440objc_init_statics (void)
441{
442 struct objc_list **cell = &uninitialized_statics;
443 struct objc_static_instances **statics_in_module;
444
40165636 445 objc_mutex_lock (__objc_runtime_mutex);
88e17b57
BE
446
447 while (*cell)
448 {
449 int module_initialized = 1;
450
451 for (statics_in_module = (*cell)->head;
452 *statics_in_module; statics_in_module++)
453 {
454 struct objc_static_instances *statics = *statics_in_module;
455 Class class = objc_lookup_class (statics->class_name);
456
40165636 457 if (! class)
88e17b57
BE
458 module_initialized = 0;
459 /* Actually, the static's class_pointer will be NULL when we
460 haven't been here before. However, the comparison is to be
461 reminded of taking into account class posing and to think about
462 possible semantics... */
463 else if (class != statics->instances[0]->class_pointer)
464 {
465 id *inst;
466
467 for (inst = &statics->instances[0]; *inst; inst++)
468 {
469 (*inst)->class_pointer = class;
470
471 /* ??? Make sure the object will not be freed. With
472 refcounting, invoke `-retain'. Without refcounting, do
473 nothing and hope that `-free' will never be invoked. */
474
475 /* ??? Send the object an `-initStatic' or something to
476 that effect now or later on? What are the semantics of
477 statically allocated instances, besides the trivial
478 NXConstantString, anyway? */
479 }
480 }
481 }
482 if (module_initialized)
483 {
484 /* Remove this module from the uninitialized list. */
485 struct objc_list *this = *cell;
486 *cell = this->tail;
40165636 487 objc_free (this);
88e17b57
BE
488 }
489 else
490 cell = &(*cell)->tail;
491 }
492
40165636 493 objc_mutex_unlock (__objc_runtime_mutex);
88e17b57
BE
494} /* objc_init_statics */
495
496/* This function is called by constructor functions generated for each
40165636
RB
497 module compiled. (_GLOBAL_$I$...) The purpose of this function is
498 to gather the module pointers so that they may be processed by the
499 initialization routines as soon as possible. */
88e17b57
BE
500
501void
502__objc_exec_class (Module_t module)
503{
504 /* Have we processed any constructors previously? This flag is used to
505 indicate that some global data structures need to be built. */
506 static BOOL previous_constructors = 0;
507
40165636 508 static struct objc_list *unclaimed_categories = 0;
88e17b57
BE
509
510 /* The symbol table (defined in objc-api.h) generated by gcc */
511 Symtab_t symtab = module->symtab;
512
513 /* The statics in this module */
514 struct objc_static_instances **statics
515 = symtab->defs[symtab->cls_def_cnt + symtab->cat_def_cnt];
516
517 /* Entry used to traverse hash lists */
40165636 518 struct objc_list **cell;
88e17b57
BE
519
520 /* The table of selector references for this module */
521 SEL selectors = symtab->refs;
522
523 /* dummy counter */
524 int i;
525
526 DEBUG_PRINTF ("received module: %s\n", module->name);
527
528 /* check gcc version */
40165636 529 init_check_module_version (module);
88e17b57
BE
530
531 /* On the first call of this routine, initialize some data structures. */
40165636 532 if (! previous_constructors)
88e17b57
BE
533 {
534 /* Initialize thread-safe system */
40165636 535 __objc_init_thread_system ();
88e17b57 536 __objc_runtime_threads_alive = 1;
40165636 537 __objc_runtime_mutex = objc_mutex_allocate ();
88e17b57 538
40165636
RB
539 __objc_init_selector_tables ();
540 __objc_init_class_tables ();
541 __objc_init_dispatch_tables ();
88e17b57 542 __objc_class_tree_list = list_cons (NULL, __objc_class_tree_list);
270a1283
DA
543 __objc_load_methods = objc_hash_new (128,
544 (hash_func_type)objc_hash_ptr,
545 objc_compare_ptrs);
88e17b57
BE
546 previous_constructors = 1;
547 }
548
549 /* Save the module pointer for later processing. (not currently used) */
40165636
RB
550 objc_mutex_lock (__objc_runtime_mutex);
551 __objc_module_list = list_cons (module, __objc_module_list);
88e17b57
BE
552
553 /* Replace referenced selectors from names to SEL's. */
554 if (selectors)
555 {
556 for (i = 0; selectors[i].sel_id; ++i)
557 {
558 const char *name, *type;
40165636
RB
559 name = (char *) selectors[i].sel_id;
560 type = (char *) selectors[i].sel_types;
88e17b57
BE
561 /* Constructors are constant static data so we can safely store
562 pointers to them in the runtime structures. is_const == YES */
563 __sel_register_typed_name (name, type,
40165636 564 (struct objc_selector *) &(selectors[i]),
88e17b57
BE
565 YES);
566 }
567 }
568
569 /* Parse the classes in the load module and gather selector information. */
570 DEBUG_PRINTF ("gathering selectors from module: %s\n", module->name);
571 for (i = 0; i < symtab->cls_def_cnt; ++i)
572 {
573 Class class = (Class) symtab->defs[i];
40165636 574 const char *superclass = (char *) class->super_class;
88e17b57
BE
575
576 /* Make sure we have what we think. */
40165636
RB
577 assert (CLS_ISCLASS (class));
578 assert (CLS_ISMETA (class->class_pointer));
88e17b57
BE
579 DEBUG_PRINTF ("phase 1, processing class: %s\n", class->name);
580
581 /* Initialize the subclass list to be NULL.
40165636 582 In some cases it isn't and this crashes the program. */
88e17b57
BE
583 class->subclass_list = NULL;
584
585 /* Store the class in the class table and assign class numbers. */
586 __objc_add_class_to_hash (class);
587
588 /* Register all of the selectors in the class and meta class. */
589 __objc_register_selectors_from_class (class);
590 __objc_register_selectors_from_class ((Class) class->class_pointer);
591
592 /* Install the fake dispatch tables */
40165636
RB
593 __objc_install_premature_dtable (class);
594 __objc_install_premature_dtable (class->class_pointer);
88e17b57
BE
595
596 /* Register the instance methods as class methods, this is
40165636
RB
597 only done for root classes. */
598 __objc_register_instance_methods_to_class (class);
88e17b57
BE
599
600 if (class->protocols)
601 __objc_init_protocols (class->protocols);
602
603 /* Check to see if the superclass is known in this point. If it's not
40165636
RB
604 add the class to the unresolved_classes list. */
605 if (superclass && ! objc_lookup_class (superclass))
88e17b57
BE
606 unresolved_classes = list_cons (class, unresolved_classes);
607 }
608
609 /* Process category information from the module. */
610 for (i = 0; i < symtab->cat_def_cnt; ++i)
611 {
612 Category_t category = symtab->defs[i + symtab->cls_def_cnt];
613 Class class = objc_lookup_class (category->class_name);
614
615 /* If the class for the category exists then append its methods. */
616 if (class)
617 {
618
619 DEBUG_PRINTF ("processing categories from (module,object): %s, %s\n",
620 module->name,
621 class->name);
622
623 /* Do instance methods. */
624 if (category->instance_methods)
625 class_add_method_list (class, category->instance_methods);
626
627 /* Do class methods. */
628 if (category->class_methods)
629 class_add_method_list ((Class) class->class_pointer,
630 category->class_methods);
631
632 if (category->protocols)
633 {
634 __objc_init_protocols (category->protocols);
635 __objc_class_add_protocols (class, category->protocols);
636 }
637
638 /* Register the instance methods as class methods, this is
40165636
RB
639 only done for root classes. */
640 __objc_register_instance_methods_to_class (class);
88e17b57
BE
641 }
642 else
643 {
644 /* The object to which the category methods belong can't be found.
645 Save the information. */
40165636 646 unclaimed_categories = list_cons (category, unclaimed_categories);
88e17b57
BE
647 }
648 }
649
650 if (statics)
651 uninitialized_statics = list_cons (statics, uninitialized_statics);
652 if (uninitialized_statics)
653 objc_init_statics ();
654
655 /* Scan the unclaimed category hash. Attempt to attach any unclaimed
656 categories to objects. */
e5e0f6f5 657 for (cell = &unclaimed_categories; *cell; )
88e17b57
BE
658 {
659 Category_t category = (*cell)->head;
660 Class class = objc_lookup_class (category->class_name);
661
662 if (class)
663 {
664 DEBUG_PRINTF ("attaching stored categories to object: %s\n",
665 class->name);
666
667 list_remove_head (cell);
668
669 if (category->instance_methods)
670 class_add_method_list (class, category->instance_methods);
671
672 if (category->class_methods)
673 class_add_method_list ((Class) class->class_pointer,
674 category->class_methods);
675
676 if (category->protocols)
677 {
678 __objc_init_protocols (category->protocols);
679 __objc_class_add_protocols (class, category->protocols);
680 }
681
682 /* Register the instance methods as class methods, this is
40165636
RB
683 only done for root classes. */
684 __objc_register_instance_methods_to_class (class);
88e17b57 685 }
e5e0f6f5
NP
686 else
687 cell = &(*cell)->tail;
88e17b57
BE
688 }
689
690 if (unclaimed_proto_list && objc_lookup_class ("Protocol"))
691 {
40165636
RB
692 list_mapcar (unclaimed_proto_list,
693 (void (*) (void *))__objc_init_protocols);
88e17b57
BE
694 list_free (unclaimed_proto_list);
695 unclaimed_proto_list = 0;
696 }
697
698 objc_send_load ();
699
40165636 700 objc_mutex_unlock (__objc_runtime_mutex);
88e17b57
BE
701}
702
40165636
RB
703static void
704objc_send_load (void)
88e17b57 705{
40165636 706 if (! __objc_module_list)
88e17b57
BE
707 return;
708
709 /* Try to find out if all the classes loaded so far also have their
40165636
RB
710 superclasses known to the runtime. We suppose that the objects
711 that are allocated in the +load method are in general of a class
712 declared in the same module. */
88e17b57
BE
713 if (unresolved_classes)
714 {
715 Class class = unresolved_classes->head;
716
40165636 717 while (objc_lookup_class ((char *) class->super_class))
88e17b57
BE
718 {
719 list_remove_head (&unresolved_classes);
720 if (unresolved_classes)
721 class = unresolved_classes->head;
722 else
723 break;
724 }
725
40165636
RB
726 /* If we still have classes for whom we don't have yet their
727 super classes known to the runtime we don't send the +load
728 messages. */
88e17b57
BE
729 if (unresolved_classes)
730 return;
731 }
732
40165636
RB
733 /* Special check to allow creating and sending messages to constant
734 strings in +load methods. If these classes are not yet known,
735 even if all the other classes are known, delay sending of +load. */
736 if (! objc_lookup_class ("NXConstantString") ||
737 ! objc_lookup_class ("Object"))
88e17b57
BE
738 return;
739
40165636
RB
740 /* Iterate over all modules in the __objc_module_list and call on
741 them the __objc_create_classes_tree function. This function
742 creates a tree of classes that resembles the class hierarchy. */
743 list_mapcar (__objc_module_list,
744 (void (*) (void *)) __objc_create_classes_tree);
88e17b57
BE
745
746 while (__objc_class_tree_list)
747 {
748#ifdef DEBUG
749 objc_preorder_traverse (__objc_class_tree_list->head,
750 0, __objc_tree_print);
751#endif
752 objc_preorder_traverse (__objc_class_tree_list->head,
753 0, __objc_send_load);
754 objc_postorder_traverse (__objc_class_tree_list->head,
755 0, __objc_destroy_class_tree_node);
756 list_remove_head (&__objc_class_tree_list);
757 }
758
40165636 759 list_mapcar (__objc_module_list, (void (*) (void *)) __objc_call_callback);
88e17b57
BE
760 list_free (__objc_module_list);
761 __objc_module_list = NULL;
762}
763
764static void
765__objc_create_classes_tree (Module_t module)
766{
767 /* The runtime mutex is locked in this point */
768
769 Symtab_t symtab = module->symtab;
770 int i;
771
40165636
RB
772 /* Iterate thru classes defined in this module and insert them in
773 the classes tree hierarchy. */
88e17b57
BE
774 for (i = 0; i < symtab->cls_def_cnt; i++)
775 {
776 Class class = (Class) symtab->defs[i];
777
778 objc_tree_insert_class (class);
779 }
780}
781
782static void
783__objc_call_callback (Module_t module)
784{
40165636 785 /* The runtime mutex is locked in this point. */
88e17b57
BE
786
787 Symtab_t symtab = module->symtab;
788 int i;
789
40165636
RB
790 /* Iterate thru classes defined in this module and call the callback
791 for each one. */
88e17b57
BE
792 for (i = 0; i < symtab->cls_def_cnt; i++)
793 {
794 Class class = (Class) symtab->defs[i];
795
40165636 796 /* Call the _objc_load_callback for this class. */
88e17b57 797 if (_objc_load_callback)
40165636 798 _objc_load_callback (class, 0);
88e17b57
BE
799 }
800
40165636
RB
801 /* Call the _objc_load_callback for categories. Don't register the
802 instance methods as class methods for categories to root classes
803 since they were already added in the class. */
88e17b57
BE
804 for (i = 0; i < symtab->cat_def_cnt; i++)
805 {
806 Category_t category = symtab->defs[i + symtab->cls_def_cnt];
807 Class class = objc_lookup_class (category->class_name);
808
809 if (_objc_load_callback)
40165636 810 _objc_load_callback (class, category);
88e17b57
BE
811 }
812}
813
40165636
RB
814/* Sanity check the version of gcc used to compile `module'. */
815
816static void
817init_check_module_version (Module_t module)
88e17b57
BE
818{
819 if ((module->version != OBJC_VERSION) || (module->size != sizeof (Module)))
820 {
821 int code;
822
40165636 823 if (module->version > OBJC_VERSION)
88e17b57
BE
824 code = OBJC_ERR_OBJC_VERSION;
825 else if (module->version < OBJC_VERSION)
826 code = OBJC_ERR_GCC_VERSION;
827 else
828 code = OBJC_ERR_MODULE_SIZE;
829
40165636
RB
830 objc_error (nil, code, "Module %s version %d doesn't match runtime %d\n",
831 module->name, (int)module->version, OBJC_VERSION);
88e17b57
BE
832 }
833}
834
835static void
40165636 836__objc_init_protocols (struct objc_protocol_list *protos)
88e17b57 837{
8f8c44cb 838 size_t i;
88e17b57
BE
839 static Class proto_class = 0;
840
841 if (! protos)
842 return;
843
40165636 844 objc_mutex_lock (__objc_runtime_mutex);
88e17b57 845
40165636
RB
846 if (! proto_class)
847 proto_class = objc_lookup_class ("Protocol");
88e17b57 848
40165636 849 if (! proto_class)
88e17b57
BE
850 {
851 unclaimed_proto_list = list_cons (protos, unclaimed_proto_list);
40165636 852 objc_mutex_unlock (__objc_runtime_mutex);
88e17b57
BE
853 return;
854 }
855
856#if 0
857 assert (protos->next == 0); /* only single ones allowed */
858#endif
859
40165636 860 for (i = 0; i < protos->count; i++)
88e17b57 861 {
40165636 862 struct objc_protocol *aProto = protos->list[i];
88e17b57
BE
863 if (((size_t)aProto->class_pointer) == PROTOCOL_VERSION)
864 {
865 /* assign class pointer */
866 aProto->class_pointer = proto_class;
867
868 /* init super protocols */
869 __objc_init_protocols (aProto->protocol_list);
870 }
871 else if (protos->list[i]->class_pointer != proto_class)
872 {
40165636 873 objc_error (nil, OBJC_ERR_PROTOCOL_VERSION,
88e17b57 874 "Version %d doesn't match runtime protocol version %d\n",
40165636
RB
875 (int) ((char *) protos->list[i]->class_pointer
876 - (char *) 0),
88e17b57
BE
877 PROTOCOL_VERSION);
878 }
879 }
880
40165636 881 objc_mutex_unlock (__objc_runtime_mutex);
88e17b57
BE
882}
883
40165636
RB
884static void
885__objc_class_add_protocols (Class class, struct objc_protocol_list *protos)
88e17b57 886{
40165636 887 /* Well... */
88e17b57
BE
888 if (! protos)
889 return;
890
40165636 891 /* Add it... */
88e17b57
BE
892 protos->next = class->protocols;
893 class->protocols = protos;
894}
This page took 0.633758 seconds and 5 git commands to generate.