|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.