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 4357 2006-01-22 23:33:38Z twisti $
39 #include "vm/global.h"
40 #include "vm/references.h"
43 /* configuration **************************************************************/
46 * TYPECHECK_STATISTICS activates gathering statistical information.
47 * TYPEINFO_DEBUG activates debug checks and debug helpers in typeinfo.c
48 * TYPECHECK_DEBUG activates debug checks in typecheck.c
49 * TYPEINFO_DEBUG_TEST activates the typeinfo test at startup.
50 * TYPECHECK_VERBOSE_IMPORTANT activates important debug messages
51 * TYPECHECK_VERBOSE activates all debug messages
52 * TYPEINFO_VERBOSE activates debug prints in typeinfo.c
54 #ifdef ENABLE_VERIFIER
56 /*#define TYPECHECK_STATISTICS*/
57 #define TYPEINFO_DEBUG
58 /*#define TYPEINFO_VERBOSE*/
59 #define TYPECHECK_DEBUG
60 /*#define TYPEINFO_DEBUG_TEST*/
61 /*#define TYPECHECK_VERBOSE*/
62 /*#define TYPECHECK_VERBOSE_IMPORTANT*/
63 #if defined(TYPECHECK_VERBOSE) || defined(TYPECHECK_VERBOSE_IMPORTANT)
64 #define TYPECHECK_VERBOSE_OPT
69 #ifdef TYPECHECK_VERBOSE_OPT
70 extern bool typecheckverbose;
73 /* resolve typedef cycles *****************************************************/
75 typedef struct typeinfo typeinfo;
76 typedef struct typeinfo_mergedlist typeinfo_mergedlist;
77 typedef struct typedescriptor typedescriptor;
78 typedef struct typevector typevector;
79 typedef struct typeinfo_retaddr_set typeinfo_retaddr_set;
81 /* types **********************************************************************/
83 /* typecheck_result - return type for boolean and tristate functions */
84 /* which may also throw exceptions (typecheck_FAIL). */
86 /* NOTE: Use the enum values, not the uppercase #define macros! */
87 #define TYPECHECK_MAYBE 0x02
88 #define TYPECHECK_FAIL 0x04
91 typecheck_FALSE = false,
92 typecheck_TRUE = true,
93 typecheck_MAYBE = TYPECHECK_MAYBE,
94 typecheck_FAIL = TYPECHECK_FAIL
97 /* check that typecheck_MAYBE is not ambiguous */
98 #if TYPECHECK_MAYBE == true
99 #error "`typecheck_MAYBE` must not be the same as `true`"
101 #if TYPECHECK_MAYBE == false
102 #error "`typecheck_MAYBE` must not be the same as `false`"
105 /* check that typecheck_FAIL is not ambiguous */
106 #if (true & TYPECHECK_FAIL) != 0
107 #error "`true` must not have bit 0x02 set (conflicts with typecheck_FAIL)"
110 /* data structures for the type system ****************************************/
112 /* The typeinfo structure stores detailed information on address types.
113 * (stack elements, variables, etc. with type == TYPE_ADR.)
115 * There are two kinds of address types which can be distinguished by
116 * the value of the typeclass field:
118 * 1) typeclass == NULL: returnAddress type
119 * use TYPEINFO_IS_PRIMITIVE to test for this
121 * 2) typeclass != NULL: reference type
122 * use TYPEINFO_IS_REFERENCE to test for this
124 * Note: For non-address types either there is no typeinfo allocated
125 * or the fields of the typeinfo struct contain undefined values!
126 * DO NOT access the typeinfo for non-address types!
128 * CAUTION: The typeinfo structure should be considered opaque outside of
129 * typeinfo.[ch]. Please use the macros and functions defined here to
130 * access typeinfo structures!
133 /* At all times *exactly one* of the following conditions is true for
134 * a particular typeinfo struct:
136 * A) typeclass == NULL
138 * This is a returnAddress type. The interpretation of the
139 * elementclass field depends on wether this typeinfo describes
140 * a stack slot or a local variable:
142 * stack slot: elementclass is a pointer to a
143 * typeinfo_retaddr_set which contains a return target for
144 * every vector in the current set of local variable vectors.
145 * See typeinfo_retaddr_set and typevector below.
147 * local variable: elementclass is the return target (when cast
150 * Use TYPEINFO_IS_PRIMITIVE to check for this.
151 * Use TYPEINFO_RETURNADDRESS to access the pointer in elementclass.
152 * Don't access other fields of the struct.
154 * B) typeclass == pseudo_class_Null
156 * This is the null-reference type.
157 * Use TYPEINFO_IS_NULLTYPE to check for this.
158 * Don't access other fields of the struct.
160 * C) typeclass == pseudo_class_New
162 * This is an 'uninitialized object' type. elementclass can be
163 * cast to instruction* and points to the NEW instruction
164 * responsible for creating this type.
166 * Use TYPEINFO_NEWOBJECT_INSTRUCTION to access the pointer in
168 * Don't access other fields of the struct.
170 * D) typeclass == pseudo_class_Arraystub
172 * This type is used to represent the result of merging array types
173 * with incompatible component types. An arraystub allows no access
174 * to its components (since their type is undefined), but it allows
175 * operations which act directly on an arbitrary array type (such as
176 * requesting the array size).
178 * NOTE: An array stub does *not* count as an array. It has dimension
181 * Otherwise like a normal class reference type.
182 * Don't access other fields of the struct.
184 * E) typeclass is an array class
186 * An array reference.
187 * elementclass...typeclass of the element type
188 * dimension......dimension of the array (>=1)
189 * elementtype....element type (ARRAYTYPE_...)
190 * merged.........mergedlist of the element type
192 * Use TYPEINFO_IS_ARRAY to check for this case.
194 * The elementclass may be one of the following:
195 * 1) pseudo_class_Arraystub
196 * 2) an unresolved type
197 * 3) a loaded interface
198 * 4) a loaded (non-pseudo-,non-array-)class != (BOOTSTRAP)java.lang.Object
199 * Note: `merged` may be used
200 * 5) (BOOTSTRAP)java.lang.Object
201 * Note: `merged` may be used
203 * For the semantics of the merged field in cases 4) and 5) consult the
204 * corresponding descriptions with `elementclass` replaced by `typeclass`.
206 * F) typeclass is an unresolved type (a symbolic class/interface reference)
208 * The type has not been resolved yet. (Meaning it corresponds to an
209 * unloaded class or interface).
210 * Don't access other fields of the struct.
212 * G) typeclass is a loaded interface
214 * An interface reference type.
215 * Don't access other fields of the struct.
217 * H) typeclass is a loaded (non-pseudo-,non-array-)class != (BOOTSTRAP)java.lang.Object
219 * A loaded class type.
220 * All classref_or_classinfos in u.merged.list (if any) are
221 * loaded subclasses of typeclass (no interfaces, array classes, or
223 * Don't access other fields of the struct.
225 * I) typeclass is (BOOTSTRAP)java.lang.Object
227 * The most general kind of reference type.
228 * In this case u.merged.count and u.merged.list
229 * are valid and may be non-zero.
230 * The classref_or_classinfos in u.merged.list (if any) may be
231 * classes, interfaces, pseudo classes or unresolved types.
232 * Don't access other fields of the struct.
235 /* The following algorithm is used to determine if the type described
236 * by this typeinfo struct supports the interface X: * XXX add MAYBE *
238 * 1) If typeclass is X or a subinterface of X the answer is "yes".
239 * 2) If typeclass is a (pseudo) class implementing X the answer is "yes".
240 * 3) If typeclass is not an array and u.merged.count>0
241 * and all classes/interfaces in u.merged.list implement X
242 * the answer is "yes".
243 * 4) If none of the above is true the answer is "no".
247 * CAUTION: The typeinfo structure should be considered opaque outside of
248 * typeinfo.[ch]. Please use the macros and functions defined here to
249 * access typeinfo structures!
252 classref_or_classinfo typeclass;
253 classref_or_classinfo elementclass; /* valid if dimension>0 */ /* various uses! */
254 typeinfo_mergedlist *merged;
256 u1 elementtype; /* valid if dimension>0 */
259 struct typeinfo_mergedlist {
261 classref_or_classinfo list[1]; /* variable length! */
264 /*-----------------------------------------------------------------------*/
265 /* a typeinfo_retaddr_set stores the set of possible returnAddresses */
266 /* that may be in a particular stack slot at a particular point in the */
269 /* There may be one or more alternative returnAddresses if the */
270 /* instruction can be reached via one or more JSR jumps (among other */
271 /* control-flow paths */
272 /*-----------------------------------------------------------------------*/
274 struct typeinfo_retaddr_set {
275 typeinfo_retaddr_set *alt; /* next alternative in set */
276 void *addr; /* return address */
279 /* a type descriptor stores a basic type and the typeinfo */
280 /* this is used for storing the type of a local variable, and for */
281 /* storing types in the signature of a method */
283 struct typedescriptor {
284 typeinfo info; /* valid if type == TYPE_ADR */
285 u1 type; /* basic type (TYPE_INT, ...) */
288 /*-----------------------------------------------------------------------*/
289 /* typevectors are used to store the types of all local variables */
290 /* at a given point in the program. */
292 /* There may be more than one possible typevector for the local */
293 /* variables at a given instruction if the instruction can be reached */
294 /* via one or more JSR jumps (among other control-flow paths). */
296 /* This is called the set of alternative type vectors at that */
297 /* particular point in the program. */
298 /*-----------------------------------------------------------------------*/
301 typevector *alt; /* next alternative in typevector set */
302 int k; /* for lining up with the stack set */
303 typedescriptor td[1]; /* types of locals, variable length! */
306 /****************************************************************************/
308 /****************************************************************************/
310 /* NOTE: The TYPEINFO macros take typeinfo *structs*, not pointers as
311 * arguments. You have to dereference any pointers.
314 /* typevectors **************************************************************/
316 #define TYPEVECTOR_SIZE(size) \
317 ((sizeof(typevector) - sizeof(typedescriptor)) \
318 + (size)*sizeof(typedescriptor))
320 #define DNEW_TYPEVECTOR(size) \
321 ((typevector*)dump_alloc(TYPEVECTOR_SIZE(size)))
323 #define DMNEW_TYPEVECTOR(num,size) \
324 ((void*)dump_alloc((num) * TYPEVECTOR_SIZE(size)))
326 #define MGET_TYPEVECTOR(array,index,size) \
327 ((typevector*) (((u1*)(array)) + TYPEVECTOR_SIZE(size) * (index)))
329 /* internally used macros ***************************************************/
331 /* internal, don't use this explicitly! */
332 #define TYPEINFO_ALLOCMERGED(mergedlist,count) \
333 do {(mergedlist) = (typeinfo_mergedlist*)dump_alloc( \
334 sizeof(typeinfo_mergedlist) \
335 + ((count)-1)*sizeof(classinfo*));} while(0)
337 /* internal, don't use this explicitly! */
338 #define TYPEINFO_FREEMERGED(mergedlist)
340 /* internal, don't use this explicitly! */
341 #define TYPEINFO_FREEMERGED_IF_ANY(mergedlist)
343 /* macros for type queries **************************************************/
345 #define TYPEINFO_IS_PRIMITIVE(info) \
346 ((info).typeclass.any == NULL)
348 #define TYPEINFO_IS_REFERENCE(info) \
349 ((info).typeclass.any != NULL)
351 #define TYPEINFO_IS_NULLTYPE(info) \
352 ((info).typeclass.cls == pseudo_class_Null)
354 #define TYPEINFO_IS_NEWOBJECT(info) \
355 ((info).typeclass.cls == pseudo_class_New)
357 #define TYPEINFO_IS_JAVA_LANG_CLASS(info) \
358 ((info).typeclass.cls == class_java_lang_Class)
360 /* only use this if TYPEINFO_IS_PRIMITIVE returned true! */
361 #define TYPEINFO_RETURNADDRESS(info) \
362 ((info).elementclass.any)
364 /* only use this if TYPEINFO_IS_NEWOBJECT returned true! */
365 #define TYPEINFO_NEWOBJECT_INSTRUCTION(info) \
366 ((info).elementclass.any)
368 /* only use this if TYPEINFO_IS_JAVA_LANG_CLASS returned true! */
369 #define TYPEINFO_JAVA_LANG_CLASS_CLASSREF(info) \
370 ((info).elementclass.ref)
372 /* macros for array type queries ********************************************/
374 #define TYPEINFO_IS_ARRAY(info) \
375 ( TYPEINFO_IS_REFERENCE(info) \
376 && ((info).dimension != 0) )
378 #define TYPEINFO_IS_SIMPLE_ARRAY(info) \
379 ( ((info).dimension == 1) )
381 #define TYPEINFO_IS_ARRAY_ARRAY(info) \
382 ( ((info).dimension >= 2) )
384 #define TYPEINFO_IS_PRIMITIVE_ARRAY(info,arraytype) \
385 ( TYPEINFO_IS_SIMPLE_ARRAY(info) \
386 && ((info).elementtype == (arraytype)) )
388 #define TYPEINFO_IS_OBJECT_ARRAY(info) \
389 ( TYPEINFO_IS_SIMPLE_ARRAY(info) \
390 && ((info).elementclass.any != NULL) )
392 /* assumes that info describes an array type */
393 #define TYPEINFO_IS_ARRAY_OF_REFS_NOCHECK(info) \
394 ( ((info).elementclass.any != NULL) \
395 || ((info).dimension >= 2) )
397 #define TYPEINFO_IS_ARRAY_OF_REFS(info) \
398 ( TYPEINFO_IS_ARRAY(info) \
399 && TYPEINFO_IS_ARRAY_OF_REFS_NOCHECK(info) )
401 #define TYPE_IS_RETURNADDRESS(type,info) \
402 ( ((type)==TYPE_ADDRESS) \
403 && TYPEINFO_IS_PRIMITIVE(info) )
405 #define TYPE_IS_REFERENCE(type,info) \
406 ( ((type)==TYPE_ADDRESS) \
407 && !TYPEINFO_IS_PRIMITIVE(info) )
409 #define TYPEDESC_IS_RETURNADDRESS(td) \
410 TYPE_IS_RETURNADDRESS((td).type,(td).info)
412 #define TYPEDESC_IS_REFERENCE(td) \
413 TYPE_IS_REFERENCE((td).type,(td).info)
415 /* queries allowing the null type ********************************************/
417 #define TYPEINFO_MAYBE_ARRAY(info) \
418 (TYPEINFO_IS_ARRAY(info) || TYPEINFO_IS_NULLTYPE(info))
420 #define TYPEINFO_MAYBE_PRIMITIVE_ARRAY(info,at) \
421 (TYPEINFO_IS_PRIMITIVE_ARRAY(info,at) || TYPEINFO_IS_NULLTYPE(info))
423 #define TYPEINFO_MAYBE_ARRAY_OF_REFS(info) \
424 (TYPEINFO_IS_ARRAY_OF_REFS(info) || TYPEINFO_IS_NULLTYPE(info))
426 /* macros for initializing typeinfo structures ******************************/
428 #define TYPEINFO_INIT_PRIMITIVE(info) \
429 do {(info).typeclass.any = NULL; \
430 (info).elementclass.any = NULL; \
431 (info).merged = NULL; \
432 (info).dimension = 0; \
433 (info).elementtype = 0;} while(0)
435 #define TYPEINFO_INIT_RETURNADDRESS(info,adr) \
436 do {(info).typeclass.any = NULL; \
437 (info).elementclass.any = (adr); \
438 (info).merged = NULL; \
439 (info).dimension = 0; \
440 (info).elementtype = 0;} while(0)
442 #define TYPEINFO_INIT_NON_ARRAY_CLASSINFO(info,cinfo) \
443 do {(info).typeclass.cls = (cinfo); \
444 (info).elementclass.any = NULL; \
445 (info).merged = NULL; \
446 (info).dimension = 0; \
447 (info).elementtype = 0;} while(0)
449 #define TYPEINFO_INIT_JAVA_LANG_CLASS(info,cr) \
450 do {(info).typeclass.any = class_java_lang_Class; \
451 (info).elementclass.ref = (cr); \
452 (info).merged = NULL; \
453 (info).dimension = 0; \
454 (info).elementtype = 0;} while(0)
456 #define TYPEINFO_INIT_NULLTYPE(info) \
457 TYPEINFO_INIT_NON_ARRAY_CLASSINFO(info,pseudo_class_Null)
459 #define TYPEINFO_INIT_NEWOBJECT(info,instr) \
460 do {(info).typeclass.cls = pseudo_class_New; \
461 (info).elementclass.any = (instr); \
462 (info).merged = NULL; \
463 (info).dimension = 0; \
464 (info).elementtype = 0;} while(0)
466 #define TYPEINFO_INIT_PRIMITIVE_ARRAY(info,arraytype) \
467 typeinfo_init_classinfo(&(info),primitivetype_table[arraytype].arrayclass);
469 /* macros for copying types (destinition is not checked or freed) ***********/
471 /* TYPEINFO_COPY makes a shallow copy, the merged pointer is simply copied. */
472 #define TYPEINFO_COPY(src,dst) \
473 do {(dst) = (src);} while(0)
475 /* TYPEINFO_CLONE makes a deep copy, the merged list (if any) is duplicated
476 * into a newly allocated array.
478 #define TYPEINFO_CLONE(src,dst) \
480 if ((dst).merged) typeinfo_clone(&(src),&(dst));} while(0)
482 /****************************************************************************/
484 /****************************************************************************/
486 /* typevector functions *****************************************************/
488 /* element read-only access */
489 bool typevectorset_checktype(typevector *set,int index,int type);
490 bool typevectorset_checkreference(typevector *set,int index);
491 bool typevectorset_checkretaddr(typevector *set,int index);
492 int typevectorset_copymergedtype(methodinfo *m,typevector *set,int index,typeinfo *dst);
493 int typevectorset_mergedtype(methodinfo *m,typevector *set,int index,typeinfo *temp,typeinfo **result);
495 /* element write access */
496 void typevectorset_store(typevector *set,int index,int type,typeinfo *info);
497 void typevectorset_store_retaddr(typevector *set,int index,typeinfo *info);
498 void typevectorset_store_twoword(typevector *set,int index,int type);
499 bool typevectorset_init_object(typevector *set,void *ins,classref_or_classinfo initclass,int size);
501 /* vector functions */
502 bool typevector_separable_from(typevector *a,typevector *b,int size);
503 typecheck_result typevector_merge(methodinfo *m,typevector *dst,typevector *y,int size);
505 /* vector set functions */
506 typevector *typevectorset_copy(typevector *src,int k,int size);
507 void typevectorset_copy_inplace(typevector *src,typevector *dst,int size);
508 bool typevectorset_separable_with(typevector *set,typevector *add,int size);
509 typecheck_result typevectorset_collapse(methodinfo *m,typevector *dst,int size);
510 void typevectorset_add(typevector *dst,typevector *v,int size);
511 typevector *typevectorset_select(typevector **set,int retindex,void *retaddr);
513 /* inquiry functions (read-only) ********************************************/
515 bool typeinfo_is_array(typeinfo *info);
516 bool typeinfo_is_primitive_array(typeinfo *info,int arraytype);
517 bool typeinfo_is_array_of_refs(typeinfo *info);
519 typecheck_result typeinfo_is_assignable(typeinfo *value,typeinfo *dest);
520 typecheck_result typeinfo_is_assignable_to_class(typeinfo *value,classref_or_classinfo dest);
522 /* initialization functions *************************************************/
524 /* RETURN VALUE (bool):
525 * true.............ok,
526 * false............an exception has been thrown.
528 * RETURN VALUE (int):
529 * >= 0.............ok,
530 * -1...............an exception has been thrown.
532 void typeinfo_init_classinfo(typeinfo *info,classinfo *c);
533 bool typeinfo_init_class(typeinfo *info,classref_or_classinfo c);
534 bool typeinfo_init_component(typeinfo *srcarray,typeinfo *dst);
536 bool typeinfo_init_from_typedesc(typedesc *desc,u1 *type,typeinfo *info);
537 bool typeinfos_init_from_methoddesc(methoddesc *desc,u1 *typebuf,
539 int buflen,bool twoword,
540 u1 *returntype,typeinfo *returntypeinfo);
541 bool typedescriptor_init_from_typedesc(typedescriptor *td,
543 int typedescriptors_init_from_methoddesc(typedescriptor *td,
545 int buflen,bool twoword,int startindex,
546 typedescriptor *returntype);
548 void typeinfo_clone(typeinfo *src,typeinfo *dest);
550 /* freeing memory ***********************************************************/
552 void typeinfo_free(typeinfo *info);
554 /* functions for merging types **********************************************/
556 typecheck_result typeinfo_merge(methodinfo *m,typeinfo *dest,typeinfo* y);
558 /* debugging helpers ********************************************************/
560 #ifdef TYPEINFO_DEBUG
564 void typeinfo_test();
565 void typeinfo_print_class(FILE *file,classref_or_classinfo c);
566 void typeinfo_print(FILE *file,typeinfo *info,int indent);
567 void typeinfo_print_short(FILE *file,typeinfo *info);
568 void typeinfo_print_type(FILE *file,int type,typeinfo *info);
569 void typeinfo_print_stacktype(FILE *file,int type,typeinfo *info);
570 void typedescriptor_print(FILE *file,typedescriptor *td);
571 void typevector_print(FILE *file,typevector *vec,int size);
572 void typevectorset_print(FILE *file,typevector *set,int size);
574 #endif /* TYPEINFO_DEBUG */
576 #endif /* _TYPEINFO_H */
580 * These are local overrides for various environment variables in Emacs.
581 * Please do not remove this and leave it at the end of the file, where
582 * Emacs will automagically detect them.
583 * ---------------------------------------------------------------------
586 * indent-tabs-mode: t