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