Removed compiler_addinitclass
[cacao.git] / typeinfo.h
1 /* typeinfo.h - type system used by the type checker
2
3    Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
4    R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser,
5    M. Probst, S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck,
6    P. Tomsich, J. Wenninger
7
8    This file is part of CACAO.
9
10    This program is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License as
12    published by the Free Software Foundation; either version 2, or (at
13    your option) any later version.
14
15    This program is distributed in the hope that it will be useful, but
16    WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
23    02111-1307, USA.
24
25    Contact: cacao@complang.tuwien.ac.at
26
27    Authors: Edwin Steiner
28
29    $Id: typeinfo.h 795 2003-12-16 22:27:52Z edwin $
30
31 */
32
33
34 #ifndef _TYPEINFO_H
35 #define _TYPEINFO_H
36
37 #include "global.h"
38
39 /* resolve typedef cycles *****************************************************/
40
41 typedef struct typeinfo typeinfo;
42 typedef struct typeinfo_mergedlist typeinfo_mergedlist;
43
44 /* global variables ***********************************************************/
45
46 /* XXX move this documentation to global.h */
47 /* The following classinfo pointers are used internally by the type system.
48  * Please do not use them directly, use the TYPEINFO_ macros instead.
49  */
50
51 /*
52  * pseudo_class_Arraystub
53  *     (extends Object implements Cloneable, java.io.Serializable)
54  *
55  *     If two arrays of incompatible component types are merged,
56  *     the resulting reference has no accessible components.
57  *     The result does, however, implement the interfaces Cloneable
58  *     and java.io.Serializable. This pseudo class is used internally
59  *     to represent such results. (They are *not* considered arrays!)
60  *
61  * pseudo_class_Null
62  *
63  *     This pseudo class is used internally to represent the
64  *     null type.
65  */
66
67 /* data structures for the type system ****************************************/
68
69 /* The typeinfo structure stores detailed information on reference types.
70  * (stack elements, variables, etc. with type == TYPE_ADR.)
71  * XXX: exclude ReturnAddresses?
72  *
73  * For primitive types either there is no typeinfo allocated or the
74  * typeclass pointer in the typeinfo struct is NULL.
75  *
76  * CAUTION: The typeinfo structure should be considered opaque outside of
77  *          typeinfo.[ch]. Please use the macros and functions defined here to
78  *          access typeinfo structures!
79  */
80
81 /* At all times *exactly one* of the following conditions is true for
82  * a particular typeinfo struct:
83  *
84  * A) typeclass == NULL
85  *
86  *        In this case the other fields of the structure
87  *        are INVALID.
88  *
89  * B) typeclass == pseudo_class_Null
90  *
91  *        XXX
92  *
93  * C) typeclass is an array class
94  *
95  *        XXX
96  *
97  * D) typeclass == pseudo_class_Arraystub
98  *
99  *        XXX
100  *
101  * E) typeclass is an interface
102  *
103  *        XXX
104  *
105  * F) typeclass is a (non-pseudo-)class != java.lang.Object
106  *
107  *        XXX
108  *        All classinfos in u.merged.list (if any) are
109  *        subclasses of typeclass.
110  *
111  * G) typeclass is java.lang.Object
112  *
113  *        XXX
114  *        In this case u.merged.count and u.merged.list
115  *        are valid and may be non-zero.
116  *        The classinfos in u.merged.list (if any) can be
117  *        classes, interfaces or pseudo classes.
118  */
119
120 /* The following algorithm is used to determine if the type described
121  * by this typeinfo struct supports the interface X:
122  *
123  *     1) If typeclass is X or a subinterface of X the answer is "yes".
124  *     2) If typeclass is a (pseudo) class implementing X the answer is "yes".
125  *     3) XXX If typeclass is not an array and u.merged.count>0
126  *        and all classes/interfaces in u.merged.list implement X
127  *        the answer is "yes".
128  *     4) If none of the above is true the answer is "no".
129  */
130
131 /*
132  * CAUTION: The typeinfo structure should be considered opaque outside of
133  *          typeinfo.[ch]. Please use the macros and functions defined here to
134  *          access typeinfo structures!
135  */
136 struct typeinfo {
137         classinfo           *typeclass;
138         classinfo           *elementclass; /* valid if dimension>0 */
139         typeinfo_mergedlist *merged;
140         u1                   dimension;
141         u1                   elementtype;  /* valid if dimension>0 */
142 };
143
144 struct typeinfo_mergedlist {
145         s4         count;
146         classinfo *list[1]; /* variable length! */
147 };
148
149 /****************************************************************************/
150 /* MACROS                                                                   */
151 /****************************************************************************/
152
153 /* NOTE: These macros take typeinfo *structs* not pointers as arguments.
154  *       You have to dereference any pointers.
155  */
156
157 /* internally used macros ***************************************************/
158
159 /* internal, don't use this explicitly! */
160 #define TYPEINFO_ALLOCMERGED(mergedlist,count)                  \
161     do {(mergedlist) = (typeinfo_mergedlist*)dump_alloc(        \
162             sizeof(typeinfo_mergedlist)                         \
163             + ((count)-1)*sizeof(classinfo*));} while(0)
164
165 /* internal, don't use this explicitly! */
166 #define TYPEINFO_FREEMERGED(mergedlist)
167
168 /* internal, don't use this explicitly! */
169 #define TYPEINFO_FREEMERGED_IF_ANY(mergedlist)
170
171 /* macros for type queries **************************************************/
172
173 #define TYPEINFO_IS_PRIMITIVE(info)                             \
174             ((info).typeclass == NULL)
175
176 #define TYPEINFO_IS_REFERENCE(info)                             \
177             ((info).typeclass != NULL)
178
179 #define TYPEINFO_IS_NULLTYPE(info)                              \
180             ((info).typeclass == pseudo_class_Null)
181
182 #define TYPEINFO_IS_NEWOBJECT(info)                             \
183             ((info).typeclass == pseudo_class_New)
184
185 /* only use this if TYPEINFO_IS_NEWOBJECT returned true! */
186 #define TYPEINFO_NEWOBJECT_INSTRUCTION(info)                    \
187             ((void *)(info).elementclass)
188
189 /* macros for array type queries ********************************************/
190
191 #define TYPEINFO_IS_ARRAY(info)                                 \
192             ( TYPEINFO_IS_REFERENCE(info)                       \
193               && ((info).dimension != 0) )
194
195 #define TYPEINFO_IS_SIMPLE_ARRAY(info)                          \
196             ( ((info).dimension == 1) )
197
198 #define TYPEINFO_IS_ARRAY_ARRAY(info)                           \
199             ( ((info).dimension >= 2) )
200
201 #define TYPEINFO_IS_PRIMITIVE_ARRAY(info,arraytype)             \
202             ( TYPEINFO_IS_SIMPLE_ARRAY(info)                    \
203               && ((info).elementtype == (arraytype)) )
204
205 #define TYPEINFO_IS_OBJECT_ARRAY(info)                          \
206             ( TYPEINFO_IS_SIMPLE_ARRAY(info)                    \
207               && ((info).elementclass != NULL) )
208
209 /* assumes that info describes an array type */
210 #define TYPEINFO_IS_ARRAY_OF_REFS_NOCHECK(info)                 \
211             ( ((info).elementclass != NULL)                     \
212               || ((info).dimension >= 2) )
213
214 #define TYPEINFO_IS_ARRAY_OF_REFS(info)                         \
215             ( TYPEINFO_IS_ARRAY(info)                           \
216               && TYPEINFO_IS_ARRAY_OF_REFS_NOCHECK(info) )
217
218 /* queries allowing the null type ********************************************/
219
220 #define TYPEINFO_MAYBE_ARRAY(info)                              \
221     (TYPEINFO_IS_ARRAY(info) || TYPEINFO_IS_NULLTYPE(info))
222
223 #define TYPEINFO_MAYBE_PRIMITIVE_ARRAY(info,at)                 \
224     (TYPEINFO_IS_PRIMITIVE_ARRAY(info,at) || TYPEINFO_IS_NULLTYPE(info))
225
226 #define TYPEINFO_MAYBE_ARRAY_OF_REFS(info)                      \
227     (TYPEINFO_IS_ARRAY_OF_REFS(info) || TYPEINFO_IS_NULLTYPE(info))
228
229 /* macros for initializing typeinfo structures ******************************/
230
231 #define TYPEINFO_INIT_PRIMITIVE(info)                           \
232          do {(info).typeclass = NULL;                           \
233              (info).elementclass = NULL;                        \
234              (info).merged = NULL;                              \
235              (info).dimension = 0;                              \
236              (info).elementtype = 0;} while(0)
237
238 #define TYPEINFO_INIT_NON_ARRAY_CLASSINFO(info,cinfo)   \
239          do {(info).typeclass = (cinfo);                \
240              (info).elementclass = NULL;                \
241              (info).merged = NULL;                      \
242              (info).dimension = 0;                      \
243              (info).elementtype = 0;} while(0)
244
245 #define TYPEINFO_INIT_NULLTYPE(info)                            \
246             TYPEINFO_INIT_CLASSINFO(info,pseudo_class_Null)
247
248 #define TYPEINFO_INIT_NEWOBJECT(info,instr)             \
249          do {(info).typeclass = pseudo_class_New;       \
250              (info).elementclass = (classinfo*) (instr);\
251              (info).merged = NULL;                      \
252              (info).dimension = 0;                      \
253              (info).elementtype = 0;} while(0)
254
255 #define TYPEINFO_INIT_PRIMITIVE_ARRAY(info,arraytype)                   \
256     TYPEINFO_INIT_CLASSINFO(info,primitivetype_table[arraytype].arrayclass);
257
258 #define TYPEINFO_INIT_CLASSINFO(info,cls)                               \
259         do {if (((info).typeclass = (cls))->vftbl->arraydesc) {         \
260                 if ((cls)->vftbl->arraydesc->elementvftbl)              \
261                     (info).elementclass = (cls)->vftbl->arraydesc->elementvftbl->class; \
262                 else                                                    \
263                     (info).elementclass = NULL;                         \
264                 (info).dimension = (cls)->vftbl->arraydesc->dimension;  \
265                 (info).elementtype = (cls)->vftbl->arraydesc->elementtype; \
266             }                                                           \
267             else {                                                      \
268                 (info).elementclass = NULL;                             \
269                 (info).dimension = 0;                                   \
270                 (info).elementtype = 0;                                 \
271             }                                                           \
272             (info).merged = NULL;} while(0)
273
274 #define TYPEINFO_INIT_FROM_FIELDINFO(info,fi)                   \
275             typeinfo_init_from_descriptor(&(info),              \
276                 (fi)->descriptor->text,utf_end((fi)->descriptor));
277
278 /* macros for writing types (destination must have been initialized) ********/
279 /* XXX delete them? */
280 #if 0
281
282 #define TYPEINFO_PUT_NULLTYPE(info)                             \
283     do {(info).typeclass = pseudo_class_Null;} while(0)
284
285 #define TYPEINFO_PUT_NON_ARRAY_CLASSINFO(info,cinfo)            \
286     do {(info).typeclass = (cinfo);} while(0)
287
288 #define TYPEINFO_PUT_CLASSINFO(info,cls)                                \
289     do {if (((info).typeclass = (cls))->vftbl->arraydesc) {             \
290                 if ((cls)->vftbl->arraydesc->elementvftbl)                \
291                     (info).elementclass = (cls)->vftbl->arraydesc->elementvftbl->class; \
292                 (info).dimension = (cls)->vftbl->arraydesc->dimension;    \
293                 (info).elementtype = (cls)->vftbl->arraydesc->elementtype; \
294         }} while(0)
295
296 /* srcarray must be an array (not checked) */
297 #define TYPEINFO_PUT_COMPONENT(srcarray,dst)                    \
298     do {typeinfo_put_component(&(srcarray),&(dst));} while(0)
299
300 #endif
301
302 /* macros for copying types (destinition is not checked or freed) ***********/
303
304 /* TYPEINFO_COPY makes a shallow copy, the merged pointer is simply copied. */
305 #define TYPEINFO_COPY(src,dst)                                  \
306     do {(dst) = (src);} while(0)
307
308 /* TYPEINFO_CLONE makes a deep copy, the merged list (if any) is duplicated
309  * into a newly allocated array.
310  */
311 #define TYPEINFO_CLONE(src,dst)                                 \
312     do {(dst) = (src);                                          \
313         if ((dst).merged) typeinfo_clone(&(src),&(dst));} while(0)
314
315 /****************************************************************************/
316 /* FUNCTIONS                                                                */
317 /****************************************************************************/
318
319 /* inquiry functions (read-only) ********************************************/
320
321 bool typeinfo_is_array(typeinfo *info);
322 bool typeinfo_is_primitive_array(typeinfo *info,int arraytype);
323 bool typeinfo_is_array_of_refs(typeinfo *info);
324
325 bool typeinfo_implements_interface(typeinfo *info,classinfo *interf);
326 bool typeinfo_is_assignable(typeinfo *value,typeinfo *dest);
327
328 /* initialization functions *************************************************/
329
330 void typeinfo_init_from_descriptor(typeinfo *info,char *utf_ptr,char *end_ptr);
331 void typeinfo_init_component(typeinfo *srcarray,typeinfo *dst);
332
333 int  typeinfo_count_method_args(utf *d,bool twoword); /* this not included */
334 void typeinfo_init_from_method_args(utf *desc,u1 *typebuf,
335                                     typeinfo *infobuf,
336                                     int buflen,bool twoword,
337                                     int *returntype,typeinfo *returntypeinfo);
338
339 void typeinfo_clone(typeinfo *src,typeinfo *dest);
340
341 /* functions for the type system ********************************************/
342
343 void typeinfo_free(typeinfo *info);
344
345 bool typeinfo_merge(typeinfo *dest,typeinfo* y);
346
347 /* debugging helpers ********************************************************/
348
349 #ifdef TYPEINFO_DEBUG
350
351 #include <stdio.h>
352
353 void typeinfo_test();
354 void typeinfo_init_from_fielddescriptor(typeinfo *info,char *desc);
355 void typeinfo_print(FILE *file,typeinfo *info,int indent);
356 void typeinfo_print_short(FILE *file,typeinfo *info);
357 void typeinfo_print_type(FILE *file,int type,typeinfo *info);
358
359 #endif /* TYPEINFO_DEBUG */
360
361 #endif /* _TYPEINFO_H */
362
363
364 /*
365  * These are local overrides for various environment variables in Emacs.
366  * Please do not remove this and leave it at the end of the file, where
367  * Emacs will automagically detect them.
368  * ---------------------------------------------------------------------
369  * Local variables:
370  * mode: c
371  * indent-tabs-mode: t
372  * c-basic-offset: 4
373  * tab-width: 4
374  * End:
375  */