1/* GNU Objective C Runtime class related functions
2   Copyright (C) 1993-2020 Free Software Foundation, Inc.
3   Contributed by Kresten Krab Thorup and Dennis Glatting.
4
5   Lock-free class table code designed and written from scratch by
6   Nicola Pero, 2001.
7
8This file is part of GCC.
9
10GCC is free software; you can redistribute it and/or modify it under the
11terms of the GNU General Public License as published by the Free Software
12Foundation; either version 3, or (at your option) any later version.
13
14GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
17details.
18
19Under Section 7 of GPL version 3, you are granted additional
20permissions described in the GCC Runtime Library Exception, version
213.1, as published by the Free Software Foundation.
22
23You should have received a copy of the GNU General Public License and
24a copy of the GCC Runtime Library Exception along with this program;
25see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
26<http://www.gnu.org/licenses/>.  */
27
28/* The code in this file critically affects class method invocation
29  speed.  This long preamble comment explains why, and the issues
30  involved.
31
32  One of the traditional weaknesses of the GNU Objective-C runtime is
33  that class method invocations are slow.  The reason is that when you
34  write
35
36  array = [NSArray new];
37
38  this gets basically compiled into the equivalent of
39
40  array = [(objc_get_class ("NSArray")) new];
41
42  objc_get_class returns the class pointer corresponding to the string
43  `NSArray'; and because of the lookup, the operation is more
44  complicated and slow than a simple instance method invocation.
45
46  Most high performance Objective-C code (using the GNU Objc runtime)
47  I had the opportunity to read (or write) work around this problem by
48  caching the class pointer:
49
50  Class arrayClass = [NSArray class];
51
52  ... later on ...
53
54  array = [arrayClass new];
55  array = [arrayClass new];
56  array = [arrayClass new];
57
58  In this case, you always perform a class lookup (the first one), but
59  then all the [arrayClass new] methods run exactly as fast as an
60  instance method invocation.  It helps if you have many class method
61  invocations to the same class.
62
63  The long-term solution to this problem would be to modify the
64  compiler to output tables of class pointers corresponding to all the
65  class method invocations, and to add code to the runtime to update
66  these tables - that should in the end allow class method invocations
67  to perform precisely as fast as instance method invocations, because
68  no class lookup would be involved.  I think the Apple Objective-C
69  runtime uses this technique.  Doing this involves synchronized
70  modifications in the runtime and in the compiler.
71
72  As a first medicine to the problem, I [NP] have redesigned and
73  rewritten the way the runtime is performing class lookup.  This
74  doesn't give as much speed as the other (definitive) approach, but
75  at least a class method invocation now takes approximately 4.5 times
76  an instance method invocation on my machine (it would take approx 12
77  times before the rewriting), which is a lot better.
78
79  One of the main reason the new class lookup is so faster is because
80  I implemented it in a way that can safely run multithreaded without
81  using locks - a so-called `lock-free' data structure.  The atomic
82  operation is pointer assignment.  The reason why in this problem
83  lock-free data structures work so well is that you never remove
84  classes from the table - and the difficult thing with lock-free data
85  structures is freeing data when is removed from the structures.  */
86
87#include "objc-private/common.h"
88#include "objc-private/error.h"
89#include "objc/runtime.h"
90#include "objc/thr.h"
91#include "objc-private/module-abi-8.h"  /* For CLS_ISCLASS and similar.  */
92#include "objc-private/runtime.h"       /* the kitchen sink */
93#include "objc-private/sarray.h"        /* For sarray_put_at_safe.  */
94#include "objc-private/selector.h"      /* For sarray_put_at_safe.  */
95#include <string.h>                     /* For memset */
96
97/* We use a table which maps a class name to the corresponding class
98   pointer.  The first part of this file defines this table, and
99   functions to do basic operations on the table.  The second part of
100   the file implements some higher level Objective-C functionality for
101   classes by using the functions provided in the first part to manage
102   the table. */
103
104/**
105 ** Class Table Internals
106 **/
107
108/* A node holding a class */
109typedef struct class_node
110{
111  struct class_node *next;      /* Pointer to next entry on the list.
112                                   NULL indicates end of list. */
113
114  const char *name;             /* The class name string */
115  int length;                   /* The class name string length */
116  Class pointer;                /* The Class pointer */
117
118} *class_node_ptr;
119
120/* A table containing classes is a class_node_ptr (pointing to the
121   first entry in the table - if it is NULL, then the table is
122   empty). */
123
124/* We have 1024 tables.  Each table contains all class names which
125   have the same hash (which is a number between 0 and 1023).  To look
126   up a class_name, we compute its hash, and get the corresponding
127   table.  Once we have the table, we simply compare strings directly
128   till we find the one which we want (using the length first).  The
129   number of tables is quite big on purpose (a normal big application
130   has less than 1000 classes), so that you shouldn't normally get any
131   collisions, and get away with a single comparison (which we can't
132   avoid since we need to know that you have got the right thing).  */
133#define CLASS_TABLE_SIZE 1024
134#define CLASS_TABLE_MASK 1023
135
136static class_node_ptr class_table_array[CLASS_TABLE_SIZE];
137
138/* The table writing mutex - we lock on writing to avoid conflicts
139   between different writers, but we read without locks.  That is
140   possible because we assume pointer assignment to be an atomic
141   operation.  TODO: This is only true under certain circumstances,
142   which should be clarified.  */
143static objc_mutex_t __class_table_lock = NULL;
144
145/* CLASS_TABLE_HASH is how we compute the hash of a class name.  It is
146   a macro - *not* a function - arguments *are* modified directly.
147
148   INDEX should be a variable holding an int;
149   HASH should be a variable holding an int;
150   CLASS_NAME should be a variable holding a (char *) to the class_name.
151
152   After the macro is executed, INDEX contains the length of the
153   string, and HASH the computed hash of the string; CLASS_NAME is
154   untouched.  */
155
156#define CLASS_TABLE_HASH(INDEX, HASH, CLASS_NAME)			\
157  do {									\
158    HASH = 0;								\
159    for (INDEX = 0; CLASS_NAME[INDEX] != '\0'; INDEX++)			\
160      {									\
161	HASH = (HASH << 4) ^ (HASH >> 28) ^ CLASS_NAME[INDEX];		\
162      }									\
163									\
164    HASH = (HASH ^ (HASH >> 10) ^ (HASH >> 20)) & CLASS_TABLE_MASK;	\
165  } while (0)
166
167/* Setup the table.  */
168static void
169class_table_setup (void)
170{
171  /* Start - nothing in the table.  */
172  memset (class_table_array, 0, sizeof (class_node_ptr) * CLASS_TABLE_SIZE);
173
174  /* The table writing mutex.  */
175  __class_table_lock = objc_mutex_allocate ();
176}
177
178
179/* Insert a class in the table (used when a new class is
180   registered).  */
181static void
182class_table_insert (const char *class_name, Class class_pointer)
183{
184  int hash, length;
185  class_node_ptr new_node;
186
187  /* Find out the class name's hash and length.  */
188  CLASS_TABLE_HASH (length, hash, class_name);
189
190  /* Prepare the new node holding the class.  */
191  new_node = objc_malloc (sizeof (struct class_node));
192  new_node->name = class_name;
193  new_node->length = length;
194  new_node->pointer = class_pointer;
195
196  /* Lock the table for modifications.  */
197  objc_mutex_lock (__class_table_lock);
198
199  /* Insert the new node in the table at the beginning of the table at
200     class_table_array[hash].  */
201  new_node->next = class_table_array[hash];
202  class_table_array[hash] = new_node;
203
204  objc_mutex_unlock (__class_table_lock);
205}
206
207/* Get a class from the table.  This does not need mutex protection.
208   Currently, this function is called each time you call a static
209   method, this is why it must be very fast.  */
210static inline Class
211class_table_get_safe (const char *class_name)
212{
213  class_node_ptr node;
214  int length, hash;
215
216  /* Compute length and hash.  */
217  CLASS_TABLE_HASH (length, hash, class_name);
218
219  node = class_table_array[hash];
220
221  if (node != NULL)
222    {
223      do
224        {
225          if (node->length == length)
226            {
227              /* Compare the class names.  */
228              int i;
229
230              for (i = 0; i < length; i++)
231                {
232                  if ((node->name)[i] != class_name[i])
233		    break;
234                }
235
236              if (i == length)
237                {
238                  /* They are equal!  */
239                  return node->pointer;
240                }
241            }
242        }
243      while ((node = node->next) != NULL);
244    }
245
246  return Nil;
247}
248
249/* Enumerate over the class table.  */
250struct class_table_enumerator
251{
252  int hash;
253  class_node_ptr node;
254};
255
256
257static Class
258class_table_next (struct class_table_enumerator **e)
259{
260  struct class_table_enumerator *enumerator = *e;
261  class_node_ptr next;
262
263  if (enumerator == NULL)
264    {
265       *e = objc_malloc (sizeof (struct class_table_enumerator));
266      enumerator = *e;
267      enumerator->hash = 0;
268      enumerator->node = NULL;
269
270      next = class_table_array[enumerator->hash];
271    }
272  else
273    next = enumerator->node->next;
274
275  if (next != NULL)
276    {
277      enumerator->node = next;
278      return enumerator->node->pointer;
279    }
280  else
281    {
282      enumerator->hash++;
283
284      while (enumerator->hash < CLASS_TABLE_SIZE)
285        {
286          next = class_table_array[enumerator->hash];
287          if (next != NULL)
288            {
289              enumerator->node = next;
290              return enumerator->node->pointer;
291            }
292          enumerator->hash++;
293        }
294
295      /* Ok - table finished - done.  */
296      objc_free (enumerator);
297      return Nil;
298    }
299}
300
301#if 0 /* DEBUGGING FUNCTIONS */
302/* Debugging function - print the class table.  */
303void
304class_table_print (void)
305{
306  int i;
307
308  for (i = 0; i < CLASS_TABLE_SIZE; i++)
309    {
310      class_node_ptr node;
311
312      printf ("%d:\n", i);
313      node = class_table_array[i];
314
315      while (node != NULL)
316        {
317          printf ("\t%s\n", node->name);
318          node = node->next;
319        }
320    }
321}
322
323/* Debugging function - print an histogram of number of classes in
324   function of hash key values.  Useful to evaluate the hash function
325   in real cases.  */
326void
327class_table_print_histogram (void)
328{
329  int i, j;
330  int counter = 0;
331
332  for (i = 0; i < CLASS_TABLE_SIZE; i++)
333    {
334      class_node_ptr node;
335
336      node = class_table_array[i];
337
338      while (node != NULL)
339        {
340          counter++;
341          node = node->next;
342        }
343      if (((i + 1) % 50) == 0)
344        {
345          printf ("%4d:", i + 1);
346          for (j = 0; j < counter; j++)
347	    printf ("X");
348
349          printf ("\n");
350          counter = 0;
351        }
352    }
353  printf ("%4d:", i + 1);
354  for (j = 0; j < counter; j++)
355    printf ("X");
356
357  printf ("\n");
358}
359#endif /* DEBUGGING FUNCTIONS */
360
361/**
362 ** Objective-C runtime functions
363 **/
364
365/* From now on, the only access to the class table data structure
366   should be via the class_table_* functions.  */
367
368/* This is a hook which is called by objc_get_class and
369   objc_lookup_class if the runtime is not able to find the class.
370   This may e.g. try to load in the class using dynamic loading.
371
372   This hook was a public, global variable in the Traditional GNU
373   Objective-C Runtime API (objc/objc-api.h).  The modern GNU
374   Objective-C Runtime API (objc/runtime.h) provides the
375   objc_setGetUnknownClassHandler() function instead.
376*/
377Class (*_objc_lookup_class) (const char *name) = 0;      /* !T:SAFE */
378
379/* The handler currently in use.  PS: if both
380   __obj_get_unknown_class_handler and _objc_lookup_class are defined,
381   __objc_get_unknown_class_handler is called first.  */
382static objc_get_unknown_class_handler
383__objc_get_unknown_class_handler = NULL;
384
385objc_get_unknown_class_handler
386objc_setGetUnknownClassHandler (objc_get_unknown_class_handler
387				new_handler)
388{
389  objc_get_unknown_class_handler old_handler
390    = __objc_get_unknown_class_handler;
391  __objc_get_unknown_class_handler = new_handler;
392  return old_handler;
393}
394
395
396/* True when class links has been resolved.  */
397BOOL __objc_class_links_resolved = NO;                  /* !T:UNUSED */
398
399
400void
401__objc_init_class_tables (void)
402{
403  /* Allocate the class hash table.  */
404
405  if (__class_table_lock)
406    return;
407
408  objc_mutex_lock (__objc_runtime_mutex);
409
410  class_table_setup ();
411
412  objc_mutex_unlock (__objc_runtime_mutex);
413}
414
415/* This function adds a class to the class hash table, and assigns the
416   class a number, unless it's already known.  Return 'YES' if the
417   class was added.  Return 'NO' if the class was already known.  */
418BOOL
419__objc_add_class_to_hash (Class class)
420{
421  Class existing_class;
422
423  objc_mutex_lock (__objc_runtime_mutex);
424
425  /* Make sure the table is there.  */
426  assert (__class_table_lock);
427
428  /* Make sure it's not a meta class.  */
429  assert (CLS_ISCLASS (class));
430
431  /* Check to see if the class is already in the hash table.  */
432  existing_class = class_table_get_safe (class->name);
433
434  if (existing_class)
435    {
436      objc_mutex_unlock (__objc_runtime_mutex);
437      return NO;
438    }
439  else
440    {
441      /* The class isn't in the hash table.  Add the class and assign
442         a class number.  */
443      static unsigned int class_number = 1;
444
445      CLS_SETNUMBER (class, class_number);
446      CLS_SETNUMBER (class->class_pointer, class_number);
447
448      ++class_number;
449      class_table_insert (class->name, class);
450
451      objc_mutex_unlock (__objc_runtime_mutex);
452      return YES;
453    }
454}
455
456Class
457objc_getClass (const char *name)
458{
459  Class class;
460
461  if (name == NULL)
462    return Nil;
463
464  class = class_table_get_safe (name);
465
466  if (class)
467    return class;
468
469  if (__objc_get_unknown_class_handler)
470    return (*__objc_get_unknown_class_handler) (name);
471
472  if (_objc_lookup_class)
473    return (*_objc_lookup_class) (name);
474
475  return Nil;
476}
477
478Class
479objc_lookUpClass (const char *name)
480{
481  if (name == NULL)
482    return Nil;
483  else
484    return class_table_get_safe (name);
485}
486
487Class
488objc_getMetaClass (const char *name)
489{
490  Class class = objc_getClass (name);
491
492  if (class)
493    return class->class_pointer;
494  else
495    return Nil;
496}
497
498Class
499objc_getRequiredClass (const char *name)
500{
501  Class class = objc_getClass (name);
502
503  if (class)
504    return class;
505  else
506    _objc_abort ("objc_getRequiredClass ('%s') failed: class not found\n", name);
507}
508
509int
510objc_getClassList (Class *returnValue, int maxNumberOfClassesToReturn)
511{
512  /* Iterate over all entries in the table.  */
513  int hash, count = 0;
514
515  for (hash = 0; hash < CLASS_TABLE_SIZE; hash++)
516    {
517      class_node_ptr node = class_table_array[hash];
518
519      while (node != NULL)
520	{
521	  if (returnValue)
522	    {
523	      if (count < maxNumberOfClassesToReturn)
524		returnValue[count] = node->pointer;
525	      else
526		return count;
527	    }
528	  count++;
529	  node = node->next;
530	}
531    }
532
533  return count;
534}
535
536Class
537objc_allocateClassPair (Class super_class, const char *class_name, size_t extraBytes)
538{
539  Class new_class;
540  Class new_meta_class;
541
542  if (class_name == NULL)
543    return Nil;
544
545  if (objc_getClass (class_name))
546    return Nil;
547
548  if (super_class)
549    {
550      /* If you want to build a hierarchy of classes, you need to
551	 build and register them one at a time.  The risk is that you
552	 are able to cause confusion by registering a subclass before
553	 the superclass or similar.  */
554      if (CLS_IS_IN_CONSTRUCTION (super_class))
555	return Nil;
556    }
557
558  /* Technically, we should create the metaclass first, then use
559     class_createInstance() to create the class.  That complication
560     would be relevant if we had class variables, but we don't, so we
561     just ignore it and create everything directly and assume all
562     classes have the same size.  */
563  new_class = objc_calloc (1, sizeof (struct objc_class) + extraBytes);
564  new_meta_class = objc_calloc (1, sizeof (struct objc_class) + extraBytes);
565
566  /* We create an unresolved class, similar to one generated by the
567     compiler.  It will be resolved later when we register it.
568
569     Note how the metaclass details are not that important; when the
570     class is resolved, the ones that matter will be fixed up.  */
571  new_class->class_pointer = new_meta_class;
572  new_meta_class->class_pointer = 0;
573
574  if (super_class)
575    {
576      /* Force the name of the superclass in place of the link to the
577	 actual superclass, which will be put there when the class is
578	 resolved.  */
579      const char *super_class_name = class_getName (super_class);
580      new_class->super_class = (void *)super_class_name;
581      new_meta_class->super_class = (void *)super_class_name;
582    }
583  else
584    {
585      new_class->super_class = (void *)0;
586      new_meta_class->super_class = (void *)0;
587    }
588
589  new_class->name = objc_malloc (strlen (class_name) + 1);
590  strcpy ((char*)new_class->name, class_name);
591  new_meta_class->name = new_class->name;
592
593  new_class->version = 0;
594  new_meta_class->version = 0;
595
596  new_class->info = _CLS_CLASS | _CLS_IN_CONSTRUCTION;
597  new_meta_class->info = _CLS_META | _CLS_IN_CONSTRUCTION;
598
599  if (super_class)
600    new_class->instance_size = super_class->instance_size;
601  else
602    new_class->instance_size = 0;
603  new_meta_class->instance_size = sizeof (struct objc_class);
604
605  return new_class;
606}
607
608void
609objc_registerClassPair (Class class_)
610{
611  if (class_ == Nil)
612    return;
613
614  if ((! CLS_ISCLASS (class_)) || (! CLS_IS_IN_CONSTRUCTION (class_)))
615    return;
616
617  if ((! CLS_ISMETA (class_->class_pointer)) || (! CLS_IS_IN_CONSTRUCTION (class_->class_pointer)))
618    return;
619
620  objc_mutex_lock (__objc_runtime_mutex);
621
622  if (objc_getClass (class_->name))
623    {
624      objc_mutex_unlock (__objc_runtime_mutex);
625      return;
626    }
627
628  CLS_SET_NOT_IN_CONSTRUCTION (class_);
629  CLS_SET_NOT_IN_CONSTRUCTION (class_->class_pointer);
630
631  __objc_init_class (class_);
632
633  /* Resolve class links immediately.  No point in waiting.  */
634  __objc_resolve_class_links ();
635
636  objc_mutex_unlock (__objc_runtime_mutex);
637}
638
639void
640objc_disposeClassPair (Class class_)
641{
642  if (class_ == Nil)
643    return;
644
645  if ((! CLS_ISCLASS (class_)) || (! CLS_IS_IN_CONSTRUCTION (class_)))
646    return;
647
648  if ((! CLS_ISMETA (class_->class_pointer)) || (! CLS_IS_IN_CONSTRUCTION (class_->class_pointer)))
649    return;
650
651  /* Undo any class_addIvar().  */
652  if (class_->ivars)
653    {
654      int i;
655      for (i = 0; i < class_->ivars->ivar_count; i++)
656	{
657	  struct objc_ivar *ivar = &(class_->ivars->ivar_list[i]);
658
659	  objc_free ((char *)ivar->ivar_name);
660	  objc_free ((char *)ivar->ivar_type);
661	}
662
663      objc_free (class_->ivars);
664    }
665
666  /* Undo any class_addMethod().  */
667  if (class_->methods)
668    {
669      struct objc_method_list *list = class_->methods;
670      while (list)
671	{
672	  int i;
673	  struct objc_method_list *next = list->method_next;
674
675	  for (i = 0; i < list->method_count; i++)
676	    {
677	      struct objc_method *method = &(list->method_list[i]);
678
679	      objc_free ((char *)method->method_name);
680	      objc_free ((char *)method->method_types);
681	    }
682
683	  objc_free (list);
684	  list = next;
685	}
686    }
687
688  /* Undo any class_addProtocol().  */
689  if (class_->protocols)
690    {
691      struct objc_protocol_list *list = class_->protocols;
692      while (list)
693	{
694	  struct objc_protocol_list *next = list->next;
695
696	  objc_free (list);
697	  list = next;
698	}
699    }
700
701  /* Undo any class_addMethod() on the meta-class.  */
702  if (class_->class_pointer->methods)
703    {
704      struct objc_method_list *list = class_->class_pointer->methods;
705      while (list)
706	{
707	  int i;
708	  struct objc_method_list *next = list->method_next;
709
710	  for (i = 0; i < list->method_count; i++)
711	    {
712	      struct objc_method *method = &(list->method_list[i]);
713
714	      objc_free ((char *)method->method_name);
715	      objc_free ((char *)method->method_types);
716	    }
717
718	  objc_free (list);
719	  list = next;
720	}
721    }
722
723  /* Undo objc_allocateClassPair().  */
724  objc_free ((char *)(class_->name));
725  objc_free (class_->class_pointer);
726  objc_free (class_);
727}
728
729/* Traditional GNU Objective-C Runtime API.  Important: this method is
730   called automatically by the compiler while messaging (if using the
731   traditional ABI), so it is worth keeping it fast; don't make it
732   just a wrapper around objc_getClass().  */
733/* Note that this is roughly equivalent to objc_getRequiredClass().  */
734/* Get the class object for the class named NAME.  If NAME does not
735   identify a known class, the hook _objc_lookup_class is called.  If
736   this fails, an error message is issued and the system aborts.  */
737Class
738objc_get_class (const char *name)
739{
740  Class class;
741
742  class = class_table_get_safe (name);
743
744  if (class)
745    return class;
746
747  if (__objc_get_unknown_class_handler)
748    class = (*__objc_get_unknown_class_handler) (name);
749
750  if ((!class)  &&  _objc_lookup_class)
751    class = (*_objc_lookup_class) (name);
752
753  if (class)
754    return class;
755
756  _objc_abort ("objc runtime: cannot find class %s\n", name);
757
758  return 0;
759}
760
761/* This is used by the compiler too.  */
762Class
763objc_get_meta_class (const char *name)
764{
765  return objc_get_class (name)->class_pointer;
766}
767
768/* This is not used by GCC, but the clang compiler seems to use it
769   when targeting the GNU runtime.  That's wrong, but we have it to
770   be compatible.  */
771Class
772objc_lookup_class (const char *name)
773{
774  return objc_getClass (name);
775}
776
777/* This is used when the implementation of a method changes.  It goes
778   through all classes, looking for the ones that have these methods
779   (either method_a or method_b; method_b can be NULL), and reloads
780   the implementation for these.  You should call this with the
781   runtime mutex already locked.  */
782void
783__objc_update_classes_with_methods (struct objc_method *method_a, struct objc_method *method_b)
784{
785  int hash;
786
787  /* Iterate over all classes.  */
788  for (hash = 0; hash < CLASS_TABLE_SIZE; hash++)
789    {
790      class_node_ptr node = class_table_array[hash];
791
792      while (node != NULL)
793	{
794	  /* We execute this loop twice: the first time, we iterate
795	     over all methods in the class (instance methods), while
796	     the second time we iterate over all methods in the meta
797	     class (class methods).  */
798	  Class class = Nil;
799	  BOOL done = NO;
800
801	  while (done == NO)
802	    {
803	      struct objc_method_list * method_list;
804
805	      if (class == Nil)
806		{
807		  /* The first time, we work on the class.  */
808		  class = node->pointer;
809		}
810	      else
811		{
812		  /* The second time, we work on the meta class.  */
813		  class = class->class_pointer;
814		  done = YES;
815		}
816
817	      method_list = class->methods;
818
819	      while (method_list)
820		{
821		  int i;
822
823		  for (i = 0; i < method_list->method_count; ++i)
824		    {
825		      struct objc_method *method = &method_list->method_list[i];
826
827		      /* If the method is one of the ones we are
828			 looking for, update the implementation.  */
829		      if (method == method_a)
830			sarray_at_put_safe (class->dtable,
831					    (sidx) method_a->method_name->sel_id,
832					    method_a->method_imp);
833
834		      if (method == method_b)
835			{
836			  if (method_b != NULL)
837			    sarray_at_put_safe (class->dtable,
838						(sidx) method_b->method_name->sel_id,
839						method_b->method_imp);
840			}
841		    }
842
843		  method_list = method_list->method_next;
844		}
845	    }
846	  node = node->next;
847	}
848    }
849}
850
851/* Resolve super/subclass links for all classes.  The only thing we
852   can be sure of is that the class_pointer for class objects point to
853   the right meta class objects.  */
854void
855__objc_resolve_class_links (void)
856{
857  struct class_table_enumerator *es = NULL;
858  Class object_class = objc_get_class ("Object");
859  Class class1;
860
861  assert (object_class);
862
863  objc_mutex_lock (__objc_runtime_mutex);
864
865  /* Assign subclass links.  */
866  while ((class1 = class_table_next (&es)))
867    {
868      /* Make sure we have what we think we have.  */
869      assert (CLS_ISCLASS (class1));
870      assert (CLS_ISMETA (class1->class_pointer));
871
872      /* The class_pointer of all meta classes point to Object's meta
873         class.  */
874      class1->class_pointer->class_pointer = object_class->class_pointer;
875
876      if (! CLS_ISRESOLV (class1))
877        {
878          CLS_SETRESOLV (class1);
879          CLS_SETRESOLV (class1->class_pointer);
880
881          if (class1->super_class)
882            {
883              Class a_super_class
884                = objc_get_class ((char *) class1->super_class);
885
886              assert (a_super_class);
887
888              DEBUG_PRINTF ("making class connections for: %s\n",
889                            class1->name);
890
891              /* Assign subclass links for superclass.  */
892              class1->sibling_class = a_super_class->subclass_list;
893              a_super_class->subclass_list = class1;
894
895              /* Assign subclass links for meta class of superclass.  */
896              if (a_super_class->class_pointer)
897                {
898                  class1->class_pointer->sibling_class
899                    = a_super_class->class_pointer->subclass_list;
900                  a_super_class->class_pointer->subclass_list
901                    = class1->class_pointer;
902                }
903            }
904          else /* A root class, make its meta object be a subclass of
905                  Object.  */
906            {
907              class1->class_pointer->sibling_class
908                = object_class->subclass_list;
909              object_class->subclass_list = class1->class_pointer;
910            }
911        }
912    }
913
914  /* Assign superclass links.  */
915   es = NULL;
916   while ((class1 = class_table_next (&es)))
917    {
918      Class sub_class;
919      for (sub_class = class1->subclass_list; sub_class;
920           sub_class = sub_class->sibling_class)
921        {
922          sub_class->super_class = class1;
923          if (CLS_ISCLASS (sub_class))
924            sub_class->class_pointer->super_class = class1->class_pointer;
925        }
926    }
927
928  objc_mutex_unlock (__objc_runtime_mutex);
929}
930
931const char *
932class_getName (Class class_)
933{
934  if (class_ == Nil)
935    return "nil";
936
937  return class_->name;
938}
939
940BOOL
941class_isMetaClass (Class class_)
942{
943  /* CLS_ISMETA includes the check for Nil class_.  */
944  return CLS_ISMETA (class_);
945}
946
947/* Even inside libobjc it may be worth using class_getSuperclass
948   instead of accessing class_->super_class directly because it
949   resolves the class links if needed.  If you access
950   class_->super_class directly, make sure to deal with the situation
951   where the class is not resolved yet!  */
952Class
953class_getSuperclass (Class class_)
954{
955  if (class_ == Nil)
956    return Nil;
957
958  /* Classes that are in construction are not resolved, and still have
959     the class name (instead of a class pointer) in the
960     class_->super_class field.  In that case we need to lookup the
961     superclass name to return the superclass.  We cannot resolve the
962     class until it is registered.  */
963  if (CLS_IS_IN_CONSTRUCTION (class_))
964    {
965      if (CLS_ISMETA (class_))
966	return object_getClass ((id)objc_lookUpClass ((const char *)(class_->super_class)));
967      else
968	return objc_lookUpClass ((const char *)(class_->super_class));
969    }
970
971  /* If the class is not resolved yet, super_class would point to a
972     string (the name of the super class) as opposed to the actual
973     super class.  In that case, we need to resolve the class links
974     before we can return super_class.  */
975  if (! CLS_ISRESOLV (class_))
976    __objc_resolve_class_links ();
977
978  return class_->super_class;
979}
980
981int
982class_getVersion (Class class_)
983{
984  if (class_ == Nil)
985    return 0;
986
987  return (int)(class_->version);
988}
989
990void
991class_setVersion (Class class_, int version)
992{
993  if (class_ == Nil)
994    return;
995
996  class_->version = version;
997}
998
999size_t
1000class_getInstanceSize (Class class_)
1001{
1002  if (class_ == Nil)
1003    return 0;
1004
1005  return class_->instance_size;
1006}
1007
1008