e779da73483752ab570b6525bc0836044659832a
[cacao.git] / src / vm / jit / verify / 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 696 2003-12-06 20:10:05Z edwin $
30
31 */
32
33 #ifndef __typeinfo_h_
34 #define __typeinfo_h_
35
36 #include "global.h"
37
38 /* resolve typedef cycles *****************************************************/
39
40 typedef struct typeinfo typeinfo;
41 typedef struct typeinfo_mergedlist typeinfo_mergedlist;
42
43 /* global variables ***********************************************************/
44
45 /* XXX move this documentation to global.h */
46 /* The following classinfo pointers are used internally by the type system.
47  * Please do not use them directly, use the TYPEINFO_ macros instead.
48  */
49
50 /*
51  * pseudo_class_Arraystub
52  *     (extends Object implements Cloneable, java.io.Serializable)
53  *
54  *     If two arrays of incompatible component types are merged,
55  *     the resulting reference has no accessible components.
56  *     The result does, however, implement the interfaces Cloneable
57  *     and java.io.Serializable. This pseudo class is used internally
58  *     to represent such results. (They are *not* considered arrays!)
59  *
60  * pseudo_class_Null
61  *
62  *     This pseudo class is used internally to represent the
63  *     null type.
64  */
65
66 /* data structures for the type system ****************************************/
67
68 /* The typeinfo structure stores detailed information on reference types.
69  * (stack elements, variables, etc. with type == TYPE_ADR.)
70  * XXX: exclude ReturnAddresses?
71  *
72  * For primitive types either there is no typeinfo allocated or the
73  * typeclass pointer in the typeinfo struct is NULL.
74  *
75  * CAUTION: The typeinfo structure should be considered opaque outside of
76  *          typeinfo.[ch]. Please use the macros and functions defined here to
77  *          access typeinfo structures!
78  */
79
80 /* At all times *exactly one* of the following conditions is true for
81  * a particular typeinfo struct:
82  *
83  * A) typeclass == NULL
84  *
85  *        In this case the other fields of the structure
86  *        are INVALID.
87  *
88  * B) typeclass == pseudo_class_Null
89  *
90  *        XXX
91  *
92  * C) typeclass is an array class
93  *
94  *        XXX
95  *
96  * D) typeclass == pseudo_class_Arraystub
97  *
98  *        XXX
99  *
100  * E) typeclass is an interface
101  *
102  *        XXX
103  *
104  * F) typeclass is a (non-pseudo-)class != java.lang.Object
105  *
106  *        XXX
107  *        All classinfos in u.merged.list (if any) are
108  *        subclasses of typeclass.
109  *
110  * G) typeclass is java.lang.Object
111  *
112  *        XXX
113  *        In this case u.merged.count and u.merged.list
114  *        are valid and may be non-zero.
115  *        The classinfos in u.merged.list (if any) can be
116  *        classes, interfaces or pseudo classes.
117  */
118
119 /* The following algorithm is used to determine if the type described
120  * by this typeinfo struct supports the interface X:
121  *
122  *     1) If typeclass is X or a subinterface of X the answer is "yes".
123  *     2) If typeclass is a (pseudo) class implementing X the answer is "yes".
124  *     3) XXX If typeclass is not an array and u.merged.count>0
125  *        and all classes/interfaces in u.merged.list implement X
126  *        the answer is "yes".
127  *     4) If none of the above is true the answer is "no".
128  */
129
130 /*
131  * CAUTION: The typeinfo structure should be considered opaque outside of
132  *          typeinfo.[ch]. Please use the macros and functions defined here to
133  *          access typeinfo structures!
134  */
135 struct typeinfo {
136         classinfo           *typeclass;
137         classinfo           *elementclass; /* valid if dimension>0 */
138         typeinfo_mergedlist *merged;
139         u1                   dimension;
140         u1                   elementtype;  /* valid if dimension>0 */
141 };
142
143 struct typeinfo_mergedlist {
144         s4         count;
145         classinfo *list[1]; /* variable length! */
146 };
147
148 /****************************************************************************/
149 /* MACROS                                                                   */
150 /****************************************************************************/
151
152 /* XXX wrap macro blocks in do { } while(0) */
153
154 /* NOTE: These macros take typeinfo *structs* not pointers as arguments.
155  *       You have to dereference any pointers.
156  */
157
158 /* internally used macros ***************************************************/
159
160 /* internal, don't use this explicitly! */
161 #define TYPEINFO_ALLOCMERGED(mergedlist,count)                  \
162             {(mergedlist) = (typeinfo_mergedlist*)dump_alloc(   \
163                 sizeof(typeinfo_mergedlist)                     \
164                 + ((count)-1)*sizeof(classinfo*));}
165
166 /* internal, don't use this explicitly! */
167 #define TYPEINFO_FREEMERGED(mergedlist)
168
169 /* internal, don't use this explicitly! */
170 #define TYPEINFO_FREEMERGED_IF_ANY(mergedlist)
171
172 /* macros for type queries **************************************************/
173
174 #define TYPEINFO_IS_PRIMITIVE(info)                             \
175             ((info).typeclass == NULL)
176
177 #define TYPEINFO_IS_REFERENCE(info)                             \
178             ((info).typeclass != NULL)
179
180 #define TYPEINFO_IS_NULLTYPE(info)                              \
181             ((info).typeclass == pseudo_class_Null)
182
183 /* macros for array type queries ********************************************/
184
185 #define TYPEINFO_IS_ARRAY(info)                                 \
186             ( TYPEINFO_IS_REFERENCE(info)                       \
187               && ((info).dimension != 0) )
188
189 #define TYPEINFO_IS_SIMPLE_ARRAY(info)                          \
190             ( ((info).dimension == 1) )
191
192 #define TYPEINFO_IS_ARRAY_ARRAY(info)                           \
193             ( ((info).dimension >= 2) )
194
195 #define TYPEINFO_IS_PRIMITIVE_ARRAY(info,arraytype)             \
196             ( TYPEINFO_IS_SIMPLE_ARRAY(info)                    \
197               && ((info).elementtype == (arraytype)) )
198
199 #define TYPEINFO_IS_OBJECT_ARRAY(info)                          \
200             ( TYPEINFO_IS_SIMPLE_ARRAY(info)                    \
201               && ((info).elementclass != NULL) )
202
203 /* assumes that info describes an array type */
204 #define TYPEINFO_IS_ARRAY_OF_REFS_NOCHECK(info)                 \
205             ( ((info).elementclass != NULL)                     \
206               || ((info).dimension >= 2) )
207
208 #define TYPEINFO_IS_ARRAY_OF_REFS(info)                         \
209             ( TYPEINFO_IS_ARRAY(info)                           \
210               && TYPEINFO_IS_ARRAY_OF_REFS_NOCHECK(info) )
211
212 /* queries allowing null types **********************************************/
213
214 #define TYPEINFO_MAYBE_ARRAY(info)                              \
215     (TYPEINFO_IS_ARRAY(info) || TYPEINFO_IS_NULLTYPE(info))
216
217 #define TYPEINFO_MAYBE_PRIMITIVE_ARRAY(info,at)                 \
218     (TYPEINFO_IS_PRIMITIVE_ARRAY(info,at) || TYPEINFO_IS_NULLTYPE(info))
219
220 #define TYPEINFO_MAYBE_ARRAY_OF_REFS(info)                      \
221     (TYPEINFO_IS_ARRAY_OF_REFS(info) || TYPEINFO_IS_NULLTYPE(info))
222
223
224 /* macros for initializing typeinfo structures ******************************/
225
226 #define TYPEINFO_INIT_PRIMITIVE(info)                           \
227             {(info).typeclass = NULL;                           \
228              (info).elementclass = NULL;                        \
229              (info).merged = NULL;                              \
230              (info).dimension = 0;                              \
231              (info).elementtype = 0;}
232
233 #define TYPEINFO_INIT_NON_ARRAY_CLASSINFO(info,cinfo)   \
234             {(info).typeclass = (cinfo);                \
235              (info).elementclass = NULL;                \
236              (info).merged = NULL;                      \
237              (info).dimension = 0;                      \
238              (info).elementtype = 0;}
239
240 #define TYPEINFO_INIT_NULLTYPE(info)                            \
241             TYPEINFO_INIT_CLASSINFO(info,pseudo_class_Null)
242
243 #define TYPEINFO_INIT_PRIMITIVE_ARRAY(info,arraytype)                   \
244     TYPEINFO_INIT_CLASSINFO(info,primitivetype_table[arraytype].arrayclass);
245
246 #define TYPEINFO_INIT_CLASSINFO(info,cls)                               \
247         {if (((info).typeclass = (cls))->vftbl->arraydesc) {              \
248                 if ((cls)->vftbl->arraydesc->elementvftbl)                \
249                     (info).elementclass = (cls)->vftbl->arraydesc->elementvftbl->class; \
250                 else                                                    \
251                     (info).elementclass = NULL;                         \
252                 (info).dimension = (cls)->vftbl->arraydesc->dimension;    \
253                 (info).elementtype = (cls)->vftbl->arraydesc->elementtype;\
254             }                                                           \
255             else {                                                      \
256                 (info).elementclass = NULL;                             \
257                 (info).dimension = 0;                                   \
258                 (info).elementtype = 0;                                 \
259             }                                                           \
260             (info).merged = NULL;}
261
262 #define TYPEINFO_INIT_FROM_FIELDINFO(info,fi)                   \
263             typeinfo_init_from_descriptor(&(info),              \
264                 (fi)->descriptor->text,utf_end((fi)->descriptor));
265
266 /* macros for freeing typeinfo structures ***********************************/
267
268 #define TYPEINFO_FREE(info)                                     \
269             {TYPEINFO_FREEMERGED_IF_ANY((info).merged);         \
270              (info).merged = NULL;}
271
272 /* macros for writing types (destination must have been initialized) ********/
273 /* XXX delete them? */
274
275 #define TYPEINFO_PUT_NULLTYPE(info)                             \
276             {(info).typeclass = pseudo_class_Null;}
277
278 #define TYPEINFO_PUT_NON_ARRAY_CLASSINFO(info,cinfo)            \
279             {(info).typeclass = (cinfo);}
280
281 #define TYPEINFO_PUT_CLASSINFO(info,cls)                                \
282         {if (((info).typeclass = (cls))->vftbl->arraydesc) {              \
283                 if ((cls)->vftbl->arraydesc->elementvftbl)                \
284                     (info).elementclass = (cls)->vftbl->arraydesc->elementvftbl->class; \
285                 (info).dimension = (cls)->vftbl->arraydesc->dimension;    \
286                 (info).elementtype = (cls)->vftbl->arraydesc->elementtype; \
287             }}
288
289 /* srcarray must be an array (not checked) */
290 #define TYPEINFO_PUT_COMPONENT(srcarray,dst)                    \
291             {typeinfo_put_component(&(srcarray),&(dst));}
292
293 /* macros for copying types (destinition is not checked or freed) ***********/
294
295 /* TYPEINFO_COPY makes a shallow copy, the merged pointer is simply copied. */
296 #define TYPEINFO_COPY(src,dst)                                  \
297             {(dst) = (src);}
298
299 /* TYPEINFO_CLONE makes a deep copy, the merged list (if any) is duplicated
300  * into a newly allocated array.
301  */
302 #define TYPEINFO_CLONE(src,dst)                                 \
303             {(dst) = (src);                                     \
304              if ((dst).merged) typeinfo_clone(&(src),&(dst));}
305
306 /****************************************************************************/
307 /* FUNCTIONS                                                                */
308 /****************************************************************************/
309
310 /* inquiry functions (read-only) ********************************************/
311
312 bool typeinfo_is_array(typeinfo *info);
313 bool typeinfo_is_primitive_array(typeinfo *info,int arraytype);
314 bool typeinfo_is_array_of_refs(typeinfo *info);
315
316 bool typeinfo_implements_interface(typeinfo *info,classinfo *interf);
317 bool typeinfo_is_assignable(typeinfo *value,typeinfo *dest);
318
319 /* initialization functions *************************************************/
320
321 void typeinfo_init_from_descriptor(typeinfo *info,char *utf_ptr,char *end_ptr);
322 void typeinfo_init_component(typeinfo *srcarray,typeinfo *dst);
323
324 int  typeinfo_count_method_args(utf *d,bool twoword); /* this not included */
325 void typeinfo_init_from_method_args(utf *desc,u1 *typebuf,
326                                     typeinfo *infobuf,
327                                     int buflen,bool twoword,
328                                     int *returntype,typeinfo *returntypeinfo);
329
330 void typeinfo_clone(typeinfo *src,typeinfo *dest);
331
332 /* functions for the type system ********************************************/
333
334 void typeinfo_free(typeinfo *info);
335
336 bool typeinfo_merge(typeinfo *dest,typeinfo* y);
337
338 /* debugging helpers ********************************************************/
339
340 #ifdef TYPEINFO_DEBUG
341
342 void typeinfo_test();
343 void typeinfo_init_from_fielddescriptor(typeinfo *info,char *desc);
344 void typeinfo_print(FILE *file,typeinfo *info,int indent);
345 void typeinfo_print_short(FILE *file,typeinfo *info);
346 void typeinfo_print_type(FILE *file,int type,typeinfo *info);
347
348 #endif // TYPEINFO_DEBUG
349
350 #endif