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