Annotation of GNUtools/cc/objc/class.c, revision 1.1.1.1

1.1       root        1: /* GNU Objective C Runtime class related functions
                      2:    Copyright (C) 1993 Free Software Foundation, Inc.
                      3: 
                      4: Author: Kresten Krab Thorup, Dennis Glatting
                      5: 
                      6: This file is part of GNU CC.
                      7: 
                      8: GNU CC is free software; you can redistribute it and/or modify it under the
                      9:    terms of the GNU General Public License as published by the Free Software
                     10:    Foundation; either version 2, or (at your option) any later version.
                     11: 
                     12: GNU CC is distributed in the hope that it will be useful, but WITHOUT ANY
                     13:    WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
                     14:    FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
                     15:    details.
                     16: 
                     17: You should have received a copy of the GNU General Public License along with
                     18:    GNU CC; see the file COPYING.  If not, write to the Free Software
                     19:    Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
                     20: 
                     21: /* As a special exception, if you link this library with files compiled with
                     22:    GCC to produce an executable, this does not cause the resulting executable
                     23:    to be covered by the GNU General Public License. This exception does not
                     24:    however invalidate any other reasons why the executable file might be
                     25:    covered by the GNU General Public License.  */
                     26: 
                     27: #include "runtime.h"           /* the kitchen sink */
                     28: #include "sarray.h"
                     29: 
                     30: /* The table of classname->class.  Used for objc_lookup_class and friends */
                     31: static cache_ptr __objc_class_hash = 0;
                     32: 
                     33: /* This is a hook which is called by objc_get_class and 
                     34:    objc_lookup_class if the runtime is not able to find the class.
                     35:    This may e.g. try to load in the class using dynamic loading */
                     36: Class* (*_objc_lookup_class)(const char* name) = 0;
                     37: 
                     38: 
                     39: /* True when class links has been resolved */     
                     40: BOOL __objc_class_links_resolved = NO;
                     41: 
                     42: 
                     43: /* Initial number of buckets size of class hash table. */
                     44: #define CLASS_HASH_SIZE 32
                     45: 
                     46: void __objc_init_class_tables()
                     47: {
                     48:   /* Allocate the class hash table */
                     49: 
                     50:   if(__objc_class_hash)
                     51:     return;
                     52: 
                     53:   __objc_class_hash
                     54:     =  hash_new (CLASS_HASH_SIZE,
                     55:                 (hash_func_type) hash_string,
                     56:                 (compare_func_type) compare_strings);
                     57: }  
                     58: 
                     59: /* This function adds a class to the class hash table, and assigns the 
                     60:    class a number, unless it's already known */
                     61: void
                     62: __objc_add_class_to_hash(Class* class)
                     63: {
                     64:   Class* h_class;
                     65: 
                     66:   /* make sure the table is there */
                     67:   assert(__objc_class_hash);
                     68: 
                     69:   /* make sure it's not a meta class */  
                     70:   assert(CLS_ISCLASS(class));
                     71: 
                     72:   /* Check to see if the class is already in the hash table.  */
                     73:   h_class = hash_value_for_key (__objc_class_hash, class->name);
                     74:   if (!h_class)
                     75:     {
                     76:       /* The class isn't in the hash table.  Add the class and assign a class
                     77:          number.  */
                     78:       static unsigned int class_number = 1;
                     79: 
                     80:       CLS_SETNUMBER(class, class_number);
                     81:       CLS_SETNUMBER(class->class_pointer, class_number);
                     82: 
                     83:       ++class_number;
                     84:       hash_add (&__objc_class_hash, class->name, class);
                     85:     }
                     86: }
                     87: 
                     88: /* Get the class object for the class named NAME.  If NAME does not
                     89:    identify a known class, the hook _objc_lookup_class is called.  If
                     90:    this fails, nil is returned */
                     91: Class* objc_lookup_class (const char* name)
                     92: {
                     93:   Class* class;
                     94: 
                     95:   /* Make sure the class hash table exists.  */
                     96:   assert (__objc_class_hash);
                     97: 
                     98:   class = hash_value_for_key (__objc_class_hash, name);
                     99: 
                    100:   if (class)
                    101:     return class;
                    102: 
                    103:   if (_objc_lookup_class)
                    104:     return (*_objc_lookup_class)(name);
                    105:   else
                    106:     return 0;
                    107: }
                    108: 
                    109: /* Get the class object for the class named NAME.  If NAME does not
                    110:    identify a known class, the hook _objc_lookup_class is called.  If
                    111:    this fails,  an error message is issued and the system aborts */
                    112: Class*
                    113: objc_get_class (const char *name)
                    114: {
                    115:   Class* class;
                    116: 
                    117:   /* Make sure the class hash table exists.  */
                    118:   assert (__objc_class_hash);
                    119: 
                    120:   class = hash_value_for_key (__objc_class_hash, name);
                    121: 
                    122:   if (class)
                    123:     return class;
                    124: 
                    125:   if (_objc_lookup_class)
                    126:     class = (*_objc_lookup_class)(name);
                    127: 
                    128:   if(class)
                    129:     return class;
                    130:   
                    131:   fprintf(stderr, "objc runtime: cannot find class %s\n", name);
                    132:   abort();
                    133: }
                    134: 
                    135: 
                    136: /* Resolve super/subclass links for all classes.  The only thing we 
                    137:    can be sure of is that the class_pointer for class objects point 
                    138:    to the right meta class objects */
                    139: void __objc_resolve_class_links()
                    140: {
                    141:   node_ptr node;
                    142:   Class* object_class = objc_get_class ("Object");
                    143: 
                    144:   assert(object_class);
                    145: 
                    146:   /* Assign subclass links */
                    147:   for (node = hash_next (__objc_class_hash, NULL); node;
                    148:        node = hash_next (__objc_class_hash, node))
                    149:     {
                    150:       Class* class1 = node->value;
                    151: 
                    152:       /* Make sure we have what we think we have.  */
                    153:       assert (CLS_ISCLASS(class1));
                    154:       assert (CLS_ISMETA(class1->class_pointer));
                    155: 
                    156:       /* The class_pointer of all meta classes point to Object's meta class. */
                    157:       class1->class_pointer->class_pointer = object_class->class_pointer;
                    158: 
                    159:       if (!(CLS_ISRESOLV(class1)))
                    160:         {
                    161:           CLS_SETRESOLV(class1);
                    162:           CLS_SETRESOLV(class1->class_pointer);
                    163:               
                    164:           if(class1->super_class)
                    165:             {   
                    166:               Class* a_super_class 
                    167:                 = objc_get_class ((char *) class1->super_class);
                    168:               
                    169:               assert (a_super_class);
                    170:               
                    171:               DEBUG_PRINTF ("making class connections for: %s\n",
                    172:                             class1->name);
                    173:               
                    174:               /* assign subclass links for superclass */
                    175:               class1->sibling_class = a_super_class->subclass_list;
                    176:               a_super_class->subclass_list = class1;
                    177:               
                    178:               /* Assign subclass links for meta class of superclass */
                    179:               if (a_super_class->class_pointer)
                    180:                 {
                    181:                   class1->class_pointer->sibling_class
                    182:                     = a_super_class->class_pointer->subclass_list;
                    183:                   a_super_class->class_pointer->subclass_list 
                    184:                     = class1->class_pointer;
                    185:                 }
                    186:             }
                    187:           else                  /* a root class, make its meta object */
                    188:                                 /* be a subclass of Object */
                    189:             {
                    190:               class1->class_pointer->sibling_class 
                    191:                 = object_class->subclass_list;
                    192:               object_class->subclass_list = class1->class_pointer;
                    193:             }
                    194:         }
                    195:     }
                    196: 
                    197:   /* Assign superclass links */
                    198:   for (node = hash_next (__objc_class_hash, NULL); node;
                    199:        node = hash_next (__objc_class_hash, node))
                    200:     {
                    201:       Class* class1 = node->value;
                    202:       Class* sub_class;
                    203:       for (sub_class = class1->subclass_list; sub_class;
                    204:            sub_class = sub_class->sibling_class)
                    205:         {
                    206:           sub_class->super_class = class1;
                    207:           if(CLS_ISCLASS(sub_class))
                    208:             sub_class->class_pointer->super_class = class1->class_pointer;
                    209:         }
                    210:     }
                    211: }
                    212: 
                    213: 
                    214: 
                    215: #define CLASSOF(c) ((c)->class_pointer)
                    216: 
                    217: Class*
                    218: class_pose_as (Class* impostor, Class* super_class)
                    219: {
                    220:   node_ptr node;
                    221:   Class* class1;
                    222: 
                    223:   if (!CLS_ISRESOLV (impostor))
                    224:     __objc_resolve_class_links ();
                    225: 
                    226:   /* preconditions */
                    227:   assert (impostor);
                    228:   assert (super_class);
                    229:   assert (impostor->super_class == super_class);
                    230:   assert (CLS_ISCLASS (impostor));
                    231:   assert (CLS_ISCLASS (super_class));
                    232:   assert (impostor->instance_size == super_class->instance_size);
                    233: 
                    234:   {
                    235:     Class **subclass = &(super_class->subclass_list);
                    236: 
                    237:     /* move subclasses of super_class to impostor */
                    238:     while (*subclass)
                    239:       {
                    240:        Class *nextSub = (*subclass)->sibling_class;
                    241: 
                    242:        if (*subclass != impostor)
                    243:          {
                    244:            Class *sub = *subclass;
                    245: 
                    246:            /* classes */
                    247:            sub->sibling_class = impostor->subclass_list;
                    248:            sub->super_class = impostor;
                    249:            impostor->subclass_list = sub;
                    250: 
                    251:            /* It will happen that SUB is not a class object if it is 
                    252:               the top of the meta class hierachy chain.  (root
                    253:               meta-class objects inherit theit class object)  If that is
                    254:               the case... dont mess with the meta-meta class. */ 
                    255:            if (CLS_ISCLASS (sub))
                    256:              {
                    257:                /* meta classes */
                    258:                CLASSOF (sub)->sibling_class = CLASSOF (impostor)->subclass_list;
                    259:                CLASSOF (sub)->super_class = CLASSOF (impostor);
                    260:                CLASSOF (impostor)->subclass_list = CLASSOF (sub);
                    261:              }
                    262:          }
                    263: 
                    264:        *subclass = nextSub;
                    265:       }
                    266: 
                    267:     /* set subclasses of superclass to be impostor only */
                    268:     super_class->subclass_list = impostor;
                    269:     CLASSOF (super_class)->subclass_list = CLASSOF (impostor);
                    270:     
                    271:     /* set impostor to have no sibling classes */
                    272:     impostor->sibling_class = 0;
                    273:     CLASSOF (impostor)->sibling_class = 0;
                    274:   }
                    275:   
                    276:   /* check relationship of impostor and super_class is kept. */
                    277:   assert (impostor->super_class == super_class);
                    278:   assert (CLASSOF (impostor)->super_class == CLASSOF (super_class));
                    279: 
                    280:   /* This is how to update the lookup table. Regardless of
                    281:      what the keys of the hashtable is, change all values that are
                    282:      suprecalss into impostor. */
                    283: 
                    284:   for (node = hash_next (__objc_class_hash, NULL); node;
                    285:        node = hash_next (__objc_class_hash, node))
                    286:     {
                    287:       class1 = (Class*)node->value;
                    288:       if (class1 == super_class)
                    289:        {
                    290:          node->value = impostor; /* change hash table value */
                    291:        }
                    292:     }      
                    293: 
                    294:   /* next, we update the dispatch tables... */
                    295:   __objc_update_dispatch_table_for_class (CLASSOF (impostor));
                    296:   __objc_update_dispatch_table_for_class (impostor);
                    297: 
                    298:   return impostor;
                    299: }
                    300:   
                    301: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.