]> git.ipfire.org Git - thirdparty/gcc.git/blame - libobjc/init.c
Move 2 mklog scripts to legacy subfolder.
[thirdparty/gcc.git] / libobjc / init.c
CommitLineData
88e17b57 1/* GNU Objective C Runtime initialization
8d9254fc 2 Copyright (C) 1993-2020 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 9terms of the GNU General Public License as published by the Free Software
748086b7 10Foundation; either version 3, or (at your option) any later version.
88e17b57 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
748086b7
JJ
17Under Section 7 of GPL version 3, you are granted additional
18permissions described in the GCC Runtime Library Exception, version
193.1, as published by the Free Software Foundation.
88e17b57 20
748086b7
JJ
21You should have received a copy of the GNU General Public License and
22a copy of the GCC Runtime Library Exception along with this program;
23see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24<http://www.gnu.org/licenses/>. */
88e17b57 25
e99776d8
NP
26/* Uncommented the following line to enable debug logging. Use this
27 only while debugging the runtime. */
28/* #define DEBUG 1 */
29
6dead247 30#include "objc-private/common.h"
7b869986 31#include "objc-private/error.h"
fed2b101 32#include "objc/runtime.h"
a19fac96 33#include "objc/thr.h"
5be9cdc1
NP
34#include "objc-private/hash.h"
35#include "objc-private/objc-list.h"
fed2b101 36#include "objc-private/module-abi-8.h"
41720477 37#include "objc-private/runtime.h" /* For __objc_resolve_class_links(). */
1af5b8f5 38#include "objc-private/selector.h" /* For __sel_register_typed_name(). */
fd312537 39#include "objc-private/objc-sync.h" /* For __objc_sync_init() */
f7185d47
NP
40#include "objc-private/protocols.h" /* For __objc_protocols_init(),
41 __objc_protocols_add_protocol()
42 __objc_protocols_register_selectors() */
682e805a 43#include "objc-private/accessors.h" /* For __objc_accessors_init() */
88e17b57 44
575584a9 45/* The version number of this runtime. This must match the number
40165636 46 defined in gcc (objc-act.c). */
88e17b57
BE
47#define OBJC_VERSION 8
48#define PROTOCOL_VERSION 2
49
c07499dc 50/* This list contains modules currently loaded into the runtime and
1588200e
NP
51 for which the +load method (and the load callback, if any) has not
52 been called yet. */
40165636 53static struct objc_list *__objc_module_list = 0; /* !T:MUTEX */
88e17b57 54
575584a9
NP
55/* This list contains all proto_list's not yet assigned class
56 links. */
40165636 57static struct objc_list *unclaimed_proto_list = 0; /* !T:MUTEX */
88e17b57
BE
58
59/* List of unresolved static instances. */
60static struct objc_list *uninitialized_statics = 0; /* !T:MUTEX */
61
0bfe3fa1
NP
62/* List of duplicated classes found while loading modules. If we find
63 a class twice, we ignore it the second time. On some platforms,
64 where the order in which modules are loaded is well defined, this
65 allows you to replace a class in a shared library by linking in a
66 new implementation which is loaded in in the right order, and which
67 overrides the existing one.
68
69 Protected by __objc_runtime_mutex. */
70static cache_ptr duplicate_classes = NULL;
71
debfbfee
NP
72/* Global runtime "write" mutex. Having a single mutex prevents
73 deadlocks, but reduces concurrency. To improve concurrency, some
74 groups of functions in the runtime have their own separate mutex
75 (eg, __class_table_lock in class.c); to avoid deadlocks, these
76 routines must make sure that they never acquire any other lock
77 while holding their own local lock. Ie, they should lock, execute
78 some C code that does not perform any calls to other runtime
79 functions which may potentially lock different locks, then unlock.
80 If they need to perform any calls to other runtime functions that
81 may potentially lock other locks, then they should use the global
82 __objc_runtime_mutex. */
88e17b57
BE
83objc_mutex_t __objc_runtime_mutex = 0;
84
40165636 85/* Number of threads that are alive. */
88e17b57
BE
86int __objc_runtime_threads_alive = 1; /* !T:MUTEX */
87
40165636 88/* Check compiler vs runtime version. */
fed2b101 89static void init_check_module_version (struct objc_module *);
88e17b57 90
40165636
RB
91/* Assign isa links to protos. */
92static void __objc_init_protocols (struct objc_protocol_list *protos);
88e17b57 93
f7185d47
NP
94/* Assign isa link to a protocol, and register it. */
95static void __objc_init_protocol (struct objc_protocol *protocol);
96
40165636
RB
97/* Add protocol to class. */
98static void __objc_class_add_protocols (Class, struct objc_protocol_list *);
88e17b57 99
120d5f8e 100/* Load callback hook. */
1588200e 101void (*_objc_load_callback) (Class class, struct objc_category *category) = 0; /* !T:SAFE */
88e17b57 102
0bfe3fa1 103/* Are all categories/classes resolved ? */
88e17b57
BE
104BOOL __objc_dangling_categories = NO; /* !T:UNUSED */
105
575584a9
NP
106/* Sends +load to all classes and categories in certain
107 situations. */
88e17b57
BE
108static void objc_send_load (void);
109
110/* Inserts all the classes defined in module in a tree of classes that
fa539f51 111 resembles the class hierarchy. This tree is traversed in preorder
40165636 112 and the classes in its nodes receive the +load message if these
fa539f51 113 methods were not executed before. The algorithm ensures that when
40165636
RB
114 the +load method of a class is executed all the superclasses have
115 been already received the +load message. */
fed2b101 116static void __objc_create_classes_tree (struct objc_module *module);
88e17b57 117
1588200e
NP
118/* Calls the _objc_load_callback for each class and category in the
119 module (if _objc_load_callback is not NULL). */
120static void __objc_call_load_callback (struct objc_module *module);
88e17b57
BE
121
122/* A special version that works only before the classes are completely
40165636 123 installed in the runtime. */
88e17b57
BE
124static BOOL class_is_subclass_of_class (Class class, Class superclass);
125
fa539f51
NP
126/* This is a node in the class tree hierarchy used to send +load
127 messages. */
0bfe3fa1
NP
128typedef struct objc_class_tree
129{
fa539f51 130 /* The class corresponding to the node. */
88e17b57 131 Class class;
fa539f51
NP
132
133 /* This is a linked list of all the direct subclasses of this class.
134 'head' points to a subclass node; 'tail' points to the next
135 objc_list node (whose 'head' points to another subclass node,
136 etc). */
137 struct objc_list *subclasses;
88e17b57
BE
138} objc_class_tree;
139
fa539f51
NP
140/* This is a linked list of objc_class_tree trees. The head of these
141 trees are root classes (their super class is Nil). These different
40165636 142 trees represent different class hierarchies. */
88e17b57
BE
143static struct objc_list *__objc_class_tree_list = NULL;
144
40165636
RB
145/* Keeps the +load methods who have been already executed. This hash
146 should not be destroyed during the execution of the program. */
88e17b57
BE
147static cache_ptr __objc_load_methods = NULL;
148
e083f3f9
RFM
149/* This function is used when building the class tree used to send
150 ordinately the +load message to all classes needing it. The tree
151 is really needed so that superclasses will get the message before
152 subclasses.
153
fa539f51 154 This tree may contain classes which are being loaded (or have just
e083f3f9
RFM
155 being loaded), and whose super_class pointers have not yet been
156 resolved. This implies that their super_class pointers point to a
157 string with the name of the superclass; when the first message is
158 sent to the class (/an object of that class) the class links will
159 be resolved, which will replace the super_class pointers with
160 pointers to the actual superclasses.
161
162 Unfortunately, the tree might also contain classes which had been
163 loaded previously, and whose class links have already been
164 resolved.
165
166 This function returns the superclass of a class in both cases, and
167 can be used to build the determine the class relationships while
575584a9 168 building the tree. */
e083f3f9
RFM
169static Class class_superclass_of_class (Class class)
170{
171 char *super_class_name;
172
173 /* If the class links have been resolved, use the resolved
575584a9 174 links. */
e083f3f9
RFM
175 if (CLS_ISRESOLV (class))
176 return class->super_class;
177
178 /* Else, 'class' has not yet been resolved. This means that its
575584a9
NP
179 super_class pointer is really the name of the super class (rather
180 than a pointer to the actual superclass). */
e083f3f9
RFM
181 super_class_name = (char *)class->super_class;
182
183 /* Return Nil for a root class. */
184 if (super_class_name == NULL)
185 return Nil;
186
187 /* Lookup the superclass of non-root classes. */
fed2b101 188 return objc_getClass (super_class_name);
e083f3f9
RFM
189}
190
191
40165636 192/* Creates a tree of classes whose topmost class is directly inherited
fa539f51
NP
193 from `upper' and the bottom class in this tree is `bottom_class'.
194 If `upper' is Nil, creates a class hierarchy up to a root class.
195 The classes in this tree are super classes of `bottom_class'. The
196 `subclasses' member of each tree node point to the list of
197 subclasses for the node. */
88e17b57
BE
198static objc_class_tree *
199create_tree_of_subclasses_inherited_from (Class bottom_class, Class upper)
200{
fed2b101 201 Class superclass;
88e17b57
BE
202 objc_class_tree *tree, *prev;
203
204 DEBUG_PRINTF ("create_tree_of_subclasses_inherited_from:");
e99776d8 205 DEBUG_PRINTF (" bottom_class = %s, upper = %s\n",
88e17b57
BE
206 (bottom_class ? bottom_class->name : NULL),
207 (upper ? upper->name : NULL));
208
fa539f51
NP
209 superclass = class_superclass_of_class (bottom_class);
210
211 prev = objc_calloc (1, sizeof (objc_class_tree));
88e17b57
BE
212 prev->class = bottom_class;
213
fa539f51
NP
214 if (superclass == upper)
215 return prev;
216
88e17b57
BE
217 while (superclass != upper)
218 {
219 tree = objc_calloc (1, sizeof (objc_class_tree));
220 tree->class = superclass;
221 tree->subclasses = list_cons (prev, tree->subclasses);
e083f3f9 222 superclass = class_superclass_of_class (superclass);
88e17b57
BE
223 prev = tree;
224 }
225
226 return tree;
227}
228
40165636 229/* Insert the `class' into the proper place in the `tree' class
fa539f51 230 hierarchy. This function returns a new tree if the class has been
40165636 231 successfully inserted into the tree or NULL if the class is not
fa539f51
NP
232 part of the classes hierarchy described by `tree'. This function
233 is private to objc_tree_insert_class (), you should not call it
40165636 234 directly. */
88e17b57
BE
235static objc_class_tree *
236__objc_tree_insert_class (objc_class_tree *tree, Class class)
237{
fa539f51
NP
238 DEBUG_PRINTF ("__objc_tree_insert_class: tree = %p (root: %s), class = %s\n",
239 tree, ((tree && tree->class) ? tree->class->name : "Nil"), class->name);
88e17b57
BE
240
241 if (tree == NULL)
242 return create_tree_of_subclasses_inherited_from (class, NULL);
243 else if (class == tree->class)
244 {
575584a9 245 /* `class' has been already inserted. */
e99776d8 246 DEBUG_PRINTF (" 1. class %s was previously inserted\n", class->name);
88e17b57
BE
247 return tree;
248 }
e083f3f9 249 else if (class_superclass_of_class (class) == tree->class)
88e17b57 250 {
575584a9
NP
251 /* If class is a direct subclass of tree->class then add class
252 to the list of subclasses. First check to see if it wasn't
253 already inserted. */
88e17b57
BE
254 struct objc_list *list = tree->subclasses;
255 objc_class_tree *node;
256
257 while (list)
258 {
259 /* Class has been already inserted; do nothing just return
40165636
RB
260 the tree. */
261 if (((objc_class_tree *) list->head)->class == class)
88e17b57 262 {
e99776d8 263 DEBUG_PRINTF (" 2. class %s was previously inserted\n",
88e17b57
BE
264 class->name);
265 return tree;
266 }
267 list = list->tail;
268 }
269
575584a9
NP
270 /* Create a new node class and insert it into the list of
271 subclasses. */
88e17b57
BE
272 node = objc_calloc (1, sizeof (objc_class_tree));
273 node->class = class;
274 tree->subclasses = list_cons (node, tree->subclasses);
e99776d8 275 DEBUG_PRINTF (" 3. class %s inserted\n", class->name);
88e17b57
BE
276 return tree;
277 }
278 else
279 {
575584a9
NP
280 /* The class is not a direct subclass of tree->class. Search
281 for class's superclasses in the list of subclasses. */
88e17b57
BE
282 struct objc_list *subclasses = tree->subclasses;
283
40165636
RB
284 /* Precondition: the class must be a subclass of tree->class;
285 otherwise return NULL to indicate our caller that it must
286 take the next tree. */
287 if (! class_is_subclass_of_class (class, tree->class))
88e17b57
BE
288 return NULL;
289
290 for (; subclasses != NULL; subclasses = subclasses->tail)
291 {
40165636 292 Class aClass = ((objc_class_tree *) (subclasses->head))->class;
88e17b57
BE
293
294 if (class_is_subclass_of_class (class, aClass))
295 {
40165636
RB
296 /* If we found one of class's superclasses we insert the
297 class into its subtree and return the original tree
298 since nothing has been changed. */
88e17b57
BE
299 subclasses->head
300 = __objc_tree_insert_class (subclasses->head, class);
e99776d8 301 DEBUG_PRINTF (" 4. class %s inserted\n", class->name);
88e17b57
BE
302 return tree;
303 }
304 }
305
40165636
RB
306 /* We haven't found a subclass of `class' in the `subclasses'
307 list. Create a new tree of classes whose topmost class is a
308 direct subclass of tree->class. */
88e17b57
BE
309 {
310 objc_class_tree *new_tree
40165636 311 = create_tree_of_subclasses_inherited_from (class, tree->class);
88e17b57 312 tree->subclasses = list_cons (new_tree, tree->subclasses);
e99776d8 313 DEBUG_PRINTF (" 5. class %s inserted\n", class->name);
88e17b57
BE
314 return tree;
315 }
316 }
317}
318
40165636 319/* This function inserts `class' in the right tree hierarchy classes. */
88e17b57
BE
320static void
321objc_tree_insert_class (Class class)
322{
323 struct objc_list *list_node;
324 objc_class_tree *tree;
fa539f51 325
88e17b57
BE
326 list_node = __objc_class_tree_list;
327 while (list_node)
328 {
fa539f51 329 /* Try to insert the class in this class hierarchy. */
88e17b57
BE
330 tree = __objc_tree_insert_class (list_node->head, class);
331 if (tree)
332 {
333 list_node->head = tree;
fa539f51 334 return;
88e17b57
BE
335 }
336 else
337 list_node = list_node->tail;
338 }
fa539f51
NP
339
340 /* If the list was finished but the class hasn't been inserted, we
cad10e05 341 don't have an existing class hierarchy that can accommodate it.
fa539f51
NP
342 Create a new one. */
343 __objc_class_tree_list = list_cons (NULL, __objc_class_tree_list);
344 __objc_class_tree_list->head = __objc_tree_insert_class (NULL, class);
88e17b57
BE
345}
346
40165636 347/* Traverse tree in preorder. Used to send +load. */
88e17b57
BE
348static void
349objc_preorder_traverse (objc_class_tree *tree,
350 int level,
40165636 351 void (*function) (objc_class_tree *, int))
88e17b57
BE
352{
353 struct objc_list *node;
354
355 (*function) (tree, level);
356 for (node = tree->subclasses; node; node = node->tail)
357 objc_preorder_traverse (node->head, level + 1, function);
358}
359
40165636 360/* Traverse tree in postorder. Used to destroy a tree. */
88e17b57
BE
361static void
362objc_postorder_traverse (objc_class_tree *tree,
40165636
RB
363 int level,
364 void (*function) (objc_class_tree *, int))
88e17b57
BE
365{
366 struct objc_list *node;
367
368 for (node = tree->subclasses; node; node = node->tail)
369 objc_postorder_traverse (node->head, level + 1, function);
370 (*function) (tree, level);
371}
372
40165636 373/* Used to print a tree class hierarchy. */
88e17b57
BE
374#ifdef DEBUG
375static void
376__objc_tree_print (objc_class_tree *tree, int level)
377{
378 int i;
379
380 for (i = 0; i < level; i++)
381 printf (" ");
382 printf ("%s\n", tree->class->name);
383}
384#endif
385
40165636 386/* Walks on a linked list of methods in the reverse order and executes
c07499dc
NP
387 all the methods corresponding to the `+load' selector. Walking in
388 the reverse order assures the +load of class is executed first and
389 then +load of categories because of the way in which categories are
390 added to the class methods. This function needs to be called with
391 the objc_runtime_mutex locked. */
88e17b57 392static void
c07499dc 393__objc_send_load_using_method_list (struct objc_method_list *method_list, Class class)
88e17b57 394{
c07499dc 395 static SEL load_selector = 0;
88e17b57
BE
396 int i;
397
c07499dc 398 if (!method_list)
88e17b57
BE
399 return;
400
c07499dc
NP
401 /* This needs no lock protection because we are called with the
402 objc_runtime_mutex locked. */
403 if (!load_selector)
404 load_selector = sel_registerName ("load");
405
406 /* method_list is a linked list of method lists; since we're
407 executing in reverse order, we need to do the next list before we
408 do this one. */
409 __objc_send_load_using_method_list (method_list->method_next, class);
88e17b57 410
40165636 411 /* Search the method list. */
88e17b57
BE
412 for (i = 0; i < method_list->method_count; i++)
413 {
fed2b101 414 struct objc_method *mth = &method_list->method_list[i];
88e17b57 415
c07499dc
NP
416 /* We are searching for +load methods that we haven't executed
417 yet. */
418 if (mth->method_name && sel_eq (mth->method_name, load_selector)
270a1283 419 && ! objc_hash_is_key_in_hash (__objc_load_methods, mth->method_imp))
88e17b57 420 {
c07499dc
NP
421 /* Add this method into the +load hash table, so we won't
422 execute it again next time. */
270a1283
DA
423 objc_hash_add (&__objc_load_methods,
424 mth->method_imp,
425 mth->method_imp);
575584a9 426
c07499dc 427 /* Call +load. */
e99776d8 428 DEBUG_PRINTF (" begin of [%s +load]\n", class->name);
e6be21fe 429 (*mth->method_imp) ((id)class, mth->method_name);
e99776d8 430 DEBUG_PRINTF (" end of [%s +load]\n", class->name);
e6be21fe 431
88e17b57
BE
432 break;
433 }
434 }
435}
436
c07499dc
NP
437/* This function needs to be called with the objc_runtime_mutex
438 locked. */
88e17b57 439static void
8f8c44cb
KG
440__objc_send_load (objc_class_tree *tree,
441 int level __attribute__ ((__unused__)))
88e17b57 442{
88e17b57 443 Class class = tree->class;
fed2b101 444 struct objc_method_list *method_list = class->class_pointer->methods;
88e17b57 445
e99776d8 446 DEBUG_PRINTF ("+load: need to send load to class '%s'\n", class->name);
c07499dc 447 __objc_send_load_using_method_list (method_list, class);
88e17b57
BE
448}
449
450static void
8f8c44cb
KG
451__objc_destroy_class_tree_node (objc_class_tree *tree,
452 int level __attribute__ ((__unused__)))
88e17b57
BE
453{
454 objc_free (tree);
455}
456
40165636
RB
457/* This is used to check if the relationship between two classes
458 before the runtime completely installs the classes. */
88e17b57
BE
459static BOOL
460class_is_subclass_of_class (Class class, Class superclass)
461{
462 for (; class != Nil;)
463 {
464 if (class == superclass)
465 return YES;
e083f3f9 466 class = class_superclass_of_class (class);
88e17b57
BE
467 }
468
469 return NO;
470}
471
40165636
RB
472/* This list contains all the classes in the runtime system for whom
473 their superclasses are not yet known to the runtime. */
474static struct objc_list *unresolved_classes = 0;
88e17b57 475
1501d094 476/* Extern function used to reference the Object class. */
6000b42b
JDA
477extern void __objc_force_linking (void);
478
479void
88e17b57
BE
480__objc_force_linking (void)
481{
482 extern void __objc_linking (void);
483 __objc_linking ();
88e17b57
BE
484}
485
40165636
RB
486/* Run through the statics list, removing modules as soon as all its
487 statics have been initialized. */
88e17b57
BE
488static void
489objc_init_statics (void)
490{
491 struct objc_list **cell = &uninitialized_statics;
492 struct objc_static_instances **statics_in_module;
493
40165636 494 objc_mutex_lock (__objc_runtime_mutex);
88e17b57
BE
495
496 while (*cell)
497 {
498 int module_initialized = 1;
499
500 for (statics_in_module = (*cell)->head;
501 *statics_in_module; statics_in_module++)
502 {
503 struct objc_static_instances *statics = *statics_in_module;
fed2b101 504 Class class = objc_getClass (statics->class_name);
88e17b57 505
40165636 506 if (! class)
88e17b57 507 {
5254c66b
NP
508 /* It is unfortunate that this will cause all the
509 statics initialization to be done again (eg, if we
510 already initialized constant strings, and are now
511 initializing protocols, setting module_initialized to
512 0 would cause constant strings to be initialized
513 again). It would be good to be able to track if we
514 have already initialized some of them. */
515 module_initialized = 0;
516 }
517 else
518 {
519 /* Note that if this is a list of Protocol objects, some
520 of them may have been initialized already (because
521 they were attached to classes or categories, and the
522 class/category loading code automatically fixes them
523 up), and some of them may not. We really need to go
f7185d47
NP
524 through the whole list to be sure! Protocols are
525 also special because we want to register them and
526 register all their selectors. */
88e17b57
BE
527 id *inst;
528
f7185d47
NP
529 if (strcmp (statics->class_name, "Protocol") == 0)
530 {
531 /* Protocols are special, because not only we want
532 to fix up their class pointers, but we also want
533 to register them and their selectors with the
534 runtime. */
535 for (inst = &statics->instances[0]; *inst; inst++)
536 __objc_init_protocol ((struct objc_protocol *)*inst);
537 }
538 else
539 {
575584a9
NP
540 /* Other static instances (typically constant
541 strings) are easier as we just fix up their class
542 pointers. */
f7185d47
NP
543 for (inst = &statics->instances[0]; *inst; inst++)
544 (*inst)->class_pointer = class;
545 }
88e17b57
BE
546 }
547 }
548 if (module_initialized)
549 {
550 /* Remove this module from the uninitialized list. */
551 struct objc_list *this = *cell;
552 *cell = this->tail;
40165636 553 objc_free (this);
88e17b57
BE
554 }
555 else
556 cell = &(*cell)->tail;
557 }
558
40165636 559 objc_mutex_unlock (__objc_runtime_mutex);
575584a9 560}
88e17b57
BE
561
562/* This function is called by constructor functions generated for each
40165636
RB
563 module compiled. (_GLOBAL_$I$...) The purpose of this function is
564 to gather the module pointers so that they may be processed by the
565 initialization routines as soon as possible. */
88e17b57 566void
fed2b101 567__objc_exec_class (struct objc_module *module)
88e17b57 568{
fed2b101
NP
569 /* Have we processed any constructors previously? This flag is used
570 to indicate that some global data structures need to be
571 built. */
88e17b57
BE
572 static BOOL previous_constructors = 0;
573
40165636 574 static struct objc_list *unclaimed_categories = 0;
88e17b57 575
fed2b101
NP
576 /* The symbol table (defined in objc-private/module-abi-8.h)
577 generated by gcc. */
578 struct objc_symtab *symtab = module->symtab;
88e17b57 579
fed2b101 580 /* The statics in this module. */
88e17b57
BE
581 struct objc_static_instances **statics
582 = symtab->defs[symtab->cls_def_cnt + symtab->cat_def_cnt];
583
fed2b101 584 /* Entry used to traverse hash lists. */
40165636 585 struct objc_list **cell;
88e17b57 586
fed2b101 587 /* The table of selector references for this module. */
600cbba2 588 struct objc_selector *selectors = symtab->refs;
88e17b57 589
88e17b57
BE
590 int i;
591
e99776d8 592 DEBUG_PRINTF ("\n__objc_exec_class (%p) - start processing module...\n", module);
88e17b57 593
575584a9 594 /* Check gcc version. */
40165636 595 init_check_module_version (module);
88e17b57 596
575584a9
NP
597 /* On the first call of this routine, initialize some data
598 structures. */
40165636 599 if (! previous_constructors)
88e17b57 600 {
575584a9 601 /* Initialize thread-safe system. */
40165636 602 __objc_init_thread_system ();
88e17b57 603 __objc_runtime_threads_alive = 1;
40165636 604 __objc_runtime_mutex = objc_mutex_allocate ();
88e17b57 605
40165636
RB
606 __objc_init_selector_tables ();
607 __objc_init_class_tables ();
608 __objc_init_dispatch_tables ();
0bfe3fa1
NP
609 duplicate_classes = objc_hash_new (8,
610 (hash_func_type)objc_hash_ptr,
611 objc_compare_ptrs);
270a1283
DA
612 __objc_load_methods = objc_hash_new (128,
613 (hash_func_type)objc_hash_ptr,
614 objc_compare_ptrs);
debfbfee 615 __objc_protocols_init ();
682e805a 616 __objc_accessors_init ();
fd312537 617 __objc_sync_init ();
88e17b57
BE
618 previous_constructors = 1;
619 }
620
c07499dc
NP
621 /* Save the module pointer so that later we remember to call +load
622 on all classes and categories on it. */
40165636
RB
623 objc_mutex_lock (__objc_runtime_mutex);
624 __objc_module_list = list_cons (module, __objc_module_list);
88e17b57 625
600cbba2 626 /* Replace referenced selectors from names to SELs. */
88e17b57 627 if (selectors)
e99776d8
NP
628 {
629 DEBUG_PRINTF (" registering selectors\n");
630 __objc_register_selectors_from_module (selectors);
631 }
88e17b57 632
575584a9
NP
633 /* Parse the classes in the load module and gather selector
634 information. */
88e17b57
BE
635 for (i = 0; i < symtab->cls_def_cnt; ++i)
636 {
637 Class class = (Class) symtab->defs[i];
40165636 638 const char *superclass = (char *) class->super_class;
88e17b57
BE
639
640 /* Make sure we have what we think. */
40165636
RB
641 assert (CLS_ISCLASS (class));
642 assert (CLS_ISMETA (class->class_pointer));
e99776d8 643 DEBUG_PRINTF (" installing class '%s'\n", class->name);
88e17b57 644
b4a50e43
NP
645 /* Workaround for a bug in clang: Clang may set flags other than
646 _CLS_CLASS and _CLS_META even when compiling for the
647 traditional ABI (version 8), confusing our runtime. Try to
648 wipe these flags out. */
649 if (CLS_ISCLASS (class))
650 __CLS_INFO (class) = _CLS_CLASS;
651 else
652 __CLS_INFO (class) = _CLS_META;
653
575584a9
NP
654 /* Initialize the subclass list to be NULL. In some cases it
655 isn't and this crashes the program. */
88e17b57
BE
656 class->subclass_list = NULL;
657
0bfe3fa1
NP
658 if (__objc_init_class (class))
659 {
660 /* Check to see if the superclass is known in this point. If
661 it's not add the class to the unresolved_classes list. */
662 if (superclass && ! objc_getClass (superclass))
663 unresolved_classes = list_cons (class, unresolved_classes);
664 }
665 }
88e17b57
BE
666
667 /* Process category information from the module. */
668 for (i = 0; i < symtab->cat_def_cnt; ++i)
669 {
fed2b101
NP
670 struct objc_category *category = symtab->defs[i + symtab->cls_def_cnt];
671 Class class = objc_getClass (category->class_name);
88e17b57 672
575584a9
NP
673 /* If the class for the category exists then append its
674 methods. */
88e17b57
BE
675 if (class)
676 {
e99776d8 677 DEBUG_PRINTF (" installing category '%s (%s)'\n", category->class_name, category->category_name);
88e17b57
BE
678 /* Do instance methods. */
679 if (category->instance_methods)
680 class_add_method_list (class, category->instance_methods);
681
682 /* Do class methods. */
683 if (category->class_methods)
684 class_add_method_list ((Class) class->class_pointer,
685 category->class_methods);
686
687 if (category->protocols)
688 {
689 __objc_init_protocols (category->protocols);
690 __objc_class_add_protocols (class, category->protocols);
691 }
692
693 /* Register the instance methods as class methods, this is
40165636
RB
694 only done for root classes. */
695 __objc_register_instance_methods_to_class (class);
88e17b57
BE
696 }
697 else
698 {
e99776d8 699 DEBUG_PRINTF (" delaying installation of category '%s (%s)'\n", category->class_name, category->category_name);
575584a9
NP
700 /* The object to which the category methods belong can't be
701 found. Save the information. */
40165636 702 unclaimed_categories = list_cons (category, unclaimed_categories);
88e17b57
BE
703 }
704 }
705
706 if (statics)
707 uninitialized_statics = list_cons (statics, uninitialized_statics);
708 if (uninitialized_statics)
709 objc_init_statics ();
710
575584a9
NP
711 /* Scan the unclaimed category hash. Attempt to attach any
712 unclaimed categories to objects. */
e5e0f6f5 713 for (cell = &unclaimed_categories; *cell; )
88e17b57 714 {
fed2b101
NP
715 struct objc_category *category = (*cell)->head;
716 Class class = objc_getClass (category->class_name);
88e17b57
BE
717
718 if (class)
719 {
e99776d8 720 DEBUG_PRINTF (" installing (delayed) category '%s (%s)'\n", category->class_name, category->category_name);
88e17b57
BE
721 list_remove_head (cell);
722
723 if (category->instance_methods)
724 class_add_method_list (class, category->instance_methods);
725
726 if (category->class_methods)
727 class_add_method_list ((Class) class->class_pointer,
728 category->class_methods);
729
730 if (category->protocols)
731 {
732 __objc_init_protocols (category->protocols);
733 __objc_class_add_protocols (class, category->protocols);
734 }
735
736 /* Register the instance methods as class methods, this is
40165636
RB
737 only done for root classes. */
738 __objc_register_instance_methods_to_class (class);
88e17b57 739 }
e5e0f6f5
NP
740 else
741 cell = &(*cell)->tail;
88e17b57
BE
742 }
743
fed2b101 744 if (unclaimed_proto_list && objc_getClass ("Protocol"))
88e17b57 745 {
40165636
RB
746 list_mapcar (unclaimed_proto_list,
747 (void (*) (void *))__objc_init_protocols);
88e17b57
BE
748 list_free (unclaimed_proto_list);
749 unclaimed_proto_list = 0;
750 }
751
752 objc_send_load ();
753
41720477
NP
754 /* Check if there are no unresolved classes (ie, classes whose
755 superclass has not been loaded yet) and that the 'Object' class,
756 used as the class of classes, exist. If so, it is worth
757 "resolving the class links" at this point, which will setup all
758 the class/superclass pointers. */
759 if (!unresolved_classes && objc_getClass ("Object"))
e99776d8
NP
760 {
761 DEBUG_PRINTF (" resolving class links\n");
762 __objc_resolve_class_links ();
763 }
120d5f8e 764
41720477 765 objc_mutex_unlock (__objc_runtime_mutex);
e99776d8
NP
766
767 DEBUG_PRINTF ("__objc_exec_class (%p) - finished processing module...\n\n", module);
88e17b57
BE
768}
769
c07499dc
NP
770/* This function needs to be called with the objc_runtime_mutex
771 locked. */
40165636
RB
772static void
773objc_send_load (void)
88e17b57 774{
c07499dc 775 if (!__objc_module_list)
88e17b57
BE
776 return;
777
778 /* Try to find out if all the classes loaded so far also have their
c07499dc 779 superclasses known to the runtime. We suppose that the objects
40165636
RB
780 that are allocated in the +load method are in general of a class
781 declared in the same module. */
88e17b57
BE
782 if (unresolved_classes)
783 {
784 Class class = unresolved_classes->head;
785
fed2b101 786 while (objc_getClass ((char *) class->super_class))
88e17b57
BE
787 {
788 list_remove_head (&unresolved_classes);
789 if (unresolved_classes)
790 class = unresolved_classes->head;
791 else
792 break;
793 }
794
40165636
RB
795 /* If we still have classes for whom we don't have yet their
796 super classes known to the runtime we don't send the +load
1588200e 797 messages (and call the load callback) yet. */
88e17b57
BE
798 if (unresolved_classes)
799 return;
800 }
801
1501d094
NP
802 /* Special check. If 'Object', which is used by meta-classes, has
803 not been loaded yet, delay sending of +load. */
fed2b101 804 if (! objc_getClass ("Object"))
88e17b57
BE
805 return;
806
40165636 807 /* Iterate over all modules in the __objc_module_list and call on
1588200e 808 them the __objc_create_classes_tree function. This function
40165636
RB
809 creates a tree of classes that resembles the class hierarchy. */
810 list_mapcar (__objc_module_list,
811 (void (*) (void *)) __objc_create_classes_tree);
88e17b57
BE
812
813 while (__objc_class_tree_list)
814 {
815#ifdef DEBUG
816 objc_preorder_traverse (__objc_class_tree_list->head,
817 0, __objc_tree_print);
818#endif
819 objc_preorder_traverse (__objc_class_tree_list->head,
820 0, __objc_send_load);
821 objc_postorder_traverse (__objc_class_tree_list->head,
822 0, __objc_destroy_class_tree_node);
823 list_remove_head (&__objc_class_tree_list);
824 }
825
1588200e
NP
826 /* For each module, call the _objc_load_callback if any is
827 defined. */
828 list_mapcar (__objc_module_list, (void (*) (void *)) __objc_call_load_callback);
829
830 /* Empty the list of modules. */
88e17b57
BE
831 list_free (__objc_module_list);
832 __objc_module_list = NULL;
833}
834
835static void
fed2b101 836__objc_create_classes_tree (struct objc_module *module)
88e17b57 837{
575584a9 838 /* The runtime mutex is locked at this point */
fed2b101 839 struct objc_symtab *symtab = module->symtab;
88e17b57
BE
840 int i;
841
cad10e05 842 /* Iterate through classes defined in this module and insert them in
40165636 843 the classes tree hierarchy. */
88e17b57
BE
844 for (i = 0; i < symtab->cls_def_cnt; i++)
845 {
846 Class class = (Class) symtab->defs[i];
847
0bfe3fa1
NP
848 if (!objc_hash_is_key_in_hash (duplicate_classes, class))
849 objc_tree_insert_class (class);
88e17b57 850 }
c07499dc
NP
851
852 /* Now iterate over "claimed" categories too (ie, categories that
853 extend a class that has already been loaded by the runtime), and
854 insert them in the classes tree hiearchy too. Otherwise, if you
855 add a category, its +load method would not be called if the class
856 is already loaded in the runtime. It the category is
857 "unclaimed", ie, we haven't loaded the main class yet, postpone
858 sending +load as we want to execute +load from the class before
859 we execute the one from the category. */
860 for (i = 0; i < symtab->cat_def_cnt; ++i)
861 {
862 struct objc_category *category = symtab->defs[i + symtab->cls_def_cnt];
863 Class class = objc_getClass (category->class_name);
864
865 /* If the class for the category exists then append its
866 methods. */
867 if (class)
868 objc_tree_insert_class (class);
869 }
88e17b57
BE
870}
871
872static void
1588200e 873__objc_call_load_callback (struct objc_module *module)
88e17b57 874{
1588200e 875 if (_objc_load_callback)
88e17b57 876 {
1588200e
NP
877 /* The runtime mutex is locked at this point. */
878 struct objc_symtab *symtab = module->symtab;
879 int i;
880
cad10e05 881 /* Iterate through classes defined in this module and call the callback
1588200e
NP
882 for each one. */
883 for (i = 0; i < symtab->cls_def_cnt; i++)
884 {
885 Class class = (Class) symtab->defs[i];
0bfe3fa1
NP
886
887 if (!objc_hash_is_key_in_hash (duplicate_classes, class))
888 {
889 /* Call the _objc_load_callback for this class. */
e99776d8 890 DEBUG_PRINTF (" calling the load callback for class '%s'\n", class->name);
0bfe3fa1
NP
891 _objc_load_callback (class, 0);
892 }
1588200e
NP
893 }
894
895 /* Call the _objc_load_callback for categories. Don't register
896 the instance methods as class methods for categories to root
897 classes since they were already added in the class. */
898 for (i = 0; i < symtab->cat_def_cnt; i++)
899 {
900 struct objc_category *category = symtab->defs[i + symtab->cls_def_cnt];
901 Class class = objc_getClass (category->class_name);
902
e99776d8
NP
903 DEBUG_PRINTF (" calling the load callback for category '%s (%s)'\n",
904 category->class_name, category->category_name);
1588200e
NP
905 _objc_load_callback (class, category);
906 }
88e17b57
BE
907 }
908}
909
40165636 910/* Sanity check the version of gcc used to compile `module'. */
40165636 911static void
fed2b101 912init_check_module_version (struct objc_module *module)
88e17b57 913{
fed2b101 914 if ((module->version != OBJC_VERSION) || (module->size != sizeof (struct objc_module)))
88e17b57 915 {
7b869986
NP
916 _objc_abort ("Module %s version %d doesn't match runtime %d\n",
917 module->name, (int)module->version, OBJC_VERSION);
88e17b57
BE
918 }
919}
920
0bfe3fa1
NP
921/* __objc_init_class must be called with __objc_runtime_mutex already
922 locked. Return YES if the class could be setup; return NO if the
923 class could not be setup because a class with the same name already
924 exists. */
925BOOL
6c5c7efd
NP
926__objc_init_class (Class class)
927{
928 /* Store the class in the class table and assign class numbers. */
1575c9de
NP
929 if (__objc_add_class_to_hash (class))
930 {
931 /* Register all of the selectors in the class and meta class. */
932 __objc_register_selectors_from_class (class);
933 __objc_register_selectors_from_class ((Class) class->class_pointer);
934
935 /* Install the fake dispatch tables. */
936 __objc_install_premature_dtable (class);
937 __objc_install_premature_dtable (class->class_pointer);
938
939 /* Register the instance methods as class methods, this is only
940 done for root classes. */
941 __objc_register_instance_methods_to_class (class);
942
943 if (class->protocols)
944 __objc_init_protocols (class->protocols);
0bfe3fa1
NP
945
946 return YES;
1575c9de
NP
947 }
948 else
0bfe3fa1
NP
949 {
950 /* The module contains a duplicate class. Remember it so that
951 we will ignore it later. */
e99776d8 952 DEBUG_PRINTF (" duplicate class '%s' - will be ignored\n", class->name);
0bfe3fa1
NP
953 objc_hash_add (&duplicate_classes, class, class);
954 return NO;
955 }
6c5c7efd
NP
956}
957
f7185d47
NP
958/* __objc_init_protocol must be called with __objc_runtime_mutex
959 already locked, and the "Protocol" class already registered. */
960static void
961__objc_init_protocol (struct objc_protocol *protocol)
962{
963 static Class proto_class = 0;
964
965 if (! proto_class)
fed2b101 966 proto_class = objc_getClass ("Protocol");
f7185d47
NP
967
968 if (((size_t)protocol->class_pointer) == PROTOCOL_VERSION)
969 {
575584a9 970 /* Assign class pointer. */
f7185d47
NP
971 protocol->class_pointer = proto_class;
972
973 /* Register all the selectors in the protocol with the runtime.
974 This both registers the selectors with the right types, and
975 it also fixes up the 'struct objc_method' structures inside
976 the protocol so that each method_name (a char * as compiled
977 by the compiler) is replaced with the appropriate runtime
978 SEL. */
979 if (protocol->class_methods)
980 __objc_register_selectors_from_description_list (protocol->class_methods);
981
982 if (protocol->instance_methods)
983 __objc_register_selectors_from_description_list (protocol->instance_methods);
984
985 /* Register the protocol in the hashtable or protocols by
986 name. */
987 __objc_protocols_add_protocol (protocol->protocol_name, protocol);
988
575584a9 989 /* Init super protocols. */
f7185d47
NP
990 __objc_init_protocols (protocol->protocol_list);
991 }
992 else if (protocol->class_pointer != proto_class)
993 {
994 _objc_abort ("Version %d doesn't match runtime protocol version %d\n",
995 (int) ((char *) protocol->class_pointer
996 - (char *) 0),
997 PROTOCOL_VERSION);
998 }
999}
1000
88e17b57 1001static void
40165636 1002__objc_init_protocols (struct objc_protocol_list *protos)
88e17b57 1003{
8f8c44cb 1004 size_t i;
88e17b57
BE
1005 static Class proto_class = 0;
1006
1007 if (! protos)
1008 return;
1009
40165636 1010 objc_mutex_lock (__objc_runtime_mutex);
88e17b57 1011
40165636 1012 if (! proto_class)
fed2b101 1013 proto_class = objc_getClass ("Protocol");
88e17b57 1014
40165636 1015 if (! proto_class)
88e17b57
BE
1016 {
1017 unclaimed_proto_list = list_cons (protos, unclaimed_proto_list);
40165636 1018 objc_mutex_unlock (__objc_runtime_mutex);
88e17b57
BE
1019 return;
1020 }
1021
1022#if 0
575584a9 1023 assert (protos->next == 0); /* Only single ones allowed. */
88e17b57
BE
1024#endif
1025
40165636 1026 for (i = 0; i < protos->count; i++)
88e17b57 1027 {
40165636 1028 struct objc_protocol *aProto = protos->list[i];
f7185d47 1029 __objc_init_protocol (aProto);
88e17b57
BE
1030 }
1031
40165636 1032 objc_mutex_unlock (__objc_runtime_mutex);
88e17b57
BE
1033}
1034
40165636
RB
1035static void
1036__objc_class_add_protocols (Class class, struct objc_protocol_list *protos)
88e17b57 1037{
88e17b57
BE
1038 if (! protos)
1039 return;
1040
88e17b57
BE
1041 protos->next = class->protocols;
1042 class->protocols = protos;
1043}