|
|
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.