Annotation of GNUtools/cc/objc/class.c, revision 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.