Annotation of GNUtools/cc/objc/init.c, revision 1.1

1.1     ! root        1: /* GNU Objective C Runtime initialization 
        !             2:    Copyright (C) 1993 Free Software Foundation, Inc.
        !             3: 
        !             4: Author: Kresten Krab Thorup
        !             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"
        !            28: 
        !            29: /* The version number of this runtime.  This must match the number 
        !            30:    defined in gcc (objc-act.c) */
        !            31: #define OBJC_VERSION 5
        !            32: #define PROTOCOL_VERSION 2
        !            33: 
        !            34: /* This list contains all modules currently loaded into the runtime */
        !            35: static struct objc_list* __objc_module_list = 0;
        !            36: 
        !            37: /* This list contains all proto_list's not yet assigned class links */
        !            38: static struct objc_list* unclaimed_proto_list = 0;
        !            39: 
        !            40: /* Check compiler vs runtime version */
        !            41: static void init_check_module_version(Module_t);
        !            42: 
        !            43: /* Assign isa links to protos */
        !            44: static void __objc_init_protocols (struct objc_protocol_list* protos);
        !            45: 
        !            46: /* Add protocol to class */
        !            47: static void __objc_class_add_protocols (Class*, struct objc_protocol_list*);
        !            48: 
        !            49: /* Is all categories/classes resolved? */
        !            50: BOOL __objc_dangling_categories = NO;
        !            51: 
        !            52: /* This function is called by constructor functions generated for each
        !            53:    module compiled.  (_GLOBAL_$I$...) The purpose of this function is to
        !            54:    gather the module pointers so that they may be processed by the
        !            55:    initialization routines as soon as possible */
        !            56: 
        !            57: void
        !            58: __objc_exec_class (Module_t module)
        !            59: {
        !            60:   /* Has we processed any constructors previously?  This flag used to 
        !            61:      indicate that some global data structures need to be built.  */ 
        !            62:   static BOOL previous_constructors = 0;
        !            63: 
        !            64:   static struct objc_list* unclaimed_categories = 0;
        !            65: 
        !            66:   /* The symbol table (defined in objc.h) generated by gcc */
        !            67:   Symtab_t symtab = module->symtab;
        !            68: 
        !            69:   /* Entry used to traverse hash lists */
        !            70:   struct objc_list** cell;
        !            71: 
        !            72:   /* The table of selector references for this module */
        !            73:   SEL *selectors = symtab->refs; 
        !            74: 
        !            75:   /* dummy counter */
        !            76:   int i;
        !            77: 
        !            78:   DEBUG_PRINTF ("received module: %s\n", module->name);
        !            79:   /* check gcc version */
        !            80:   init_check_module_version(module);
        !            81: 
        !            82:   /* On the first call of this routine, initialize some data structures.  */
        !            83:   if (!previous_constructors)
        !            84:     {
        !            85:       __objc_init_selector_tables();
        !            86:       __objc_init_class_tables();
        !            87:       __objc_init_dispatch_tables();
        !            88:       previous_constructors = 1;
        !            89:     }
        !            90: 
        !            91:   /* Save the module pointer for later processing. (not currently used) */
        !            92:   __objc_module_list = list_cons(module, __objc_module_list);
        !            93: 
        !            94:   /* Parse the classes in the load module and gather selector information.  */
        !            95:   DEBUG_PRINTF ("gathering selectors from module: %s\n", module->name);
        !            96:   for (i = 0; i < symtab->cls_def_cnt; ++i)
        !            97:     {
        !            98:       Class* class = (Class*) symtab->defs[i];
        !            99: 
        !           100:       /* Make sure we have what we think.  */
        !           101:       assert (CLS_ISCLASS(class));
        !           102:       assert (CLS_ISMETA(class->class_pointer));
        !           103:       DEBUG_PRINTF ("phase 1, processing class: %s\n", class->name);
        !           104: 
        !           105:       /* Store the class in the class table and assign class numbers.  */
        !           106:       __objc_add_class_to_hash (class);
        !           107: 
        !           108:       /* Register all of the selectors in the class and meta class.  */
        !           109:       __objc_register_selectors_from_class (class);
        !           110:       __objc_register_selectors_from_class ((Class*) class->class_pointer);
        !           111: 
        !           112:       /* Install the fake dispatch tables */
        !           113:       __objc_install_premature_dtable(class);
        !           114:       __objc_install_premature_dtable(class->class_pointer);
        !           115: 
        !           116:       if (class->protocols)
        !           117:        __objc_init_protocols (class->protocols);
        !           118:    }
        !           119: 
        !           120:   /* Replace referenced selectors from names to SEL's.  */
        !           121:   if (selectors)
        !           122:     {
        !           123:       for (i = 0; selectors[i]; ++i)
        !           124:        selectors[i] = sel_register_name ((const char *) selectors[i]);
        !           125:     }
        !           126: 
        !           127:   /* Process category information from the module.  */
        !           128:   for (i = 0; i < symtab->cat_def_cnt; ++i)
        !           129:     {
        !           130:       Category_t category = symtab->defs[i + symtab->cls_def_cnt];
        !           131:       Class* class = objc_lookup_class (category->class_name);
        !           132:       
        !           133:       /* If the class for the category exists then append its methods.  */
        !           134:       if (class)
        !           135:        {
        !           136: 
        !           137:          DEBUG_PRINTF ("processing categories from (module,object): %s, %s\n",
        !           138:                        module->name,
        !           139:                        class->name);
        !           140: 
        !           141:          /* Do instance methods.  */
        !           142:          if (category->instance_methods)
        !           143:            class_add_method_list (class, category->instance_methods);
        !           144: 
        !           145:          /* Do class methods.  */
        !           146:          if (category->class_methods)
        !           147:            class_add_method_list ((Class*) class->class_pointer, 
        !           148:                                   category->class_methods);
        !           149: 
        !           150:          if (category->protocols)
        !           151:            {
        !           152:              __objc_init_protocols (category->protocols);
        !           153:              __objc_class_add_protocols (class, category->protocols);
        !           154:            }
        !           155: 
        !           156:        }
        !           157:       else
        !           158:        {
        !           159:          /* The object to which the category methods belong can't be found.
        !           160:             Save the information.  */
        !           161:          unclaimed_categories = list_cons(category, unclaimed_categories);
        !           162:        }
        !           163:     }
        !           164: 
        !           165:   /* Scan the unclaimed category hash.  Attempt to attach any unclaimed
        !           166:      categories to objects.  */
        !           167:   for (cell = &unclaimed_categories;
        !           168:        *cell;
        !           169:        ({ if (*cell) cell = &(*cell)->tail; }))
        !           170:     {
        !           171:       Category_t category = (*cell)->head;
        !           172:       Class* class = objc_lookup_class (category->class_name);
        !           173:       
        !           174:       if (class)
        !           175:        {
        !           176:          DEBUG_PRINTF ("attaching stored categories to object: %s\n",
        !           177:                        class->name);
        !           178:          
        !           179:          list_remove_head (cell);
        !           180:          
        !           181:          if (category->instance_methods)
        !           182:            class_add_method_list (class, category->instance_methods);
        !           183:          
        !           184:          if (category->class_methods)
        !           185:            class_add_method_list ((Class*) class->class_pointer,
        !           186:                                   category->class_methods);
        !           187:          
        !           188:          if (category->protocols)
        !           189:            {
        !           190:              __objc_init_protocols (category->protocols);
        !           191:              __objc_class_add_protocols (class, category->protocols);
        !           192:            }
        !           193:          
        !           194:        }
        !           195:     }
        !           196:   
        !           197:   if (unclaimed_proto_list && objc_lookup_class ("Protocol"))
        !           198:     {
        !           199:       list_mapcar (unclaimed_proto_list,(void(*)(void*))__objc_init_protocols);
        !           200:       list_free (unclaimed_proto_list);
        !           201:       unclaimed_proto_list = 0;
        !           202:     }
        !           203: 
        !           204: }
        !           205: 
        !           206: /* Sanity check the version of gcc used to compile `module'*/
        !           207: static void init_check_module_version(Module_t module)
        !           208: {
        !           209:   if ((module->version != OBJC_VERSION) || (module->size != sizeof (Module)))
        !           210:     {
        !           211:       fprintf (stderr, "Module %s version %d doesn't match runtime %d\n",
        !           212:               module->name, (int)module->version, OBJC_VERSION);
        !           213:       if(module->version > OBJC_VERSION)
        !           214:        fprintf (stderr, "Runtime (libobjc.a) is out of date\n");
        !           215:       else if (module->version < OBJC_VERSION)
        !           216:        fprintf (stderr, "Compiler (gcc) is out of date\n");
        !           217:       else
        !           218:        fprintf (stderr, "Objective C internal error -- bad Module size\n");
        !           219:       abort ();
        !           220:     }
        !           221: }
        !           222: 
        !           223: static void
        !           224: __objc_init_protocols (struct objc_protocol_list* protos)
        !           225: {
        !           226:   int i;
        !           227:   static Class* proto_class = 0;
        !           228: 
        !           229:   if (! protos)
        !           230:     return;
        !           231: 
        !           232:   if (!proto_class)
        !           233:     proto_class = objc_lookup_class("Protocol");
        !           234: 
        !           235:   if (!proto_class)
        !           236:     {
        !           237:       unclaimed_proto_list = list_cons (protos, unclaimed_proto_list);
        !           238:       return;
        !           239:     }
        !           240: 
        !           241:   assert (protos->next == 0);  /* only single ones allowed */
        !           242: 
        !           243:   for(i = 0; i < protos->count; i++)
        !           244:     {
        !           245:       struct objc_protocol* aProto = protos->list[i];
        !           246:       if (((size_t)aProto->class_pointer) == PROTOCOL_VERSION)
        !           247:        {
        !           248:          /* assign class pointer */
        !           249:          aProto->class_pointer = proto_class;
        !           250: 
        !           251:          /* init super protocols */
        !           252:          __objc_init_protocols (aProto->protocol_list);
        !           253:        }
        !           254:       else if (protos->list[i]->class_pointer != proto_class)
        !           255:        {
        !           256:          fprintf (stderr,
        !           257:                   "Version %d doesn't match runtime protocol version %d\n",
        !           258:                   (int)((char*)protos->list[i]->class_pointer-(char*)0),
        !           259:                   PROTOCOL_VERSION);
        !           260:          abort ();
        !           261:        }
        !           262:     }
        !           263: }
        !           264: 
        !           265: static void __objc_class_add_protocols (Class* class,
        !           266:                                        struct objc_protocol_list* protos)
        !           267: {
        !           268:   /* Well... */
        !           269:   if (! protos)
        !           270:     return;
        !           271: 
        !           272:   /* Add it... */
        !           273:   protos->next = class->protocols;
        !           274:   class->protocols = protos;
        !           275: }

unix.superglobalmegacorp.com

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