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

1.1       root        1: /* GNU Objective C Runtime initialization 
1.1.1.3 ! root        2:    Copyright (C) 1993, 1995 Free Software Foundation, Inc.
        !             3:    Contributed by Kresten Krab Thorup
1.1       root        4: 
                      5: This file is part of GNU CC.
                      6: 
                      7: GNU CC is free software; you can redistribute it and/or modify it under the
1.1.1.3 ! root        8: terms of the GNU General Public License as published by the Free Software
        !             9: Foundation; either version 2, or (at your option) any later version.
1.1       root       10: 
                     11: GNU CC is distributed in the hope that it will be useful, but WITHOUT ANY
1.1.1.3 ! root       12: WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
        !            13: FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
        !            14: details.
1.1       root       15: 
                     16: You should have received a copy of the GNU General Public License along with
1.1.1.3 ! root       17: GNU CC; see the file COPYING.  If not, write to the Free Software
        !            18: Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
1.1       root       19: 
                     20: /* As a special exception, if you link this library with files compiled with
                     21:    GCC to produce an executable, this does not cause the resulting executable
                     22:    to be covered by the GNU General Public License. This exception does not
                     23:    however invalidate any other reasons why the executable file might be
                     24:    covered by the GNU General Public License.  */
                     25: 
                     26: #include "runtime.h"
                     27: 
                     28: /* The version number of this runtime.  This must match the number 
                     29:    defined in gcc (objc-act.c) */
1.1.1.3 ! root       30: #define OBJC_VERSION 7
1.1       root       31: #define PROTOCOL_VERSION 2
                     32: 
                     33: /* This list contains all modules currently loaded into the runtime */
                     34: static struct objc_list* __objc_module_list = 0;
                     35: 
                     36: /* This list contains all proto_list's not yet assigned class links */
                     37: static struct objc_list* unclaimed_proto_list = 0;
                     38: 
1.1.1.3 ! root       39: /* List of unresolved static instances.  */
        !            40: static struct objc_list *uninitialized_statics;
        !            41: 
1.1       root       42: /* Check compiler vs runtime version */
1.1.1.3 ! root       43: static void init_check_module_version (Module_t);
1.1       root       44: 
                     45: /* Assign isa links to protos */
                     46: static void __objc_init_protocols (struct objc_protocol_list* protos);
                     47: 
                     48: /* Add protocol to class */
1.1.1.3 ! root       49: static void __objc_class_add_protocols (Class, struct objc_protocol_list*);
        !            50: 
        !            51: /* This is a hook which is called by __objc_exec_class every time a class
        !            52:    or a category is loaded into the runtime.  This may e.g. help a
        !            53:    dynamic loader determine the classes that have been loaded when
        !            54:    an object file is dynamically linked in */
        !            55: void (*_objc_load_callback)(Class class, Category* category) = 0;
1.1       root       56: 
                     57: /* Is all categories/classes resolved? */
                     58: BOOL __objc_dangling_categories = NO;
                     59: 
1.1.1.2   root       60: extern SEL
                     61: __sel_register_typed_name (const char *name, const char *types, 
                     62:                           struct objc_selector *orig);
                     63: 
1.1.1.3 ! root       64: /* Run through the statics list, removing modules as soon as all its statics
        !            65:    have been initialized.  */
        !            66: static void
        !            67: objc_init_statics ()
        !            68: {
        !            69:   struct objc_list **cell = &uninitialized_statics;
        !            70:   struct objc_static_instances **statics_in_module;
        !            71: 
        !            72:   while (*cell)
        !            73:     {
        !            74:       int module_initialized = 1;
        !            75: 
        !            76:       for (statics_in_module = (*cell)->head;
        !            77:           *statics_in_module; statics_in_module++)
        !            78:        {
        !            79:          struct objc_static_instances *statics = *statics_in_module;
        !            80:          Class class = objc_lookup_class (statics->class_name);
        !            81: 
        !            82:          if (!class)
        !            83:            module_initialized = 0;
        !            84:          /* Actually, the static's class_pointer will be NULL when we
        !            85:              haven't been here before.  However, the comparison is to be
        !            86:              reminded of taking into account class posing and to think about
        !            87:              possible semantics...  */
        !            88:          else if (class != statics->instances[0]->class_pointer)
        !            89:            {
        !            90:              id *inst;
        !            91: 
        !            92:              for (inst = &statics->instances[0]; *inst; inst++)
        !            93:                {
        !            94:                  (*inst)->class_pointer = class;
        !            95: 
        !            96:                  /* ??? Make sure the object will not be freed.  With
        !            97:                      refcounting, invoke `-retain'.  Without refcounting, do
        !            98:                      nothing and hope that `-free' will never be invoked.  */
        !            99: 
        !           100:                  /* ??? Send the object an `-initStatic' or something to
        !           101:                      that effect now or later on?  What are the semantics of
        !           102:                      statically allocated instances, besides the trivial
        !           103:                      NXConstantString, anyway?  */
        !           104:                }
        !           105:            }
        !           106:        }
        !           107:       if (module_initialized)
        !           108:        {
        !           109:          /* Remove this module from the uninitialized list.  */
        !           110:          struct objc_list *this = *cell;
        !           111:          *cell = this->tail;
        !           112:          free (this);
        !           113:        }
        !           114:       else
        !           115:        cell = &(*cell)->tail;
        !           116:     }
        !           117: } /* objc_init_statics */
1.1.1.2   root      118: 
1.1       root      119: /* This function is called by constructor functions generated for each
                    120:    module compiled.  (_GLOBAL_$I$...) The purpose of this function is to
                    121:    gather the module pointers so that they may be processed by the
                    122:    initialization routines as soon as possible */
                    123: 
                    124: void
                    125: __objc_exec_class (Module_t module)
                    126: {
1.1.1.3 ! root      127:   /* Have we processed any constructors previously?  This flag is used to
        !           128:      indicate that some global data structures need to be built.  */
1.1       root      129:   static BOOL previous_constructors = 0;
                    130: 
                    131:   static struct objc_list* unclaimed_categories = 0;
                    132: 
1.1.1.3 ! root      133:   /* The symbol table (defined in objc-api.h) generated by gcc */
1.1       root      134:   Symtab_t symtab = module->symtab;
                    135: 
                    136:   /* Entry used to traverse hash lists */
                    137:   struct objc_list** cell;
                    138: 
                    139:   /* The table of selector references for this module */
1.1.1.2   root      140:   SEL selectors = symtab->refs; 
1.1       root      141: 
                    142:   /* dummy counter */
                    143:   int i;
                    144: 
                    145:   DEBUG_PRINTF ("received module: %s\n", module->name);
1.1.1.3 ! root      146: 
1.1       root      147:   /* check gcc version */
                    148:   init_check_module_version(module);
                    149: 
                    150:   /* On the first call of this routine, initialize some data structures.  */
                    151:   if (!previous_constructors)
                    152:     {
                    153:       __objc_init_selector_tables();
                    154:       __objc_init_class_tables();
                    155:       __objc_init_dispatch_tables();
                    156:       previous_constructors = 1;
                    157:     }
                    158: 
                    159:   /* Save the module pointer for later processing. (not currently used) */
                    160:   __objc_module_list = list_cons(module, __objc_module_list);
                    161: 
1.1.1.2   root      162:   /* Replace referenced selectors from names to SEL's.  */
                    163:   if (selectors)
                    164:     {
                    165:       for (i = 0; selectors[i].sel_id; ++i)
                    166:        {
                    167:          const char *name, *type;
                    168:          name = (char*)selectors[i].sel_id;
                    169:          type = (char*)selectors[i].sel_types;
                    170:          __sel_register_typed_name (name, type, 
                    171:                                     (struct objc_selector*)&(selectors[i]));
                    172:        }
                    173:     }
                    174: 
1.1       root      175:   /* Parse the classes in the load module and gather selector information.  */
                    176:   DEBUG_PRINTF ("gathering selectors from module: %s\n", module->name);
                    177:   for (i = 0; i < symtab->cls_def_cnt; ++i)
                    178:     {
1.1.1.3 ! root      179:       Class class = (Class) symtab->defs[i];
1.1       root      180: 
                    181:       /* Make sure we have what we think.  */
                    182:       assert (CLS_ISCLASS(class));
                    183:       assert (CLS_ISMETA(class->class_pointer));
                    184:       DEBUG_PRINTF ("phase 1, processing class: %s\n", class->name);
                    185: 
                    186:       /* Store the class in the class table and assign class numbers.  */
                    187:       __objc_add_class_to_hash (class);
                    188: 
                    189:       /* Register all of the selectors in the class and meta class.  */
                    190:       __objc_register_selectors_from_class (class);
1.1.1.3 ! root      191:       __objc_register_selectors_from_class ((Class) class->class_pointer);
1.1       root      192: 
                    193:       /* Install the fake dispatch tables */
                    194:       __objc_install_premature_dtable(class);
                    195:       __objc_install_premature_dtable(class->class_pointer);
                    196: 
                    197:       if (class->protocols)
                    198:        __objc_init_protocols (class->protocols);
1.1.1.3 ! root      199: 
        !           200:       if (_objc_load_callback)
        !           201:        _objc_load_callback(class, 0);
1.1       root      202:    }
                    203: 
                    204:   /* Process category information from the module.  */
                    205:   for (i = 0; i < symtab->cat_def_cnt; ++i)
                    206:     {
                    207:       Category_t category = symtab->defs[i + symtab->cls_def_cnt];
1.1.1.3 ! root      208:       Class class = objc_lookup_class (category->class_name);
1.1       root      209:       
                    210:       /* If the class for the category exists then append its methods.  */
                    211:       if (class)
                    212:        {
                    213: 
                    214:          DEBUG_PRINTF ("processing categories from (module,object): %s, %s\n",
                    215:                        module->name,
                    216:                        class->name);
                    217: 
                    218:          /* Do instance methods.  */
                    219:          if (category->instance_methods)
                    220:            class_add_method_list (class, category->instance_methods);
                    221: 
                    222:          /* Do class methods.  */
                    223:          if (category->class_methods)
1.1.1.3 ! root      224:            class_add_method_list ((Class) class->class_pointer, 
1.1       root      225:                                   category->class_methods);
                    226: 
                    227:          if (category->protocols)
                    228:            {
                    229:              __objc_init_protocols (category->protocols);
                    230:              __objc_class_add_protocols (class, category->protocols);
                    231:            }
                    232: 
1.1.1.3 ! root      233:           if (_objc_load_callback)
        !           234:            _objc_load_callback(class, category);
1.1       root      235:        }
                    236:       else
                    237:        {
                    238:          /* The object to which the category methods belong can't be found.
                    239:             Save the information.  */
                    240:          unclaimed_categories = list_cons(category, unclaimed_categories);
                    241:        }
                    242:     }
                    243: 
1.1.1.3 ! root      244:   if (module->statics)
        !           245:     uninitialized_statics = list_cons (module->statics, uninitialized_statics);
        !           246:   if (uninitialized_statics)
        !           247:     objc_init_statics ();
        !           248: 
1.1       root      249:   /* Scan the unclaimed category hash.  Attempt to attach any unclaimed
                    250:      categories to objects.  */
                    251:   for (cell = &unclaimed_categories;
                    252:        *cell;
1.1.1.2   root      253:        ({ if (*cell) cell = &(*cell)->tail; }))
1.1       root      254:     {
                    255:       Category_t category = (*cell)->head;
1.1.1.3 ! root      256:       Class class = objc_lookup_class (category->class_name);
1.1       root      257:       
                    258:       if (class)
                    259:        {
                    260:          DEBUG_PRINTF ("attaching stored categories to object: %s\n",
                    261:                        class->name);
                    262:          
                    263:          list_remove_head (cell);
                    264:          
                    265:          if (category->instance_methods)
                    266:            class_add_method_list (class, category->instance_methods);
                    267:          
                    268:          if (category->class_methods)
1.1.1.3 ! root      269:            class_add_method_list ((Class) class->class_pointer,
1.1       root      270:                                   category->class_methods);
                    271:          
                    272:          if (category->protocols)
                    273:            {
                    274:              __objc_init_protocols (category->protocols);
                    275:              __objc_class_add_protocols (class, category->protocols);
                    276:            }
                    277:          
1.1.1.3 ! root      278:           if (_objc_load_callback)
        !           279:            _objc_load_callback(class, category);
1.1       root      280:        }
                    281:     }
                    282:   
                    283:   if (unclaimed_proto_list && objc_lookup_class ("Protocol"))
                    284:     {
                    285:       list_mapcar (unclaimed_proto_list,(void(*)(void*))__objc_init_protocols);
                    286:       list_free (unclaimed_proto_list);
                    287:       unclaimed_proto_list = 0;
                    288:     }
                    289: 
                    290: }
                    291: 
                    292: /* Sanity check the version of gcc used to compile `module'*/
                    293: static void init_check_module_version(Module_t module)
                    294: {
                    295:   if ((module->version != OBJC_VERSION) || (module->size != sizeof (Module)))
                    296:     {
                    297:       fprintf (stderr, "Module %s version %d doesn't match runtime %d\n",
1.1.1.2   root      298:               module->name, (int)module->version, OBJC_VERSION);
1.1       root      299:       if(module->version > OBJC_VERSION)
                    300:        fprintf (stderr, "Runtime (libobjc.a) is out of date\n");
                    301:       else if (module->version < OBJC_VERSION)
                    302:        fprintf (stderr, "Compiler (gcc) is out of date\n");
                    303:       else
                    304:        fprintf (stderr, "Objective C internal error -- bad Module size\n");
                    305:       abort ();
                    306:     }
                    307: }
                    308: 
                    309: static void
                    310: __objc_init_protocols (struct objc_protocol_list* protos)
                    311: {
                    312:   int i;
1.1.1.3 ! root      313:   static Class proto_class = 0;
1.1       root      314: 
                    315:   if (! protos)
                    316:     return;
                    317: 
                    318:   if (!proto_class)
                    319:     proto_class = objc_lookup_class("Protocol");
                    320: 
                    321:   if (!proto_class)
                    322:     {
                    323:       unclaimed_proto_list = list_cons (protos, unclaimed_proto_list);
                    324:       return;
                    325:     }
                    326: 
1.1.1.2   root      327: #if 0
1.1       root      328:   assert (protos->next == 0);  /* only single ones allowed */
1.1.1.2   root      329: #endif
1.1       root      330: 
                    331:   for(i = 0; i < protos->count; i++)
                    332:     {
                    333:       struct objc_protocol* aProto = protos->list[i];
                    334:       if (((size_t)aProto->class_pointer) == PROTOCOL_VERSION)
                    335:        {
                    336:          /* assign class pointer */
                    337:          aProto->class_pointer = proto_class;
                    338: 
                    339:          /* init super protocols */
                    340:          __objc_init_protocols (aProto->protocol_list);
                    341:        }
                    342:       else if (protos->list[i]->class_pointer != proto_class)
                    343:        {
                    344:          fprintf (stderr,
                    345:                   "Version %d doesn't match runtime protocol version %d\n",
1.1.1.2   root      346:                   (int)((char*)protos->list[i]->class_pointer-(char*)0),
1.1       root      347:                   PROTOCOL_VERSION);
                    348:          abort ();
                    349:        }
                    350:     }
                    351: }
                    352: 
1.1.1.3 ! root      353: static void __objc_class_add_protocols (Class class,
1.1       root      354:                                        struct objc_protocol_list* protos)
                    355: {
                    356:   /* Well... */
                    357:   if (! protos)
                    358:     return;
                    359: 
                    360:   /* Add it... */
                    361:   protos->next = class->protocols;
                    362:   class->protocols = protos;
                    363: }

unix.superglobalmegacorp.com

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