1 /* typeinfo.h - type system used by the type checker
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
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 887 2004-01-19 12:14:39Z edwin $
39 /* resolve typedef cycles *****************************************************/
41 typedef struct typeinfo typeinfo;
42 typedef struct typeinfo_mergedlist typeinfo_mergedlist;
43 typedef struct typedescriptor typedescriptor;
44 typedef struct typevector typevector;
45 typedef struct typeinfo_retaddr_set typeinfo_retaddr_set;
47 /* data structures for the type system ****************************************/
49 /* The typeinfo structure stores detailed information on address types.
50 * (stack elements, variables, etc. with type == TYPE_ADR.)
52 * There are two kinds of address types which can are distinguished by
53 * the value of the typeclass field:
55 * 1) typeclass == NULL: returnAddress type
56 * use TYPEINFO_IS_PRIMITIVE to test for this
58 * 2) typeclass != NULL: reference type
59 * use TYPEINFO_IS_REFERENCE to test for this
61 * Note: For non-address types either there is no typeinfo allocated
62 * or the fields of the typeinfo struct contain undefined values!
64 * CAUTION: The typeinfo structure should be considered opaque outside of
65 * typeinfo.[ch]. Please use the macros and functions defined here to
66 * access typeinfo structures!
69 /* At all times *exactly one* of the following conditions is true for
70 * a particular typeinfo struct:
72 * A) typeclass == NULL
74 * This is a returnAddress type. The interpretation of the
75 * elementclass field depends on wether this typeinfo describes
76 * a stack slot or a local variable:
78 * stack slot: elementclass is a pointer to a
79 * typeinfo_retaddr_set which contains a return target for
80 * every vector in the current set of local variable vectors.
81 * local variable: elementclass is the return target (when cast
84 * Use TYPEINFO_IS_PRIMITIVE to check for this.
85 * Use TYPEINFO_RETURNADDRESS to access the pointer in elementclass.
86 * Don't access other fields of the struct.
88 * B) typeclass == pseudo_class_Null
90 * This is the null-reference type. Use TYPEINFO_IS_NULLTYPE to check for this.
91 * Don't access other fields of the struct.
93 * C) typeclass == pseudo_class_New
95 * This is a 'uninitialized object' type. elementclass can be
96 * cast to instruction* and points to the NEW instruction
97 * responsible for creating this type.
99 * Use TYPEINFO_NEWOBJECT_INSTRUCTION to access the pointer in
101 * Don't access other fields of the struct.
103 * D) typeclass == pseudo_class_Arraystub
105 * See global.h for a describes of pseudo_class_Arraystub.
106 * Otherwise like a normal class reference type.
107 * Don't access other fields of the struct.
109 * E) typeclass is an array class
111 * An array reference.
112 * elementclass...typeclass of the element type
113 * dimension......dimension of the array (>=1)
114 * elementtype....element type (ARRAYTYPE_...)
115 * merged.........mergedlist of the element type
117 * F) typeclass is an interface
119 * An interface reference type.
120 * Don't access other fields of the struct.
122 * G) typeclass is a (non-pseudo-,non-array-)class != java.lang.Object
124 * A class reference type.
125 * All classinfos in u.merged.list (if any) are
126 * subclasses of typeclass (no interfaces or array classes).
127 * Don't access other fields of the struct.
129 * H) typeclass is java.lang.Object
131 * The most general kind of reference type.
132 * In this case u.merged.count and u.merged.list
133 * are valid and may be non-zero.
134 * The classinfos in u.merged.list (if any) may be
135 * classes, interfaces and pseudo classes.
136 * Don't access other fields of the struct.
139 /* The following algorithm is used to determine if the type described
140 * by this typeinfo struct supports the interface X:
142 * 1) If typeclass is X or a subinterface of X the answer is "yes".
143 * 2) If typeclass is a (pseudo) class implementing X the answer is "yes".
144 * 3) If typeclass is not an array and u.merged.count>0
145 * and all classes/interfaces in u.merged.list implement X
146 * the answer is "yes".
147 * 4) If none of the above is true the answer is "no".
151 * CAUTION: The typeinfo structure should be considered opaque outside of
152 * typeinfo.[ch]. Please use the macros and functions defined here to
153 * access typeinfo structures!
156 classinfo *typeclass;
157 classinfo *elementclass; /* valid if dimension>0 */ /* various uses! */
158 typeinfo_mergedlist *merged;
160 u1 elementtype; /* valid if dimension>0 */
163 struct typeinfo_mergedlist {
165 classinfo *list[1]; /* variable length! */
168 struct typeinfo_retaddr_set {
169 typeinfo_retaddr_set *alt; /* next alternative in set */
170 void *addr; /* return address */
173 struct typedescriptor {
174 typeinfo info; /* valid if type == TYPE_ADR */
175 u1 type; /* basic type (TYPE_INT, ...) */
178 /* typevectors are used to store the types of local variables */
181 typevector *alt; /* next alternative in typevector set */
182 int k; /* for lining up with the stack set */
183 typedescriptor td[1]; /* variable length! */
186 /****************************************************************************/
188 /****************************************************************************/
190 /* NOTE: The TYPEINFO macros take typeinfo *structs*, not pointers as
191 * arguments. You have to dereference any pointers.
194 /* typevectors **************************************************************/
196 #define TYPEVECTOR_SIZE(size) \
197 ((sizeof(typevector) - sizeof(typedescriptor)) \
198 + (size)*sizeof(typedescriptor))
200 #define DNEW_TYPEVECTOR(size) \
201 ((typevector*)dump_alloc(TYPEVECTOR_SIZE(size)))
203 #define DMNEW_TYPEVECTOR(num,size) \
204 ((void*)dump_alloc((num) * TYPEVECTOR_SIZE(size)))
206 #define MGET_TYPEVECTOR(array,index,size) \
207 ((typevector*) (((u1*)(array)) + TYPEVECTOR_SIZE(size) * (index)))
209 #define COPY_TYPEVECTORSET(src,dst,size) \
210 do {memcpy(dst,src,TYPEVECTOR_SIZE(size)); \
213 (dst)->alt = typevectorset_copy((src)->alt,1,size); \
216 /* internally used macros ***************************************************/
218 /* internal, don't use this explicitly! */
219 #define TYPEINFO_ALLOCMERGED(mergedlist,count) \
220 do {(mergedlist) = (typeinfo_mergedlist*)dump_alloc( \
221 sizeof(typeinfo_mergedlist) \
222 + ((count)-1)*sizeof(classinfo*));} while(0)
224 /* internal, don't use this explicitly! */
225 #define TYPEINFO_FREEMERGED(mergedlist)
227 /* internal, don't use this explicitly! */
228 #define TYPEINFO_FREEMERGED_IF_ANY(mergedlist)
230 /* macros for type queries **************************************************/
232 #define TYPEINFO_IS_PRIMITIVE(info) \
233 ((info).typeclass == NULL)
235 #define TYPEINFO_IS_REFERENCE(info) \
236 ((info).typeclass != NULL)
238 #define TYPEINFO_IS_NULLTYPE(info) \
239 ((info).typeclass == pseudo_class_Null)
241 #define TYPEINFO_IS_NEWOBJECT(info) \
242 ((info).typeclass == pseudo_class_New)
244 /* only use this if TYPEINFO_IS_PRIMITIVE returned true! */
245 #define TYPEINFO_RETURNADDRESS(info) \
246 ((void *)(info).elementclass)
248 /* only use this if TYPEINFO_IS_NEWOBJECT returned true! */
249 #define TYPEINFO_NEWOBJECT_INSTRUCTION(info) \
250 ((void *)(info).elementclass)
252 /* macros for array type queries ********************************************/
254 #define TYPEINFO_IS_ARRAY(info) \
255 ( TYPEINFO_IS_REFERENCE(info) \
256 && ((info).dimension != 0) )
258 #define TYPEINFO_IS_SIMPLE_ARRAY(info) \
259 ( ((info).dimension == 1) )
261 #define TYPEINFO_IS_ARRAY_ARRAY(info) \
262 ( ((info).dimension >= 2) )
264 #define TYPEINFO_IS_PRIMITIVE_ARRAY(info,arraytype) \
265 ( TYPEINFO_IS_SIMPLE_ARRAY(info) \
266 && ((info).elementtype == (arraytype)) )
268 #define TYPEINFO_IS_OBJECT_ARRAY(info) \
269 ( TYPEINFO_IS_SIMPLE_ARRAY(info) \
270 && ((info).elementclass != NULL) )
272 /* assumes that info describes an array type */
273 #define TYPEINFO_IS_ARRAY_OF_REFS_NOCHECK(info) \
274 ( ((info).elementclass != NULL) \
275 || ((info).dimension >= 2) )
277 #define TYPEINFO_IS_ARRAY_OF_REFS(info) \
278 ( TYPEINFO_IS_ARRAY(info) \
279 && TYPEINFO_IS_ARRAY_OF_REFS_NOCHECK(info) )
281 #define TYPE_IS_RETURNADDRESS(type,info) \
282 ( ((type)==TYPE_ADDRESS) \
283 && TYPEINFO_IS_PRIMITIVE(info) )
285 #define TYPE_IS_REFERENCE(type,info) \
286 ( ((type)==TYPE_ADDRESS) \
287 && !TYPEINFO_IS_PRIMITIVE(info) )
289 #define TYPEDESC_IS_RETURNADDRESS(td) \
290 TYPE_IS_RETURNADDRESS((td).type,(td).info)
292 #define TYPEDESC_IS_REFERENCE(td) \
293 TYPE_IS_REFERENCE((td).type,(td).info)
295 /* queries allowing the null type ********************************************/
297 #define TYPEINFO_MAYBE_ARRAY(info) \
298 (TYPEINFO_IS_ARRAY(info) || TYPEINFO_IS_NULLTYPE(info))
300 #define TYPEINFO_MAYBE_PRIMITIVE_ARRAY(info,at) \
301 (TYPEINFO_IS_PRIMITIVE_ARRAY(info,at) || TYPEINFO_IS_NULLTYPE(info))
303 #define TYPEINFO_MAYBE_ARRAY_OF_REFS(info) \
304 (TYPEINFO_IS_ARRAY_OF_REFS(info) || TYPEINFO_IS_NULLTYPE(info))
306 /* macros for initializing typeinfo structures ******************************/
308 #define TYPEINFO_INIT_PRIMITIVE(info) \
309 do {(info).typeclass = NULL; \
310 (info).elementclass = NULL; \
311 (info).merged = NULL; \
312 (info).dimension = 0; \
313 (info).elementtype = 0;} while(0)
315 #define TYPEINFO_INIT_RETURNADDRESS(info,adr) \
316 do {(info).typeclass = NULL; \
317 (info).elementclass = (classinfo*) (adr); \
318 (info).merged = NULL; \
319 (info).dimension = 0; \
320 (info).elementtype = 0;} while(0)
322 #define TYPEINFO_INIT_NON_ARRAY_CLASSINFO(info,cinfo) \
323 do {(info).typeclass = (cinfo); \
324 (info).elementclass = NULL; \
325 (info).merged = NULL; \
326 (info).dimension = 0; \
327 (info).elementtype = 0;} while(0)
329 #define TYPEINFO_INIT_NULLTYPE(info) \
330 TYPEINFO_INIT_CLASSINFO(info,pseudo_class_Null)
332 #define TYPEINFO_INIT_NEWOBJECT(info,instr) \
333 do {(info).typeclass = pseudo_class_New; \
334 (info).elementclass = (classinfo*) (instr);\
335 (info).merged = NULL; \
336 (info).dimension = 0; \
337 (info).elementtype = 0;} while(0)
339 #define TYPEINFO_INIT_PRIMITIVE_ARRAY(info,arraytype) \
340 TYPEINFO_INIT_CLASSINFO(info,primitivetype_table[arraytype].arrayclass);
342 #define TYPEINFO_INIT_CLASSINFO(info,cls) \
343 do {if (((info).typeclass = (cls))->vftbl->arraydesc) { \
344 if ((cls)->vftbl->arraydesc->elementvftbl) \
345 (info).elementclass = (cls)->vftbl->arraydesc->elementvftbl->class; \
347 (info).elementclass = NULL; \
348 (info).dimension = (cls)->vftbl->arraydesc->dimension; \
349 (info).elementtype = (cls)->vftbl->arraydesc->elementtype; \
352 (info).elementclass = NULL; \
353 (info).dimension = 0; \
354 (info).elementtype = 0; \
356 (info).merged = NULL;} while(0)
358 #define TYPEINFO_INIT_FROM_FIELDINFO(info,fi) \
359 typeinfo_init_from_descriptor(&(info), \
360 (fi)->descriptor->text,utf_end((fi)->descriptor));
362 /* macros for copying types (destinition is not checked or freed) ***********/
364 /* TYPEINFO_COPY makes a shallow copy, the merged pointer is simply copied. */
365 #define TYPEINFO_COPY(src,dst) \
366 do {(dst) = (src);} while(0)
368 /* TYPEINFO_CLONE makes a deep copy, the merged list (if any) is duplicated
369 * into a newly allocated array.
371 #define TYPEINFO_CLONE(src,dst) \
373 if ((dst).merged) typeinfo_clone(&(src),&(dst));} while(0)
375 /****************************************************************************/
377 /****************************************************************************/
379 /* typevector functions *****************************************************/
381 /* element read-only access */
382 bool typevectorset_checktype(typevector *set,int index,int type);
383 bool typevectorset_checkreference(typevector *set,int index);
384 bool typevectorset_checkretaddr(typevector *set,int index);
385 int typevectorset_copymergedtype(typevector *set,int index,typeinfo *dst);
386 typeinfo *typevectorset_mergedtypeinfo(typevector *set,int index,typeinfo *temp);
387 int typevectorset_mergedtype(typevector *set,int index,typeinfo *temp,typeinfo **result);
389 /* element write access */
390 void typevectorset_store(typevector *set,int index,int type,typeinfo *info);
391 void typevectorset_store_retaddr(typevector *set,int index,typeinfo *info);
392 void typevectorset_store_twoword(typevector *set,int index,int type);
393 void typevectorset_init_object(typevector *set,void *ins,classinfo *initclass,int size);
395 /* vector functions */
396 bool typevector_separable_from(typevector *a,typevector *b,int size);
397 bool typevector_merge(typevector *dst,typevector *y,int size);
399 /* vector set functions */
400 typevector *typevectorset_copy(typevector *src,int k,int size);
401 bool typevectorset_separable_with(typevector *set,typevector *add,int size);
402 bool typevectorset_collapse(typevector *dst,int size);
403 void typevectorset_add(typevector *dst,typevector *v,int size);
404 typevector *typevectorset_select(typevector **set,int retindex,void *retaddr);
406 /* inquiry functions (read-only) ********************************************/
408 bool typeinfo_is_array(typeinfo *info);
409 bool typeinfo_is_primitive_array(typeinfo *info,int arraytype);
410 bool typeinfo_is_array_of_refs(typeinfo *info);
412 bool typeinfo_implements_interface(typeinfo *info,classinfo *interf);
413 bool typeinfo_is_assignable(typeinfo *value,typeinfo *dest);
414 bool typeinfo_is_assignable_to_classinfo(typeinfo *value,classinfo *dest);
416 /* initialization functions *************************************************/
418 void typeinfo_init_from_descriptor(typeinfo *info,char *utf_ptr,char *end_ptr);
419 void typeinfo_init_component(typeinfo *srcarray,typeinfo *dst);
421 int typeinfo_count_method_args(utf *d,bool twoword); /* this not included */
422 void typeinfo_init_from_method_args(utf *desc,u1 *typebuf,
424 int buflen,bool twoword,
425 int *returntype,typeinfo *returntypeinfo);
426 int typedescriptors_init_from_method_args(typedescriptor *td,
428 int buflen,bool twoword,
429 typedescriptor *returntype);
431 void typeinfo_clone(typeinfo *src,typeinfo *dest);
433 /* functions for the type system ********************************************/
435 void typeinfo_free(typeinfo *info);
437 bool typeinfo_merge(typeinfo *dest,typeinfo* y);
439 /* debugging helpers ********************************************************/
441 #ifdef TYPEINFO_DEBUG
445 void typeinfo_test();
446 void typeinfo_init_from_fielddescriptor(typeinfo *info,char *desc);
447 void typeinfo_print(FILE *file,typeinfo *info,int indent);
448 void typeinfo_print_short(FILE *file,typeinfo *info);
449 void typeinfo_print_type(FILE *file,int type,typeinfo *info);
450 void typeinfo_print_stacktype(FILE *file,int type,typeinfo *info);
451 void typedescriptor_print(FILE *file,typedescriptor *td);
452 void typevector_print(FILE *file,typevector *vec,int size);
453 void typevectorset_print(FILE *file,typevector *set,int size);
455 #endif /* TYPEINFO_DEBUG */
457 #endif /* _TYPEINFO_H */
461 * These are local overrides for various environment variables in Emacs.
462 * Please do not remove this and leave it at the end of the file, where
463 * Emacs will automagically detect them.
464 * ---------------------------------------------------------------------
467 * indent-tabs-mode: t