OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libobjc/] [init.c] - Blame information for rev 778

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.