]> gcc.gnu.org Git - gcc.git/blame - gcc/objc/init.c
Update header.
[gcc.git] / gcc / objc / init.c
CommitLineData
c72fc2d9 1/* GNU Objective C Runtime initialization
4426bf3f
RK
2 Copyright (C) 1993, 1995 Free Software Foundation, Inc.
3 Contributed by Kresten Krab Thorup
c72fc2d9
TW
4
5This file is part of GNU CC.
6
7GNU CC is free software; you can redistribute it and/or modify it under the
4426bf3f
RK
8terms of the GNU General Public License as published by the Free Software
9Foundation; either version 2, or (at your option) any later version.
c72fc2d9
TW
10
11GNU CC is distributed in the hope that it will be useful, but WITHOUT ANY
4426bf3f
RK
12WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14details.
c72fc2d9
TW
15
16You should have received a copy of the GNU General Public License along with
4426bf3f
RK
17GNU CC; see the file COPYING. If not, write to the Free Software
18Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
c72fc2d9
TW
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) */
4426bf3f 30#define OBJC_VERSION 7
c72fc2d9
TW
31#define PROTOCOL_VERSION 2
32
33/* This list contains all modules currently loaded into the runtime */
34static struct objc_list* __objc_module_list = 0;
35
36/* This list contains all proto_list's not yet assigned class links */
37static struct objc_list* unclaimed_proto_list = 0;
38
4426bf3f
RK
39/* List of unresolved static instances. */
40static struct objc_list *uninitialized_statics;
41
c72fc2d9 42/* Check compiler vs runtime version */
4426bf3f 43static void init_check_module_version (Module_t);
c72fc2d9
TW
44
45/* Assign isa links to protos */
46static void __objc_init_protocols (struct objc_protocol_list* protos);
47
48/* Add protocol to class */
4426bf3f 49static void __objc_class_add_protocols (Class, struct objc_protocol_list*);
c72fc2d9 50
d8a55d09
RK
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 */
55void (*_objc_load_callback)(Class class, Category* category) = 0;
56
c72fc2d9
TW
57/* Is all categories/classes resolved? */
58BOOL __objc_dangling_categories = NO;
59
a39d31bc
KKT
60extern SEL
61__sel_register_typed_name (const char *name, const char *types,
62 struct objc_selector *orig);
63
4426bf3f
RK
64/* Run through the statics list, removing modules as soon as all its statics
65 have been initialized. */
66static void
67objc_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;
df27f225 80 Class class = objc_lookup_class (statics->class_name);
4426bf3f
RK
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 */
a39d31bc 118
c72fc2d9
TW
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
124void
125__objc_exec_class (Module_t module)
126{
4426bf3f
RK
127 /* Have we processed any constructors previously? This flag is used to
128 indicate that some global data structures need to be built. */
c72fc2d9
TW
129 static BOOL previous_constructors = 0;
130
131 static struct objc_list* unclaimed_categories = 0;
132
4426bf3f 133 /* The symbol table (defined in objc-api.h) generated by gcc */
c72fc2d9
TW
134 Symtab_t symtab = module->symtab;
135
c72fc2d9
TW
136 /* Entry used to traverse hash lists */
137 struct objc_list** cell;
138
139 /* The table of selector references for this module */
a39d31bc 140 SEL selectors = symtab->refs;
c72fc2d9
TW
141
142 /* dummy counter */
143 int i;
144
145 DEBUG_PRINTF ("received module: %s\n", module->name);
4426bf3f 146
c72fc2d9
TW
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
a39d31bc
KKT
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
c72fc2d9
TW
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 {
4426bf3f 179 Class class = (Class) symtab->defs[i];
c72fc2d9
TW
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);
4426bf3f 191 __objc_register_selectors_from_class ((Class) class->class_pointer);
c72fc2d9
TW
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);
d8a55d09
RK
199
200 if (_objc_load_callback)
201 _objc_load_callback(class, 0);
c72fc2d9
TW
202 }
203
c72fc2d9
TW
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];
4426bf3f 208 Class class = objc_lookup_class (category->class_name);
c72fc2d9
TW
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)
4426bf3f 224 class_add_method_list ((Class) class->class_pointer,
c72fc2d9
TW
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
d8a55d09
RK
233 if (_objc_load_callback)
234 _objc_load_callback(class, category);
c72fc2d9
TW
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
4426bf3f
RK
244 if (module->statics)
245 uninitialized_statics = list_cons (module->statics, uninitialized_statics);
246 if (uninitialized_statics)
247 objc_init_statics ();
248
c72fc2d9
TW
249 /* Scan the unclaimed category hash. Attempt to attach any unclaimed
250 categories to objects. */
251 for (cell = &unclaimed_categories;
252 *cell;
a39d31bc 253 ({ if (*cell) cell = &(*cell)->tail; }))
c72fc2d9
TW
254 {
255 Category_t category = (*cell)->head;
4426bf3f 256 Class class = objc_lookup_class (category->class_name);
c72fc2d9
TW
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)
4426bf3f 269 class_add_method_list ((Class) class->class_pointer,
c72fc2d9
TW
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
d8a55d09
RK
278 if (_objc_load_callback)
279 _objc_load_callback(class, category);
c72fc2d9
TW
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'*/
293static 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",
a39d31bc 298 module->name, (int)module->version, OBJC_VERSION);
c72fc2d9
TW
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
309static void
310__objc_init_protocols (struct objc_protocol_list* protos)
311{
312 int i;
4426bf3f 313 static Class proto_class = 0;
c72fc2d9
TW
314
315 if (! protos)
316 return;
317
eba92c95
RS
318 if (!proto_class)
319 proto_class = objc_lookup_class("Protocol");
c72fc2d9 320
eba92c95 321 if (!proto_class)
c72fc2d9
TW
322 {
323 unclaimed_proto_list = list_cons (protos, unclaimed_proto_list);
324 return;
325 }
326
2acb0388 327#if 0
c72fc2d9 328 assert (protos->next == 0); /* only single ones allowed */
2acb0388 329#endif
c72fc2d9
TW
330
331 for(i = 0; i < protos->count; i++)
332 {
eba92c95
RS
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)
c72fc2d9
TW
343 {
344 fprintf (stderr,
0046ffa3 345 "Version %d doesn't match runtime protocol version %d\n",
a39d31bc 346 (int)((char*)protos->list[i]->class_pointer-(char*)0),
c72fc2d9
TW
347 PROTOCOL_VERSION);
348 abort ();
349 }
350 }
351}
352
4426bf3f 353static void __objc_class_add_protocols (Class class,
c72fc2d9
TW
354 struct objc_protocol_list* protos)
355{
c72fc2d9
TW
356 /* Well... */
357 if (! protos)
358 return;
359
360 /* Add it... */
361 protos->next = class->protocols;
362 class->protocols = protos;
363}
This page took 0.294975 seconds and 5 git commands to generate.