]> gcc.gnu.org Git - gcc.git/blame - gcc/objc/init.c
(__objc_thread_detach_function): Clear thread storage.
[gcc.git] / gcc / objc / init.c
CommitLineData
c72fc2d9 1/* GNU Objective C Runtime initialization
aef85e6a 2 Copyright (C) 1993, 1995, 1996 Free Software Foundation, Inc.
4426bf3f 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 17GNU CC; see the file COPYING. If not, write to the Free Software
84c09f78 18Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 */
aef85e6a 34static struct objc_list* __objc_module_list = 0; /* !T:MUTEX */
c72fc2d9
TW
35
36/* This list contains all proto_list's not yet assigned class links */
aef85e6a 37static struct objc_list* unclaimed_proto_list = 0; /* !T:MUTEX */
c72fc2d9 38
4426bf3f 39/* List of unresolved static instances. */
aef85e6a
RK
40static struct objc_list *uninitialized_statics = 0; /* !T:MUTEX */
41
42/* Global runtime "write" mutex. */
43_objc_mutex_t __objc_runtime_mutex;
44
45/* Number of threads that are alive. */
46int __objc_runtime_threads_alive = 1; /* !T:MUTEX */
4426bf3f 47
c72fc2d9 48/* Check compiler vs runtime version */
4426bf3f 49static void init_check_module_version (Module_t);
c72fc2d9
TW
50
51/* Assign isa links to protos */
52static void __objc_init_protocols (struct objc_protocol_list* protos);
53
54/* Add protocol to class */
4426bf3f 55static void __objc_class_add_protocols (Class, struct objc_protocol_list*);
c72fc2d9 56
d8a55d09
RK
57/* This is a hook which is called by __objc_exec_class every time a class
58 or a category is loaded into the runtime. This may e.g. help a
59 dynamic loader determine the classes that have been loaded when
60 an object file is dynamically linked in */
aef85e6a 61void (*_objc_load_callback)(Class class, Category* category) = 0; /* !T:SAFE */
d8a55d09 62
c72fc2d9 63/* Is all categories/classes resolved? */
aef85e6a 64BOOL __objc_dangling_categories = NO; /* !T:UNUSED */
c72fc2d9 65
a39d31bc
KKT
66extern SEL
67__sel_register_typed_name (const char *name, const char *types,
68 struct objc_selector *orig);
69
4426bf3f
RK
70/* Run through the statics list, removing modules as soon as all its statics
71 have been initialized. */
72static void
73objc_init_statics ()
74{
75 struct objc_list **cell = &uninitialized_statics;
76 struct objc_static_instances **statics_in_module;
77
aef85e6a
RK
78 objc_mutex_lock(__objc_runtime_mutex);
79
4426bf3f
RK
80 while (*cell)
81 {
82 int module_initialized = 1;
83
84 for (statics_in_module = (*cell)->head;
85 *statics_in_module; statics_in_module++)
86 {
87 struct objc_static_instances *statics = *statics_in_module;
df27f225 88 Class class = objc_lookup_class (statics->class_name);
4426bf3f
RK
89
90 if (!class)
91 module_initialized = 0;
92 /* Actually, the static's class_pointer will be NULL when we
93 haven't been here before. However, the comparison is to be
94 reminded of taking into account class posing and to think about
95 possible semantics... */
96 else if (class != statics->instances[0]->class_pointer)
97 {
98 id *inst;
99
100 for (inst = &statics->instances[0]; *inst; inst++)
101 {
102 (*inst)->class_pointer = class;
103
104 /* ??? Make sure the object will not be freed. With
105 refcounting, invoke `-retain'. Without refcounting, do
106 nothing and hope that `-free' will never be invoked. */
107
108 /* ??? Send the object an `-initStatic' or something to
109 that effect now or later on? What are the semantics of
110 statically allocated instances, besides the trivial
111 NXConstantString, anyway? */
112 }
113 }
114 }
115 if (module_initialized)
116 {
117 /* Remove this module from the uninitialized list. */
118 struct objc_list *this = *cell;
119 *cell = this->tail;
120 free (this);
121 }
122 else
123 cell = &(*cell)->tail;
124 }
aef85e6a
RK
125
126 objc_mutex_unlock(__objc_runtime_mutex);
4426bf3f 127} /* objc_init_statics */
a39d31bc 128
c72fc2d9
TW
129/* This function is called by constructor functions generated for each
130 module compiled. (_GLOBAL_$I$...) The purpose of this function is to
131 gather the module pointers so that they may be processed by the
132 initialization routines as soon as possible */
133
134void
135__objc_exec_class (Module_t module)
136{
4426bf3f
RK
137 /* Have we processed any constructors previously? This flag is used to
138 indicate that some global data structures need to be built. */
c72fc2d9
TW
139 static BOOL previous_constructors = 0;
140
141 static struct objc_list* unclaimed_categories = 0;
142
4426bf3f 143 /* The symbol table (defined in objc-api.h) generated by gcc */
c72fc2d9
TW
144 Symtab_t symtab = module->symtab;
145
c72fc2d9
TW
146 /* Entry used to traverse hash lists */
147 struct objc_list** cell;
148
149 /* The table of selector references for this module */
a39d31bc 150 SEL selectors = symtab->refs;
c72fc2d9
TW
151
152 /* dummy counter */
153 int i;
154
155 DEBUG_PRINTF ("received module: %s\n", module->name);
4426bf3f 156
c72fc2d9
TW
157 /* check gcc version */
158 init_check_module_version(module);
159
160 /* On the first call of this routine, initialize some data structures. */
161 if (!previous_constructors)
162 {
aef85e6a
RK
163 /* Initialize thread-safe system */
164 __objc_init_thread_system();
165 __objc_runtime_threads_alive = 1;
166 __objc_runtime_mutex = objc_mutex_allocate();
167
c72fc2d9
TW
168 __objc_init_selector_tables();
169 __objc_init_class_tables();
170 __objc_init_dispatch_tables();
171 previous_constructors = 1;
172 }
173
174 /* Save the module pointer for later processing. (not currently used) */
aef85e6a 175 objc_mutex_lock(__objc_runtime_mutex);
c72fc2d9
TW
176 __objc_module_list = list_cons(module, __objc_module_list);
177
a39d31bc
KKT
178 /* Replace referenced selectors from names to SEL's. */
179 if (selectors)
180 {
181 for (i = 0; selectors[i].sel_id; ++i)
182 {
183 const char *name, *type;
184 name = (char*)selectors[i].sel_id;
185 type = (char*)selectors[i].sel_types;
186 __sel_register_typed_name (name, type,
187 (struct objc_selector*)&(selectors[i]));
188 }
189 }
190
c72fc2d9
TW
191 /* Parse the classes in the load module and gather selector information. */
192 DEBUG_PRINTF ("gathering selectors from module: %s\n", module->name);
193 for (i = 0; i < symtab->cls_def_cnt; ++i)
194 {
4426bf3f 195 Class class = (Class) symtab->defs[i];
c72fc2d9
TW
196
197 /* Make sure we have what we think. */
198 assert (CLS_ISCLASS(class));
199 assert (CLS_ISMETA(class->class_pointer));
200 DEBUG_PRINTF ("phase 1, processing class: %s\n", class->name);
201
202 /* Store the class in the class table and assign class numbers. */
203 __objc_add_class_to_hash (class);
204
205 /* Register all of the selectors in the class and meta class. */
206 __objc_register_selectors_from_class (class);
4426bf3f 207 __objc_register_selectors_from_class ((Class) class->class_pointer);
c72fc2d9
TW
208
209 /* Install the fake dispatch tables */
210 __objc_install_premature_dtable(class);
211 __objc_install_premature_dtable(class->class_pointer);
212
213 if (class->protocols)
214 __objc_init_protocols (class->protocols);
d8a55d09
RK
215
216 if (_objc_load_callback)
217 _objc_load_callback(class, 0);
c72fc2d9
TW
218 }
219
c72fc2d9
TW
220 /* Process category information from the module. */
221 for (i = 0; i < symtab->cat_def_cnt; ++i)
222 {
223 Category_t category = symtab->defs[i + symtab->cls_def_cnt];
4426bf3f 224 Class class = objc_lookup_class (category->class_name);
c72fc2d9
TW
225
226 /* If the class for the category exists then append its methods. */
227 if (class)
228 {
229
230 DEBUG_PRINTF ("processing categories from (module,object): %s, %s\n",
231 module->name,
232 class->name);
233
234 /* Do instance methods. */
235 if (category->instance_methods)
236 class_add_method_list (class, category->instance_methods);
237
238 /* Do class methods. */
239 if (category->class_methods)
4426bf3f 240 class_add_method_list ((Class) class->class_pointer,
c72fc2d9
TW
241 category->class_methods);
242
243 if (category->protocols)
244 {
245 __objc_init_protocols (category->protocols);
246 __objc_class_add_protocols (class, category->protocols);
247 }
248
d8a55d09
RK
249 if (_objc_load_callback)
250 _objc_load_callback(class, category);
c72fc2d9
TW
251 }
252 else
253 {
254 /* The object to which the category methods belong can't be found.
255 Save the information. */
256 unclaimed_categories = list_cons(category, unclaimed_categories);
257 }
258 }
259
4426bf3f
RK
260 if (module->statics)
261 uninitialized_statics = list_cons (module->statics, uninitialized_statics);
262 if (uninitialized_statics)
263 objc_init_statics ();
264
c72fc2d9
TW
265 /* Scan the unclaimed category hash. Attempt to attach any unclaimed
266 categories to objects. */
267 for (cell = &unclaimed_categories;
268 *cell;
a39d31bc 269 ({ if (*cell) cell = &(*cell)->tail; }))
c72fc2d9
TW
270 {
271 Category_t category = (*cell)->head;
4426bf3f 272 Class class = objc_lookup_class (category->class_name);
c72fc2d9
TW
273
274 if (class)
275 {
276 DEBUG_PRINTF ("attaching stored categories to object: %s\n",
277 class->name);
278
279 list_remove_head (cell);
280
281 if (category->instance_methods)
282 class_add_method_list (class, category->instance_methods);
283
284 if (category->class_methods)
4426bf3f 285 class_add_method_list ((Class) class->class_pointer,
c72fc2d9
TW
286 category->class_methods);
287
288 if (category->protocols)
289 {
290 __objc_init_protocols (category->protocols);
291 __objc_class_add_protocols (class, category->protocols);
292 }
293
d8a55d09
RK
294 if (_objc_load_callback)
295 _objc_load_callback(class, category);
c72fc2d9
TW
296 }
297 }
298
299 if (unclaimed_proto_list && objc_lookup_class ("Protocol"))
300 {
301 list_mapcar (unclaimed_proto_list,(void(*)(void*))__objc_init_protocols);
302 list_free (unclaimed_proto_list);
303 unclaimed_proto_list = 0;
304 }
305
aef85e6a 306 objc_mutex_unlock(__objc_runtime_mutex);
c72fc2d9
TW
307}
308
309/* Sanity check the version of gcc used to compile `module'*/
310static void init_check_module_version(Module_t module)
311{
312 if ((module->version != OBJC_VERSION) || (module->size != sizeof (Module)))
313 {
314 fprintf (stderr, "Module %s version %d doesn't match runtime %d\n",
a39d31bc 315 module->name, (int)module->version, OBJC_VERSION);
c72fc2d9
TW
316 if(module->version > OBJC_VERSION)
317 fprintf (stderr, "Runtime (libobjc.a) is out of date\n");
318 else if (module->version < OBJC_VERSION)
319 fprintf (stderr, "Compiler (gcc) is out of date\n");
320 else
321 fprintf (stderr, "Objective C internal error -- bad Module size\n");
322 abort ();
323 }
324}
325
326static void
327__objc_init_protocols (struct objc_protocol_list* protos)
328{
329 int i;
4426bf3f 330 static Class proto_class = 0;
c72fc2d9
TW
331
332 if (! protos)
333 return;
334
aef85e6a
RK
335 objc_mutex_lock(__objc_runtime_mutex);
336
eba92c95
RS
337 if (!proto_class)
338 proto_class = objc_lookup_class("Protocol");
c72fc2d9 339
eba92c95 340 if (!proto_class)
c72fc2d9
TW
341 {
342 unclaimed_proto_list = list_cons (protos, unclaimed_proto_list);
8c55cd78 343 objc_mutex_unlock(__objc_runtime_mutex);
c72fc2d9
TW
344 return;
345 }
346
2acb0388 347#if 0
c72fc2d9 348 assert (protos->next == 0); /* only single ones allowed */
2acb0388 349#endif
c72fc2d9
TW
350
351 for(i = 0; i < protos->count; i++)
352 {
eba92c95
RS
353 struct objc_protocol* aProto = protos->list[i];
354 if (((size_t)aProto->class_pointer) == PROTOCOL_VERSION)
355 {
356 /* assign class pointer */
357 aProto->class_pointer = proto_class;
358
359 /* init super protocols */
360 __objc_init_protocols (aProto->protocol_list);
361 }
362 else if (protos->list[i]->class_pointer != proto_class)
c72fc2d9
TW
363 {
364 fprintf (stderr,
0046ffa3 365 "Version %d doesn't match runtime protocol version %d\n",
a39d31bc 366 (int)((char*)protos->list[i]->class_pointer-(char*)0),
c72fc2d9
TW
367 PROTOCOL_VERSION);
368 abort ();
369 }
370 }
aef85e6a
RK
371
372 objc_mutex_unlock(__objc_runtime_mutex);
c72fc2d9
TW
373}
374
4426bf3f 375static void __objc_class_add_protocols (Class class,
c72fc2d9
TW
376 struct objc_protocol_list* protos)
377{
c72fc2d9
TW
378 /* Well... */
379 if (! protos)
380 return;
381
382 /* Add it... */
383 protos->next = class->protocols;
384 class->protocols = protos;
385}
This page took 0.31242 seconds and 5 git commands to generate.