(root)/
gcc-13.2.0/
libobjc/
class.c
       1  /* GNU Objective C Runtime class related functions
       2     Copyright (C) 1993-2023 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  
       8  This file is part of GCC.
       9  
      10  GCC is free software; you can redistribute it and/or modify it under the
      11  terms of the GNU General Public License as published by the Free Software
      12  Foundation; either version 3, or (at your option) any later version.
      13  
      14  GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      15  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
      16  FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
      17  details.
      18  
      19  Under Section 7 of GPL version 3, you are granted additional
      20  permissions described in the GCC Runtime Library Exception, version
      21  3.1, as published by the Free Software Foundation.
      22  
      23  You should have received a copy of the GNU General Public License and
      24  a copy of the GCC Runtime Library Exception along with this program;
      25  see 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 */
     109  typedef 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  
     136  static 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.  */
     143  static 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.  */
     168  static void
     169  class_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).  */
     181  static void 
     182  class_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.  */
     210  static inline Class 
     211  class_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.  */
     250  struct class_table_enumerator
     251  {
     252    int hash;
     253    class_node_ptr node;
     254  };
     255  
     256  
     257  static Class
     258  class_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.  */
     303  void
     304  class_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.  */
     326  void
     327  class_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  */
     377  Class (*_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.  */
     382  static objc_get_unknown_class_handler
     383  __objc_get_unknown_class_handler = NULL;
     384  
     385  objc_get_unknown_class_handler
     386  objc_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.  */     
     397  BOOL __objc_class_links_resolved = NO;                  /* !T:UNUSED */
     398  
     399  
     400  void
     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.  */
     418  BOOL
     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  
     456  Class
     457  objc_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  
     478  Class
     479  objc_lookUpClass (const char *name)
     480  {
     481    if (name == NULL)
     482      return Nil;
     483    else
     484      return class_table_get_safe (name);
     485  }
     486  
     487  Class
     488  objc_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  
     498  Class
     499  objc_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  
     509  int
     510  objc_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  
     536  Class
     537  objc_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  
     608  void
     609  objc_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  
     639  void
     640  objc_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.  */
     737  Class
     738  objc_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.  */
     762  Class
     763  objc_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.  */
     771  Class
     772  objc_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.  */
     782  void
     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.  */
     854  void
     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  
     931  const char *
     932  class_getName (Class class_)
     933  {
     934    if (class_ == Nil)
     935      return "nil";
     936  
     937    return class_->name;
     938  }
     939  
     940  BOOL
     941  class_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!  */
     952  Class
     953  class_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  
     981  int
     982  class_getVersion (Class class_)
     983  {
     984    if (class_ == Nil)
     985      return 0;
     986  
     987    return (int)(class_->version);
     988  }
     989  
     990  void
     991  class_setVersion (Class class_, int version)
     992  {
     993    if (class_ == Nil)
     994      return;
     995  
     996    class_->version = version;
     997  }
     998  
     999  size_t
    1000  class_getInstanceSize (Class class_)
    1001  {
    1002    if (class_ == Nil)
    1003      return 0;
    1004  
    1005    return class_->instance_size;
    1006  }
    1007