1 /* typeinfo.h - type system used by the type checker
3 Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
4 R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
5 C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
6 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., 59 Temple Place - Suite 330, Boston, MA
25 Contact: cacao@complang.tuwien.ac.at
27 Authors: Edwin Steiner
29 $Id: typeinfo.h 2749 2005-06-20 15:04:31Z edwin $
36 #include "vm/global.h"
37 #include "vm/references.h"
39 /* configuration **************************************************************/
42 * TYPECHECK_STATISTICS activates gathering statistical information.
43 * TYPEINFO_DEBUG activates debug checks and debug helpers in typeinfo.c
44 * TYPECHECK_DEBUG activates debug checks in typecheck.c
45 * TYPEINFO_DEBUG_TEST activates the typeinfo test at startup.
46 * TYPECHECK_VERBOSE_IMPORTANT activates important debug messages
47 * TYPECHECK_VERBOSE activates all debug messages
48 * TYPEINFO_VERBOSE activates debug prints in typeinfo.c
50 #ifdef CACAO_TYPECHECK
51 /*#define TYPECHECK_STATISTICS*/
52 #define TYPEINFO_DEBUG
53 /*#define TYPEINFO_VERBOSE*/
54 #define TYPECHECK_DEBUG
55 /*#define TYPEINFO_DEBUG_TEST*/
56 /*#define TYPECHECK_VERBOSE*/
57 /*#define TYPECHECK_VERBOSE_IMPORTANT*/
58 #if defined(TYPECHECK_VERBOSE) || defined(TYPECHECK_VERBOSE_IMPORTANT)
59 #define TYPECHECK_VERBOSE_OPT
63 #ifdef TYPECHECK_VERBOSE_OPT
64 extern bool typecheckverbose;
67 /* resolve typedef cycles *****************************************************/
69 typedef struct typeinfo typeinfo;
70 typedef struct typeinfo_mergedlist typeinfo_mergedlist;
71 typedef struct typedescriptor typedescriptor;
72 typedef struct typevector typevector;
73 typedef struct typeinfo_retaddr_set typeinfo_retaddr_set;
75 /* constants ******************************************************************/
80 #error "`MAYBE` must not be the same as `true`"
83 #error "`MAYBE` must not be the same as `false`"
86 /* types **********************************************************************/
88 /* a tristate_t is one of {true,false,MAYBE} */
89 typedef int tristate_t;
91 /* data structures for the type system ****************************************/
93 /* The typeinfo structure stores detailed information on address types.
94 * (stack elements, variables, etc. with type == TYPE_ADR.)
96 * There are two kinds of address types which can be distinguished by
97 * the value of the typeclass field:
99 * 1) typeclass == NULL: returnAddress type
100 * use TYPEINFO_IS_PRIMITIVE to test for this
102 * 2) typeclass != NULL: reference type
103 * use TYPEINFO_IS_REFERENCE to test for this
105 * Note: For non-address types either there is no typeinfo allocated
106 * or the fields of the typeinfo struct contain undefined values!
107 * DO NOT access the typeinfo for non-address types!
109 * CAUTION: The typeinfo structure should be considered opaque outside of
110 * typeinfo.[ch]. Please use the macros and functions defined here to
111 * access typeinfo structures!
114 /* At all times *exactly one* of the following conditions is true for
115 * a particular typeinfo struct:
117 * A) typeclass == NULL
119 * This is a returnAddress type. The interpretation of the
120 * elementclass field depends on wether this typeinfo describes
121 * a stack slot or a local variable:
123 * stack slot: elementclass is a pointer to a
124 * typeinfo_retaddr_set which contains a return target for
125 * every vector in the current set of local variable vectors.
126 * See typeinfo_retaddr_set and typevector below.
128 * local variable: elementclass is the return target (when cast
131 * Use TYPEINFO_IS_PRIMITIVE to check for this.
132 * Use TYPEINFO_RETURNADDRESS to access the pointer in elementclass.
133 * Don't access other fields of the struct.
135 * B) typeclass == pseudo_class_Null
137 * This is the null-reference type.
138 * Use TYPEINFO_IS_NULLTYPE to check for this.
139 * Don't access other fields of the struct.
141 * C) typeclass == pseudo_class_New
143 * This is an 'uninitialized object' type. elementclass can be
144 * cast to instruction* and points to the NEW instruction
145 * responsible for creating this type.
147 * Use TYPEINFO_NEWOBJECT_INSTRUCTION to access the pointer in
149 * Don't access other fields of the struct.
151 * D) typeclass == pseudo_class_Arraystub
153 * This type is used to represent the result of merging array types
154 * with incompatible component types. An arraystub allows no access
155 * to its components (since their type is undefined), but it allows
156 * operations which act directly on an arbitrary array type (such as
157 * requesting the array size).
159 * NOTE: An array stub does *not* count as an array. It has dimension
162 * Otherwise like a normal class reference type.
163 * Don't access other fields of the struct.
165 * E) typeclass is an array class
167 * An array reference.
168 * elementclass...typeclass of the element type
169 * dimension......dimension of the array (>=1)
170 * elementtype....element type (ARRAYTYPE_...)
171 * merged.........mergedlist of the element type
173 * Use TYPEINFO_IS_ARRAY to check for this case.
175 * The elementclass may be one of the following:
176 * 1) pseudo_class_Arraystub
177 * 2) an unresolved type
178 * 3) a loaded interface
179 * 4) a loaded (non-pseudo-,non-array-)class != (BOOTSTRAP)java.lang.Object
180 * Note: `merged` may be used
181 * 5) (BOOTSTRAP)java.lang.Object
182 * Note: `merged` may be used
184 * For the semantics of the merged field in cases 4) and 5) consult the
185 * corresponding descriptions with `elementclass` replaced by `typeclass`.
187 * F) typeclass is an unresolved type (a symbolic class/interface reference)
189 * The type has not been resolved yet. (Meaning it corresponds to an
190 * unloaded class or interface).
191 * Don't access other fields of the struct.
193 * G) typeclass is a loaded interface
195 * An interface reference type.
196 * Don't access other fields of the struct.
198 * H) typeclass is a loaded (non-pseudo-,non-array-)class != (BOOTSTRAP)java.lang.Object
200 * A loaded class type.
201 * All classref_or_classinfos in u.merged.list (if any) are
202 * loaded subclasses of typeclass (no interfaces, array classes, or
204 * Don't access other fields of the struct.
206 * I) typeclass is (BOOTSTRAP)java.lang.Object
208 * The most general kind of reference type.
209 * In this case u.merged.count and u.merged.list
210 * are valid and may be non-zero.
211 * The classref_or_classinfos in u.merged.list (if any) may be
212 * classes, interfaces, pseudo classes or unresolved types.
213 * Don't access other fields of the struct.
216 /* The following algorithm is used to determine if the type described
217 * by this typeinfo struct supports the interface X: * XXX add MAYBE *
219 * 1) If typeclass is X or a subinterface of X the answer is "yes".
220 * 2) If typeclass is a (pseudo) class implementing X the answer is "yes".
221 * 3) If typeclass is not an array and u.merged.count>0
222 * and all classes/interfaces in u.merged.list implement X
223 * the answer is "yes".
224 * 4) If none of the above is true the answer is "no".
228 * CAUTION: The typeinfo structure should be considered opaque outside of
229 * typeinfo.[ch]. Please use the macros and functions defined here to
230 * access typeinfo structures!
233 classref_or_classinfo typeclass;
234 classref_or_classinfo elementclass; /* valid if dimension>0 */ /* various uses! */
235 typeinfo_mergedlist *merged;
237 u1 elementtype; /* valid if dimension>0 */
240 struct typeinfo_mergedlist {
242 classref_or_classinfo list[1]; /* variable length! */
245 /*-----------------------------------------------------------------------*/
246 /* a typeinfo_retaddr_set stores the set of possible returnAddresses */
247 /* that may be in a particular stack slot at a particular point in the */
250 /* There may be one or more alternative returnAddresses if the */
251 /* instruction can be reached via one or more JSR jumps (among other */
252 /* control-flow paths */
253 /*-----------------------------------------------------------------------*/
255 struct typeinfo_retaddr_set {
256 typeinfo_retaddr_set *alt; /* next alternative in set */
257 void *addr; /* return address */
260 /* a type descriptor stores a basic type and the typeinfo */
261 /* this is used for storing the type of a local variable, and for */
262 /* storing types in the signature of a method */
264 struct typedescriptor {
265 typeinfo info; /* valid if type == TYPE_ADR */
266 u1 type; /* basic type (TYPE_INT, ...) */
269 /*-----------------------------------------------------------------------*/
270 /* typevectors are used to store the types of all local variables */
271 /* at a given point in the program. */
273 /* There may be more than one possible typevector for the local */
274 /* variables at a given instruction if the instruction can be reached */
275 /* via one or more JSR jumps (among other control-flow paths). */
277 /* This is called the set of alternative type vectors at that */
278 /* particular point in the program. */
279 /*-----------------------------------------------------------------------*/
282 typevector *alt; /* next alternative in typevector set */
283 int k; /* for lining up with the stack set */
284 typedescriptor td[1]; /* types of locals, variable length! */
287 /****************************************************************************/
289 /****************************************************************************/
291 /* NOTE: The TYPEINFO macros take typeinfo *structs*, not pointers as
292 * arguments. You have to dereference any pointers.
295 /* typevectors **************************************************************/
297 #define TYPEVECTOR_SIZE(size) \
298 ((sizeof(typevector) - sizeof(typedescriptor)) \
299 + (size)*sizeof(typedescriptor))
301 #define DNEW_TYPEVECTOR(size) \
302 ((typevector*)dump_alloc(TYPEVECTOR_SIZE(size)))
304 #define DMNEW_TYPEVECTOR(num,size) \
305 ((void*)dump_alloc((num) * TYPEVECTOR_SIZE(size)))
307 #define MGET_TYPEVECTOR(array,index,size) \
308 ((typevector*) (((u1*)(array)) + TYPEVECTOR_SIZE(size) * (index)))
310 #define COPY_TYPEVECTORSET(src,dst,size) \
311 do {memcpy(dst,src,TYPEVECTOR_SIZE(size)); \
314 (dst)->alt = typevectorset_copy((src)->alt,1,size); \
317 /* internally used macros ***************************************************/
319 /* internal, don't use this explicitly! */
320 #define TYPEINFO_ALLOCMERGED(mergedlist,count) \
321 do {(mergedlist) = (typeinfo_mergedlist*)dump_alloc( \
322 sizeof(typeinfo_mergedlist) \
323 + ((count)-1)*sizeof(classinfo*));} while(0)
325 /* internal, don't use this explicitly! */
326 #define TYPEINFO_FREEMERGED(mergedlist)
328 /* internal, don't use this explicitly! */
329 #define TYPEINFO_FREEMERGED_IF_ANY(mergedlist)
331 /* macros for type queries **************************************************/
333 #define TYPEINFO_IS_PRIMITIVE(info) \
334 ((info).typeclass.any == NULL)
336 #define TYPEINFO_IS_REFERENCE(info) \
337 ((info).typeclass.any != NULL)
339 #define TYPEINFO_IS_NULLTYPE(info) \
340 ((info).typeclass.cls == pseudo_class_Null)
342 #define TYPEINFO_IS_NEWOBJECT(info) \
343 ((info).typeclass.cls == pseudo_class_New)
345 /* only use this if TYPEINFO_IS_PRIMITIVE returned true! */
346 #define TYPEINFO_RETURNADDRESS(info) \
347 ((void *)(info).elementclass.any)
349 /* only use this if TYPEINFO_IS_NEWOBJECT returned true! */
350 #define TYPEINFO_NEWOBJECT_INSTRUCTION(info) \
351 ((void *)(info).elementclass.any)
353 /* macros for array type queries ********************************************/
355 #define TYPEINFO_IS_ARRAY(info) \
356 ( TYPEINFO_IS_REFERENCE(info) \
357 && ((info).dimension != 0) )
359 #define TYPEINFO_IS_SIMPLE_ARRAY(info) \
360 ( ((info).dimension == 1) )
362 #define TYPEINFO_IS_ARRAY_ARRAY(info) \
363 ( ((info).dimension >= 2) )
365 #define TYPEINFO_IS_PRIMITIVE_ARRAY(info,arraytype) \
366 ( TYPEINFO_IS_SIMPLE_ARRAY(info) \
367 && ((info).elementtype == (arraytype)) )
369 #define TYPEINFO_IS_OBJECT_ARRAY(info) \
370 ( TYPEINFO_IS_SIMPLE_ARRAY(info) \
371 && ((info).elementclass.any != NULL) )
373 /* assumes that info describes an array type */
374 #define TYPEINFO_IS_ARRAY_OF_REFS_NOCHECK(info) \
375 ( ((info).elementclass.any != NULL) \
376 || ((info).dimension >= 2) )
378 #define TYPEINFO_IS_ARRAY_OF_REFS(info) \
379 ( TYPEINFO_IS_ARRAY(info) \
380 && TYPEINFO_IS_ARRAY_OF_REFS_NOCHECK(info) )
382 #define TYPE_IS_RETURNADDRESS(type,info) \
383 ( ((type)==TYPE_ADDRESS) \
384 && TYPEINFO_IS_PRIMITIVE(info) )
386 #define TYPE_IS_REFERENCE(type,info) \
387 ( ((type)==TYPE_ADDRESS) \
388 && !TYPEINFO_IS_PRIMITIVE(info) )
390 #define TYPEDESC_IS_RETURNADDRESS(td) \
391 TYPE_IS_RETURNADDRESS((td).type,(td).info)
393 #define TYPEDESC_IS_REFERENCE(td) \
394 TYPE_IS_REFERENCE((td).type,(td).info)
396 /* queries allowing the null type ********************************************/
398 #define TYPEINFO_MAYBE_ARRAY(info) \
399 (TYPEINFO_IS_ARRAY(info) || TYPEINFO_IS_NULLTYPE(info))
401 #define TYPEINFO_MAYBE_PRIMITIVE_ARRAY(info,at) \
402 (TYPEINFO_IS_PRIMITIVE_ARRAY(info,at) || TYPEINFO_IS_NULLTYPE(info))
404 #define TYPEINFO_MAYBE_ARRAY_OF_REFS(info) \
405 (TYPEINFO_IS_ARRAY_OF_REFS(info) || TYPEINFO_IS_NULLTYPE(info))
407 /* macros for initializing typeinfo structures ******************************/
409 #define TYPEINFO_INIT_PRIMITIVE(info) \
410 do {(info).typeclass.any = NULL; \
411 (info).elementclass.any = NULL; \
412 (info).merged = NULL; \
413 (info).dimension = 0; \
414 (info).elementtype = 0;} while(0)
416 #define TYPEINFO_INIT_RETURNADDRESS(info,adr) \
417 do {(info).typeclass.any = NULL; \
418 (info).elementclass.any = (adr); \
419 (info).merged = NULL; \
420 (info).dimension = 0; \
421 (info).elementtype = 0;} while(0)
423 #define TYPEINFO_INIT_NON_ARRAY_CLASSINFO(info,cinfo) \
424 do {(info).typeclass.cls = (cinfo); \
425 (info).elementclass.any = NULL; \
426 (info).merged = NULL; \
427 (info).dimension = 0; \
428 (info).elementtype = 0;} while(0)
430 #define TYPEINFO_INIT_NULLTYPE(info) \
431 TYPEINFO_INIT_NON_ARRAY_CLASSINFO(info,pseudo_class_Null)
433 #define TYPEINFO_INIT_NEWOBJECT(info,instr) \
434 do {(info).typeclass.cls = pseudo_class_New; \
435 (info).elementclass.any = (instr); \
436 (info).merged = NULL; \
437 (info).dimension = 0; \
438 (info).elementtype = 0;} while(0)
440 #define TYPEINFO_INIT_PRIMITIVE_ARRAY(info,arraytype) \
441 TYPEINFO_INIT_CLASSINFO(info,primitivetype_table[arraytype].arrayclass);
443 #define TYPEINFO_INIT_CLASSINFO(info,c) \
444 do {if (((info).typeclass.cls = (c))->vftbl->arraydesc) { \
445 if ((c)->vftbl->arraydesc->elementvftbl) \
446 (info).elementclass.cls = (c)->vftbl->arraydesc->elementvftbl->class; \
448 (info).elementclass.any = NULL; \
449 (info).dimension = (c)->vftbl->arraydesc->dimension; \
450 (info).elementtype = (c)->vftbl->arraydesc->elementtype;\
453 (info).elementclass.any = NULL; \
454 (info).dimension = 0; \
455 (info).elementtype = 0; \
457 (info).merged = NULL;} while(0)
459 #define TYPEINFO_INIT_CLASSREF(info,c) \
460 typeinfo_init_class(&(info),CLASSREF_OR_CLASSINFO(c))
462 #define TYPEINFO_INIT_CLASSREF_OR_CLASSINFO(info,c) \
463 typeinfo_init_class(&(info),c)
465 /* macros for copying types (destinition is not checked or freed) ***********/
467 /* TYPEINFO_COPY makes a shallow copy, the merged pointer is simply copied. */
468 #define TYPEINFO_COPY(src,dst) \
469 do {(dst) = (src);} while(0)
471 /* TYPEINFO_CLONE makes a deep copy, the merged list (if any) is duplicated
472 * into a newly allocated array.
474 #define TYPEINFO_CLONE(src,dst) \
476 if ((dst).merged) typeinfo_clone(&(src),&(dst));} while(0)
478 /****************************************************************************/
480 /****************************************************************************/
482 /* typevector functions *****************************************************/
484 /* element read-only access */
485 bool typevectorset_checktype(typevector *set,int index,int type);
486 bool typevectorset_checkreference(typevector *set,int index);
487 bool typevectorset_checkretaddr(typevector *set,int index);
488 int typevectorset_copymergedtype(typevector *set,int index,typeinfo *dst);
489 typeinfo *typevectorset_mergedtypeinfo(typevector *set,int index,typeinfo *temp);
490 int typevectorset_mergedtype(typevector *set,int index,typeinfo *temp,typeinfo **result);
492 /* element write access */
493 void typevectorset_store(typevector *set,int index,int type,typeinfo *info);
494 void typevectorset_store_retaddr(typevector *set,int index,typeinfo *info);
495 void typevectorset_store_twoword(typevector *set,int index,int type);
496 void typevectorset_init_object(typevector *set,void *ins,classref_or_classinfo initclass,int size);
498 /* vector functions */
499 bool typevector_separable_from(typevector *a,typevector *b,int size);
500 bool typevector_merge(typevector *dst,typevector *y,int size);
502 /* vector set functions */
503 typevector *typevectorset_copy(typevector *src,int k,int size);
504 bool typevectorset_separable_with(typevector *set,typevector *add,int size);
505 bool typevectorset_collapse(typevector *dst,int size);
506 void typevectorset_add(typevector *dst,typevector *v,int size);
507 typevector *typevectorset_select(typevector **set,int retindex,void *retaddr);
509 /* inquiry functions (read-only) ********************************************/
511 bool typeinfo_is_array(typeinfo *info);
512 bool typeinfo_is_primitive_array(typeinfo *info,int arraytype);
513 bool typeinfo_is_array_of_refs(typeinfo *info);
515 tristate_t typeinfo_implements_interface(typeinfo *info,classinfo *interf);
516 tristate_t typeinfo_is_assignable(typeinfo *value,typeinfo *dest);
517 tristate_t typeinfo_is_assignable_to_class(typeinfo *value,classref_or_classinfo dest);
519 /* initialization functions *************************************************/
521 bool typeinfo_init_class(typeinfo *info,classref_or_classinfo c);
522 void typeinfo_init_component(typeinfo *srcarray,typeinfo *dst);
524 void typeinfo_init_from_typedesc(typedesc *desc,u1 *type,typeinfo *info);
525 void typeinfo_init_from_methoddesc(methoddesc *desc,u1 *typebuf,
527 int buflen,bool twoword,
528 u1 *returntype,typeinfo *returntypeinfo);
529 void typedescriptor_init_from_typedesc(typedescriptor *td,
531 int typedescriptors_init_from_methoddesc(typedescriptor *td,
533 int buflen,bool twoword,int startindex,
534 typedescriptor *returntype);
536 void typeinfo_clone(typeinfo *src,typeinfo *dest);
538 /* freeing memory ***********************************************************/
540 void typeinfo_free(typeinfo *info);
542 /* functions for merging types **********************************************/
544 bool typeinfo_merge(typeinfo *dest,typeinfo* y);
546 /* debugging helpers ********************************************************/
548 #ifdef TYPEINFO_DEBUG
552 void typeinfo_test();
553 void typeinfo_print_class(FILE *file,classref_or_classinfo c);
554 void typeinfo_print(FILE *file,typeinfo *info,int indent);
555 void typeinfo_print_short(FILE *file,typeinfo *info);
556 void typeinfo_print_type(FILE *file,int type,typeinfo *info);
557 void typeinfo_print_stacktype(FILE *file,int type,typeinfo *info);
558 void typedescriptor_print(FILE *file,typedescriptor *td);
559 void typevector_print(FILE *file,typevector *vec,int size);
560 void typevectorset_print(FILE *file,typevector *set,int size);
562 #endif /* TYPEINFO_DEBUG */
564 #endif /* _TYPEINFO_H */
568 * These are local overrides for various environment variables in Emacs.
569 * Please do not remove this and leave it at the end of the file, where
570 * Emacs will automagically detect them.
571 * ---------------------------------------------------------------------
574 * indent-tabs-mode: t