1 /* typeinfo.h - type system used by the type checker
3 Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
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.
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.
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., 51 Franklin Street, Fifth Floor, Boston, MA
25 Contact: cacao@cacaojvm.org
27 Authors: Edwin Steiner
29 $Id: typeinfo.h 5601 2006-10-01 14:37:17Z edwin $
36 /* resolve typedef cycles *****************************************************/
38 typedef struct typeinfo typeinfo;
39 typedef struct typeinfo_mergedlist typeinfo_mergedlist;
40 typedef struct typedescriptor typedescriptor;
45 #include "vm/global.h"
46 #include "vm/references.h"
49 /* configuration **************************************************************/
52 * TYPECHECK_STATISTICS activates gathering statistical information.
53 * TYPEINFO_DEBUG activates debug checks and debug helpers in typeinfo.c
54 * TYPECHECK_DEBUG activates debug checks in typecheck.c
55 * TYPEINFO_DEBUG_TEST activates the typeinfo test at startup.
56 * TYPECHECK_VERBOSE_IMPORTANT activates important debug messages
57 * TYPECHECK_VERBOSE activates all debug messages
58 * TYPEINFO_VERBOSE activates debug prints in typeinfo.c
60 #ifdef ENABLE_VERIFIER
62 /*#define TYPECHECK_STATISTICS*/
63 #define TYPEINFO_DEBUG
64 /*#define TYPEINFO_VERBOSE*/
65 #define TYPECHECK_DEBUG
66 /*#define TYPEINFO_DEBUG_TEST*/
67 /*#define TYPECHECK_VERBOSE*/
68 /*#define TYPECHECK_VERBOSE_IMPORTANT*/
69 #if defined(TYPECHECK_VERBOSE) || defined(TYPECHECK_VERBOSE_IMPORTANT)
70 #define TYPECHECK_VERBOSE_OPT
75 #ifdef TYPECHECK_VERBOSE_OPT
76 extern bool opt_typecheckverbose;
79 /* types **********************************************************************/
81 /* typecheck_result - return type for boolean and tristate functions */
82 /* which may also throw exceptions (typecheck_FAIL). */
84 /* NOTE: Use the enum values, not the uppercase #define macros! */
85 #define TYPECHECK_MAYBE 0x02
86 #define TYPECHECK_FAIL 0x04
89 typecheck_FALSE = false,
90 typecheck_TRUE = true,
91 typecheck_MAYBE = TYPECHECK_MAYBE,
92 typecheck_FAIL = TYPECHECK_FAIL
95 /* check that typecheck_MAYBE is not ambiguous */
96 #if TYPECHECK_MAYBE == true
97 #error "`typecheck_MAYBE` must not be the same as `true`"
99 #if TYPECHECK_MAYBE == false
100 #error "`typecheck_MAYBE` must not be the same as `false`"
103 /* check that typecheck_FAIL is not ambiguous */
104 #if (true & TYPECHECK_FAIL) != 0
105 #error "`true` must not have bit 0x02 set (conflicts with typecheck_FAIL)"
108 /* data structures for the type system ****************************************/
110 /* The typeinfo structure stores detailed information on address types.
111 * (stack elements, variables, etc. with type == TYPE_ADR.)
113 * There are two kinds of address types which can be distinguished by
114 * the value of the typeclass field:
116 * 1) typeclass == NULL: returnAddress type
117 * use TYPEINFO_IS_PRIMITIVE to test for this
119 * 2) typeclass != NULL: reference type
120 * use TYPEINFO_IS_REFERENCE to test for this
122 * Note: For non-address types either there is no typeinfo allocated
123 * or the fields of the typeinfo struct contain undefined values!
124 * DO NOT access the typeinfo for non-address types!
126 * CAUTION: The typeinfo structure should be considered opaque outside of
127 * typeinfo.[ch]. Please use the macros and functions defined here to
128 * access typeinfo structures!
131 /* At all times *exactly one* of the following conditions is true for
132 * a particular typeinfo struct:
134 * A) typeclass == NULL
136 * This is a returnAddress type.
138 * Use TYPEINFO_IS_PRIMITIVE to check for this.
139 * Use TYPEINFO_RETURNADDRESS to access the pointer in elementclass.
140 * Don't access other fields of the struct.
142 * B) typeclass == pseudo_class_Null
144 * This is the null-reference type.
145 * Use TYPEINFO_IS_NULLTYPE to check for this.
146 * Don't access other fields of the struct.
148 * C) typeclass == pseudo_class_New
150 * This is an 'uninitialized object' type. elementclass can be
151 * cast to instruction* and points to the NEW instruction
152 * responsible for creating this type.
154 * Use TYPEINFO_NEWOBJECT_INSTRUCTION to access the pointer in
156 * Don't access other fields of the struct.
158 * D) typeclass == pseudo_class_Arraystub
160 * This type is used to represent the result of merging array types
161 * with incompatible component types. An arraystub allows no access
162 * to its components (since their type is undefined), but it allows
163 * operations which act directly on an arbitrary array type (such as
164 * requesting the array size).
166 * NOTE: An array stub does *not* count as an array. It has dimension
169 * Otherwise like a normal class reference type.
170 * Don't access other fields of the struct.
172 * E) typeclass is an array class
174 * An array reference.
175 * elementclass...typeclass of the element type
176 * dimension......dimension of the array (>=1)
177 * elementtype....element type (ARRAYTYPE_...)
178 * merged.........mergedlist of the element type
180 * Use TYPEINFO_IS_ARRAY to check for this case.
182 * The elementclass may be one of the following:
183 * 1) pseudo_class_Arraystub
184 * 2) an unresolved type
185 * 3) a loaded interface
186 * 4) a loaded (non-pseudo-,non-array-)class != (BOOTSTRAP)java.lang.Object
187 * Note: `merged` may be used
188 * 5) (BOOTSTRAP)java.lang.Object
189 * Note: `merged` may be used
191 * For the semantics of the merged field in cases 4) and 5) consult the
192 * corresponding descriptions with `elementclass` replaced by `typeclass`.
194 * F) typeclass is an unresolved type (a symbolic class/interface reference)
196 * The type has not been resolved yet. (Meaning it corresponds to an
197 * unloaded class or interface).
198 * Don't access other fields of the struct.
200 * G) typeclass is a loaded interface
202 * An interface reference type.
203 * Don't access other fields of the struct.
205 * H) typeclass is a loaded (non-pseudo-,non-array-)class != (BOOTSTRAP)java.lang.Object
207 * A loaded class type.
208 * All classref_or_classinfos in u.merged.list (if any) are
209 * loaded subclasses of typeclass (no interfaces, array classes, or
211 * Don't access other fields of the struct.
213 * I) typeclass is (BOOTSTRAP)java.lang.Object
215 * The most general kind of reference type.
216 * In this case u.merged.count and u.merged.list
217 * are valid and may be non-zero.
218 * The classref_or_classinfos in u.merged.list (if any) may be
219 * classes, interfaces, pseudo classes or unresolved types.
220 * Don't access other fields of the struct.
223 /* The following algorithm is used to determine if the type described
224 * by this typeinfo struct supports the interface X: * XXX add MAYBE *
226 * 1) If typeclass is X or a subinterface of X the answer is "yes".
227 * 2) If typeclass is a (pseudo) class implementing X the answer is "yes".
228 * 3) If typeclass is not an array and u.merged.count>0
229 * and all classes/interfaces in u.merged.list implement X
230 * the answer is "yes".
231 * 4) If none of the above is true the answer is "no".
235 * CAUTION: The typeinfo structure should be considered opaque outside of
236 * typeinfo.[ch]. Please use the macros and functions defined here to
237 * access typeinfo structures!
240 classref_or_classinfo typeclass;
241 classref_or_classinfo elementclass; /* valid if dimension>0 */ /* various uses! */
242 typeinfo_mergedlist *merged;
244 u1 elementtype; /* valid if dimension>0 */
247 struct typeinfo_mergedlist {
249 classref_or_classinfo list[1]; /* variable length! */
252 /* a type descriptor stores a basic type and the typeinfo */
253 /* this is used for storing the type of a local variable, and for */
254 /* storing types in the signature of a method */
256 struct typedescriptor {
257 typeinfo typeinfo; /* valid if type == TYPE_ADR */
258 u1 type; /* basic type (TYPE_INT, ...) */
261 /****************************************************************************/
263 /****************************************************************************/
265 /* NOTE: The TYPEINFO macros take typeinfo *structs*, not pointers as
266 * arguments. You have to dereference any pointers.
269 /* typevectors **************************************************************/
271 #define TYPEVECTOR_SIZE(size) \
272 ((size) * sizeof(varinfo))
274 #define DNEW_TYPEVECTOR(size) \
275 ((varinfo*)dump_alloc(TYPEVECTOR_SIZE(size)))
277 #define DMNEW_TYPEVECTOR(num,size) \
278 ((void*)dump_alloc((num) * TYPEVECTOR_SIZE(size)))
280 #define MGET_TYPEVECTOR(array,index,size) \
281 ((varinfo*) (((u1*)(array)) + TYPEVECTOR_SIZE(size) * (index)))
283 /* internally used macros ***************************************************/
285 /* internal, don't use this explicitly! */
286 #define TYPEINFO_ALLOCMERGED(mergedlist,count) \
287 do {(mergedlist) = (typeinfo_mergedlist*)dump_alloc( \
288 sizeof(typeinfo_mergedlist) \
289 + ((count)-1)*sizeof(classinfo*));} while(0)
291 /* internal, don't use this explicitly! */
292 #define TYPEINFO_FREEMERGED(mergedlist)
294 /* internal, don't use this explicitly! */
295 #define TYPEINFO_FREEMERGED_IF_ANY(mergedlist)
297 /* macros for type queries **************************************************/
299 #define TYPEINFO_IS_PRIMITIVE(info) \
300 ((info).typeclass.any == NULL)
302 #define TYPEINFO_IS_REFERENCE(info) \
303 ((info).typeclass.any != NULL)
305 #define TYPEINFO_IS_NULLTYPE(info) \
306 ((info).typeclass.cls == pseudo_class_Null)
308 #define TYPEINFO_IS_NEWOBJECT(info) \
309 ((info).typeclass.cls == pseudo_class_New)
311 #define TYPEINFO_IS_JAVA_LANG_CLASS(info) \
312 ((info).typeclass.cls == class_java_lang_Class)
314 /* only use this if TYPEINFO_IS_PRIMITIVE returned true! */
315 #define TYPEINFO_RETURNADDRESS(info) \
316 ((info).elementclass.any)
318 /* only use this if TYPEINFO_IS_NEWOBJECT returned true! */
319 #define TYPEINFO_NEWOBJECT_INSTRUCTION(info) \
320 ((info).elementclass.any)
322 /* only use this if TYPEINFO_IS_JAVA_LANG_CLASS returned true! */
323 #define TYPEINFO_JAVA_LANG_CLASS_CLASSREF(info) \
324 ((info).elementclass.ref)
326 /* macros for array type queries ********************************************/
328 #define TYPEINFO_IS_ARRAY(info) \
329 ( TYPEINFO_IS_REFERENCE(info) \
330 && ((info).dimension != 0) )
332 #define TYPEINFO_IS_SIMPLE_ARRAY(info) \
333 ( ((info).dimension == 1) )
335 #define TYPEINFO_IS_ARRAY_ARRAY(info) \
336 ( ((info).dimension >= 2) )
338 #define TYPEINFO_IS_PRIMITIVE_ARRAY(info,arraytype) \
339 ( TYPEINFO_IS_SIMPLE_ARRAY(info) \
340 && ((info).elementtype == (arraytype)) )
342 #define TYPEINFO_IS_OBJECT_ARRAY(info) \
343 ( TYPEINFO_IS_SIMPLE_ARRAY(info) \
344 && ((info).elementclass.any != NULL) )
346 /* assumes that info describes an array type */
347 #define TYPEINFO_IS_ARRAY_OF_REFS_NOCHECK(info) \
348 ( ((info).elementclass.any != NULL) \
349 || ((info).dimension >= 2) )
351 #define TYPEINFO_IS_ARRAY_OF_REFS(info) \
352 ( TYPEINFO_IS_ARRAY(info) \
353 && TYPEINFO_IS_ARRAY_OF_REFS_NOCHECK(info) )
355 #define TYPE_IS_RETURNADDRESS(type,info) \
356 ( ((type)==TYPE_ADR) \
357 && TYPEINFO_IS_PRIMITIVE(info) )
359 #define TYPE_IS_REFERENCE(type,info) \
360 ( ((type)==TYPE_ADR) \
361 && !TYPEINFO_IS_PRIMITIVE(info) )
363 #define TYPEDESC_IS_RETURNADDRESS(td) \
364 TYPE_IS_RETURNADDRESS((td).type,(td).typeinfo)
366 #define TYPEDESC_IS_REFERENCE(td) \
367 TYPE_IS_REFERENCE((td).type,(td).typeinfo)
369 /* queries allowing the null type ********************************************/
371 #define TYPEINFO_MAYBE_ARRAY(info) \
372 (TYPEINFO_IS_ARRAY(info) || TYPEINFO_IS_NULLTYPE(info))
374 #define TYPEINFO_MAYBE_PRIMITIVE_ARRAY(info,at) \
375 (TYPEINFO_IS_PRIMITIVE_ARRAY(info,at) || TYPEINFO_IS_NULLTYPE(info))
377 #define TYPEINFO_MAYBE_ARRAY_OF_REFS(info) \
378 (TYPEINFO_IS_ARRAY_OF_REFS(info) || TYPEINFO_IS_NULLTYPE(info))
380 /* macros for initializing typeinfo structures ******************************/
382 #define TYPEINFO_INIT_PRIMITIVE(info) \
383 do {(info).typeclass.any = NULL; \
384 (info).elementclass.any = NULL; \
385 (info).merged = NULL; \
386 (info).dimension = 0; \
387 (info).elementtype = 0;} while(0)
389 #define TYPEINFO_INIT_RETURNADDRESS(info,adr) \
390 do {(info).typeclass.any = NULL; \
391 (info).elementclass.any = (adr); \
392 (info).merged = NULL; \
393 (info).dimension = 0; \
394 (info).elementtype = 0;} while(0)
396 #define TYPEINFO_INIT_NON_ARRAY_CLASSINFO(info,cinfo) \
397 do {(info).typeclass.cls = (cinfo); \
398 (info).elementclass.any = NULL; \
399 (info).merged = NULL; \
400 (info).dimension = 0; \
401 (info).elementtype = 0;} while(0)
403 #define TYPEINFO_INIT_JAVA_LANG_CLASS(info,c) \
404 do {(info).typeclass.any = class_java_lang_Class; \
405 (info).elementclass = (c); \
406 (info).merged = NULL; \
407 (info).dimension = 0; \
408 (info).elementtype = 0;} while(0)
410 #define TYPEINFO_INIT_NULLTYPE(info) \
411 TYPEINFO_INIT_NON_ARRAY_CLASSINFO(info,pseudo_class_Null)
413 #define TYPEINFO_INIT_NEWOBJECT(info,instr) \
414 do {(info).typeclass.cls = pseudo_class_New; \
415 (info).elementclass.any = (instr); \
416 (info).merged = NULL; \
417 (info).dimension = 0; \
418 (info).elementtype = 0;} while(0)
420 #define TYPEINFO_INIT_PRIMITIVE_ARRAY(info,arraytype) \
421 typeinfo_init_classinfo(&(info),primitivetype_table[arraytype].arrayclass);
423 /* macros for copying types (destinition is not checked or freed) ***********/
425 /* TYPEINFO_COPY makes a shallow copy, the merged pointer is simply copied. */
426 #define TYPEINFO_COPY(src,dst) \
427 do {(dst) = (src);} while(0)
429 /* TYPEINFO_CLONE makes a deep copy, the merged list (if any) is duplicated
430 * into a newly allocated array.
432 #define TYPEINFO_CLONE(src,dst) \
434 if ((dst).merged) typeinfo_clone(&(src),&(dst));} while(0)
436 /****************************************************************************/
438 /****************************************************************************/
440 /* typevector functions *****************************************************/
442 /* element read-only access */
443 bool typevector_checktype(varinfo *set,int index,int type);
444 bool typevector_checkreference(varinfo *set,int index);
445 bool typevector_checkretaddr(varinfo *set,int index);
447 /* element write access */
448 void typevector_store(varinfo *set,int index,int type,typeinfo *info);
449 void typevector_store_retaddr(varinfo *set,int index,typeinfo *info);
450 bool typevector_init_object(varinfo *set,void *ins,classref_or_classinfo initclass,int size);
452 /* vector functions */
453 varinfo *typevector_copy(varinfo *src,int size);
454 void typevector_copy_inplace(varinfo *src,varinfo *dst,int size);
455 typecheck_result typevector_merge(methodinfo *m,varinfo *dst,varinfo *y,int size);
457 /* inquiry functions (read-only) ********************************************/
459 bool typeinfo_is_array(typeinfo *info);
460 bool typeinfo_is_primitive_array(typeinfo *info,int arraytype);
461 bool typeinfo_is_array_of_refs(typeinfo *info);
463 typecheck_result typeinfo_is_assignable(typeinfo *value,typeinfo *dest);
464 typecheck_result typeinfo_is_assignable_to_class(typeinfo *value,classref_or_classinfo dest);
466 /* initialization functions *************************************************/
468 /* RETURN VALUE (bool):
469 * true.............ok,
470 * false............an exception has been thrown.
472 * RETURN VALUE (int):
473 * >= 0.............ok,
474 * -1...............an exception has been thrown.
476 void typeinfo_init_classinfo(typeinfo *info,classinfo *c);
477 bool typeinfo_init_class(typeinfo *info,classref_or_classinfo c);
478 bool typeinfo_init_component(typeinfo *srcarray,typeinfo *dst);
480 bool typeinfo_init_from_typedesc(typedesc *desc,u1 *type,typeinfo *info);
481 bool typeinfos_init_from_methoddesc(methoddesc *desc,u1 *typebuf,
483 int buflen,bool twoword,
484 u1 *returntype,typeinfo *returntypeinfo);
485 bool typedescriptor_init_from_typedesc(typedescriptor *td,
487 bool typeinfo_init_varinfo_from_typedesc(varinfo *var,
489 int typedescriptors_init_from_methoddesc(typedescriptor *td,
491 int buflen,bool twoword,int startindex,
492 typedescriptor *returntype);
493 bool typeinfo_init_varinfos_from_methoddesc(varinfo *vars,
495 int buflen, int startindex,
497 typedescriptor *returntype);
499 void typeinfo_clone(typeinfo *src,typeinfo *dest);
501 /* freeing memory ***********************************************************/
503 void typeinfo_free(typeinfo *info);
505 /* functions for merging types **********************************************/
507 typecheck_result typeinfo_merge(methodinfo *m,typeinfo *dest,typeinfo* y);
509 /* debugging helpers ********************************************************/
511 #ifdef TYPEINFO_DEBUG
515 void typeinfo_test();
516 void typeinfo_print_class(FILE *file,classref_or_classinfo c);
517 void typeinfo_print(FILE *file,typeinfo *info,int indent);
518 void typeinfo_print_short(FILE *file,typeinfo *info);
519 void typeinfo_print_type(FILE *file,int type,typeinfo *info);
520 void typedescriptor_print(FILE *file,typedescriptor *td);
521 void typevector_print(FILE *file,varinfo *vec,int size);
523 #endif /* TYPEINFO_DEBUG */
525 #endif /* _TYPEINFO_H */
529 * These are local overrides for various environment variables in Emacs.
530 * Please do not remove this and leave it at the end of the file, where
531 * Emacs will automagically detect them.
532 * ---------------------------------------------------------------------
535 * indent-tabs-mode: t