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