1 /* GNU Objective C Runtime initialization
2 Copyright (C) 1993 Free Software Foundation, Inc.
4 Author: Kresten Krab Thorup
6 This file is part of GNU CC.
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.
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
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. */
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. */
29 /* The version number of this runtime. This must match the number
30 defined in gcc (objc-act.c) */
31 #define OBJC_VERSION 6
32 #define PROTOCOL_VERSION 2
34 /* This list contains all modules currently loaded into the runtime */
35 static struct objc_list
* __objc_module_list
= 0;
37 /* This list contains all proto_list's not yet assigned class links */
38 static struct objc_list
* unclaimed_proto_list
= 0;
40 /* Check compiler vs runtime version */
41 static void init_check_module_version(Module_t
);
43 /* Assign isa links to protos */
44 static void __objc_init_protocols (struct objc_protocol_list
* protos
);
46 /* Add protocol to class */
47 static void __objc_class_add_protocols (Class
*, struct objc_protocol_list
*);
49 /* Is all categories/classes resolved? */
50 BOOL __objc_dangling_categories
= NO
;
53 __sel_register_typed_name (const char *name
, const char *types
,
54 struct objc_selector
*orig
);
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 */
63 __objc_exec_class (Module_t module
)
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;
69 static struct objc_list
* unclaimed_categories
= 0;
71 /* The symbol table (defined in objc.h) generated by gcc */
72 Symtab_t symtab
= module
->symtab
;
74 /* Entry used to traverse hash lists */
75 struct objc_list
** cell
;
77 /* The table of selector references for this module */
78 SEL selectors
= symtab
->refs
;
83 DEBUG_PRINTF ("received module: %s\n", module
->name
);
84 /* check gcc version */
85 init_check_module_version(module
);
87 /* On the first call of this routine, initialize some data structures. */
88 if (!previous_constructors
)
90 __objc_init_selector_tables();
91 __objc_init_class_tables();
92 __objc_init_dispatch_tables();
93 previous_constructors
= 1;
96 /* Save the module pointer for later processing. (not currently used) */
97 __objc_module_list
= list_cons(module
, __objc_module_list
);
99 /* Replace referenced selectors from names to SEL's. */
102 for (i
= 0; selectors
[i
].sel_id
; ++i
)
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
]));
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
)
116 Class
* class = (Class
*) symtab
->defs
[i
];
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
);
123 /* Store the class in the class table and assign class numbers. */
124 __objc_add_class_to_hash (class);
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
);
130 /* Install the fake dispatch tables */
131 __objc_install_premature_dtable(class);
132 __objc_install_premature_dtable(class->class_pointer
);
134 if (class->protocols
)
135 __objc_init_protocols (class->protocols
);
138 /* Process category information from the module. */
139 for (i
= 0; i
< symtab
->cat_def_cnt
; ++i
)
141 Category_t category
= symtab
->defs
[i
+ symtab
->cls_def_cnt
];
142 Class
* class = objc_lookup_class (category
->class_name
);
144 /* If the class for the category exists then append its methods. */
148 DEBUG_PRINTF ("processing categories from (module,object): %s, %s\n",
152 /* Do instance methods. */
153 if (category
->instance_methods
)
154 class_add_method_list (class, category
->instance_methods
);
156 /* Do class methods. */
157 if (category
->class_methods
)
158 class_add_method_list ((Class
*) class->class_pointer
,
159 category
->class_methods
);
161 if (category
->protocols
)
163 __objc_init_protocols (category
->protocols
);
164 __objc_class_add_protocols (class, category
->protocols
);
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
);
176 /* Scan the unclaimed category hash. Attempt to attach any unclaimed
177 categories to objects. */
178 for (cell
= &unclaimed_categories
;
180 ({ if (*cell
) cell
= &(*cell
)->tail
; }))
182 Category_t category
= (*cell
)->head
;
183 Class
* class = objc_lookup_class (category
->class_name
);
187 DEBUG_PRINTF ("attaching stored categories to object: %s\n",
190 list_remove_head (cell
);
192 if (category
->instance_methods
)
193 class_add_method_list (class, category
->instance_methods
);
195 if (category
->class_methods
)
196 class_add_method_list ((Class
*) class->class_pointer
,
197 category
->class_methods
);
199 if (category
->protocols
)
201 __objc_init_protocols (category
->protocols
);
202 __objc_class_add_protocols (class, category
->protocols
);
208 if (unclaimed_proto_list
&& objc_lookup_class ("Protocol"))
210 list_mapcar (unclaimed_proto_list
,(void(*)(void*))__objc_init_protocols
);
211 list_free (unclaimed_proto_list
);
212 unclaimed_proto_list
= 0;
217 /* Sanity check the version of gcc used to compile `module'*/
218 static void init_check_module_version(Module_t module
)
220 if ((module
->version
!= OBJC_VERSION
) || (module
->size
!= sizeof (Module
)))
222 fprintf (stderr
, "Module %s version %d doesn't match runtime %d\n",
223 module
->name
, (int)module
->version
, OBJC_VERSION
);
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");
229 fprintf (stderr
, "Objective C internal error -- bad Module size\n");
235 __objc_init_protocols (struct objc_protocol_list
* protos
)
238 static Class
* proto_class
= 0;
244 proto_class
= objc_lookup_class("Protocol");
248 unclaimed_proto_list
= list_cons (protos
, unclaimed_proto_list
);
252 assert (protos
->next
== 0); /* only single ones allowed */
254 for(i
= 0; i
< protos
->count
; i
++)
256 struct objc_protocol
* aProto
= protos
->list
[i
];
257 if (((size_t)aProto
->class_pointer
) == PROTOCOL_VERSION
)
259 /* assign class pointer */
260 aProto
->class_pointer
= proto_class
;
262 /* init super protocols */
263 __objc_init_protocols (aProto
->protocol_list
);
265 else if (protos
->list
[i
]->class_pointer
!= proto_class
)
268 "Version %d doesn't match runtime protocol version %d\n",
269 (int)((char*)protos
->list
[i
]->class_pointer
-(char*)0),
276 static void __objc_class_add_protocols (Class
* class,
277 struct objc_protocol_list
* protos
)
284 protos
->next
= class->protocols
;
285 class->protocols
= protos
;