Annotation of gcc/objc/init.c, revision 1.1.1.2

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

unix.superglobalmegacorp.com

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