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