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 868 2004-01-10 20:12:10Z 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 /* global variables ***********************************************************/
49 /* XXX move this documentation to global.h */
50 /* The following classinfo pointers are used internally by the type system.
51 * Please do not use them directly, use the TYPEINFO_ macros instead.
55 * pseudo_class_Arraystub
56 * (extends Object implements Cloneable, java.io.Serializable)
58 * If two arrays of incompatible component types are merged,
59 * the resulting reference has no accessible components.
60 * The result does, however, implement the interfaces Cloneable
61 * and java.io.Serializable. This pseudo class is used internally
62 * to represent such results. (They are *not* considered arrays!)
66 * This pseudo class is used internally to represent the
70 /* data structures for the type system ****************************************/
72 /* The typeinfo structure stores detailed information on reference types.
73 * (stack elements, variables, etc. with type == TYPE_ADR.)
74 * XXX: exclude ReturnAddresses?
76 * For primitive types either there is no typeinfo allocated or the
77 * typeclass pointer in the typeinfo struct is NULL.
79 * CAUTION: The typeinfo structure should be considered opaque outside of
80 * typeinfo.[ch]. Please use the macros and functions defined here to
81 * access typeinfo structures!
84 /* At all times *exactly one* of the following conditions is true for
85 * a particular typeinfo struct:
87 * A) typeclass == NULL
89 * In this case the other fields of the structure
92 * B) typeclass == pseudo_class_Null
96 * C) typeclass is an array class
100 * D) typeclass == pseudo_class_Arraystub
104 * E) typeclass is an interface
108 * F) typeclass is a (non-pseudo-)class != java.lang.Object
111 * All classinfos in u.merged.list (if any) are
112 * subclasses of typeclass.
114 * G) typeclass is java.lang.Object
117 * In this case u.merged.count and u.merged.list
118 * are valid and may be non-zero.
119 * The classinfos in u.merged.list (if any) can be
120 * classes, interfaces or pseudo classes.
123 /* The following algorithm is used to determine if the type described
124 * by this typeinfo struct supports the interface X:
126 * 1) If typeclass is X or a subinterface of X the answer is "yes".
127 * 2) If typeclass is a (pseudo) class implementing X the answer is "yes".
128 * 3) XXX If typeclass is not an array and u.merged.count>0
129 * and all classes/interfaces in u.merged.list implement X
130 * the answer is "yes".
131 * 4) If none of the above is true the answer is "no".
135 * CAUTION: The typeinfo structure should be considered opaque outside of
136 * typeinfo.[ch]. Please use the macros and functions defined here to
137 * access typeinfo structures!
140 classinfo *typeclass;
141 classinfo *elementclass; /* valid if dimension>0 */ /* XXX various uses */
142 typeinfo_mergedlist *merged;
144 u1 elementtype; /* valid if dimension>0 */
147 struct typeinfo_mergedlist {
149 classinfo *list[1]; /* variable length! */
152 struct typeinfo_retaddr_set {
153 typeinfo_retaddr_set *alt; /* next alternative in set */
154 void *addr; /* return address */
157 struct typedescriptor {
158 typeinfo info; /* valid if type == TYPE_ADR */
159 u1 type; /* basic type (TYPE_INT, ...) */
162 /* typevectors are used to store the types of local variables */
165 typevector *alt; /* next alternative in typevector set */
166 int k; /* for lining up with the stack set */
167 typedescriptor td[1]; /* variable length! */
170 /****************************************************************************/
172 /****************************************************************************/
174 /* NOTE: The TYPEINFO macros take typeinfo *structs*, not pointers as
175 * arguments. You have to dereference any pointers.
178 /* typevectors **************************************************************/
180 #define TYPEVECTOR_SIZE(size) \
181 ((sizeof(typevector) - sizeof(typedescriptor)) \
182 + (size)*sizeof(typedescriptor))
184 #define DNEW_TYPEVECTOR(size) \
185 ((typevector*)dump_alloc(TYPEVECTOR_SIZE(size)))
187 #define DMNEW_TYPEVECTOR(num,size) \
188 ((void*)dump_alloc((num) * TYPEVECTOR_SIZE(size)))
190 #define MGET_TYPEVECTOR(array,index,size) \
191 ((typevector*) (((u1*)(array)) + TYPEVECTOR_SIZE(size) * (index)))
193 #define COPY_TYPEVECTORSET(src,dst,size) \
194 do {memcpy(dst,src,TYPEVECTOR_SIZE(size)); \
197 (dst)->alt = typevectorset_copy((src)->alt,1,size); \
200 /* internally used macros ***************************************************/
202 /* internal, don't use this explicitly! */
203 #define TYPEINFO_ALLOCMERGED(mergedlist,count) \
204 do {(mergedlist) = (typeinfo_mergedlist*)dump_alloc( \
205 sizeof(typeinfo_mergedlist) \
206 + ((count)-1)*sizeof(classinfo*));} while(0)
208 /* internal, don't use this explicitly! */
209 #define TYPEINFO_FREEMERGED(mergedlist)
211 /* internal, don't use this explicitly! */
212 #define TYPEINFO_FREEMERGED_IF_ANY(mergedlist)
214 /* macros for type queries **************************************************/
216 #define TYPEINFO_IS_PRIMITIVE(info) \
217 ((info).typeclass == NULL)
219 #define TYPEINFO_IS_REFERENCE(info) \
220 ((info).typeclass != NULL)
222 #define TYPEINFO_IS_NULLTYPE(info) \
223 ((info).typeclass == pseudo_class_Null)
225 #define TYPEINFO_IS_NEWOBJECT(info) \
226 ((info).typeclass == pseudo_class_New)
228 /* only use this if TYPEINFO_IS_PRIMITIVE returned true! */
229 #define TYPEINFO_RETURNADDRESS(info) \
230 ((void *)(info).elementclass)
232 /* only use this if TYPEINFO_IS_NEWOBJECT returned true! */
233 #define TYPEINFO_NEWOBJECT_INSTRUCTION(info) \
234 ((void *)(info).elementclass)
236 /* macros for array type queries ********************************************/
238 #define TYPEINFO_IS_ARRAY(info) \
239 ( TYPEINFO_IS_REFERENCE(info) \
240 && ((info).dimension != 0) )
242 #define TYPEINFO_IS_SIMPLE_ARRAY(info) \
243 ( ((info).dimension == 1) )
245 #define TYPEINFO_IS_ARRAY_ARRAY(info) \
246 ( ((info).dimension >= 2) )
248 #define TYPEINFO_IS_PRIMITIVE_ARRAY(info,arraytype) \
249 ( TYPEINFO_IS_SIMPLE_ARRAY(info) \
250 && ((info).elementtype == (arraytype)) )
252 #define TYPEINFO_IS_OBJECT_ARRAY(info) \
253 ( TYPEINFO_IS_SIMPLE_ARRAY(info) \
254 && ((info).elementclass != NULL) )
256 /* assumes that info describes an array type */
257 #define TYPEINFO_IS_ARRAY_OF_REFS_NOCHECK(info) \
258 ( ((info).elementclass != NULL) \
259 || ((info).dimension >= 2) )
261 #define TYPEINFO_IS_ARRAY_OF_REFS(info) \
262 ( TYPEINFO_IS_ARRAY(info) \
263 && TYPEINFO_IS_ARRAY_OF_REFS_NOCHECK(info) )
265 #define TYPE_IS_RETURNADDRESS(type,info) \
266 ( ((type)==TYPE_ADDRESS) \
267 && TYPEINFO_IS_PRIMITIVE(info) )
269 #define TYPE_IS_REFERENCE(type,info) \
270 ( ((type)==TYPE_ADDRESS) \
271 && !TYPEINFO_IS_PRIMITIVE(info) )
273 #define TYPEDESC_IS_RETURNADDRESS(td) \
274 TYPE_IS_RETURNADDRESS((td).type,(td).info)
276 #define TYPEDESC_IS_REFERENCE(td) \
277 TYPE_IS_REFERENCE((td).type,(td).info)
279 /* queries allowing the null type ********************************************/
281 #define TYPEINFO_MAYBE_ARRAY(info) \
282 (TYPEINFO_IS_ARRAY(info) || TYPEINFO_IS_NULLTYPE(info))
284 #define TYPEINFO_MAYBE_PRIMITIVE_ARRAY(info,at) \
285 (TYPEINFO_IS_PRIMITIVE_ARRAY(info,at) || TYPEINFO_IS_NULLTYPE(info))
287 #define TYPEINFO_MAYBE_ARRAY_OF_REFS(info) \
288 (TYPEINFO_IS_ARRAY_OF_REFS(info) || TYPEINFO_IS_NULLTYPE(info))
290 /* macros for initializing typeinfo structures ******************************/
292 #define TYPEINFO_INIT_PRIMITIVE(info) \
293 do {(info).typeclass = NULL; \
294 (info).elementclass = NULL; \
295 (info).merged = NULL; \
296 (info).dimension = 0; \
297 (info).elementtype = 0;} while(0)
299 #define TYPEINFO_INIT_RETURNADDRESS(info,adr) \
300 do {(info).typeclass = NULL; \
301 (info).elementclass = (classinfo*) (adr); \
302 (info).merged = NULL; \
303 (info).dimension = 0; \
304 (info).elementtype = 0;} while(0)
306 #define TYPEINFO_INIT_NON_ARRAY_CLASSINFO(info,cinfo) \
307 do {(info).typeclass = (cinfo); \
308 (info).elementclass = NULL; \
309 (info).merged = NULL; \
310 (info).dimension = 0; \
311 (info).elementtype = 0;} while(0)
313 #define TYPEINFO_INIT_NULLTYPE(info) \
314 TYPEINFO_INIT_CLASSINFO(info,pseudo_class_Null)
316 #define TYPEINFO_INIT_NEWOBJECT(info,instr) \
317 do {(info).typeclass = pseudo_class_New; \
318 (info).elementclass = (classinfo*) (instr);\
319 (info).merged = NULL; \
320 (info).dimension = 0; \
321 (info).elementtype = 0;} while(0)
323 #define TYPEINFO_INIT_PRIMITIVE_ARRAY(info,arraytype) \
324 TYPEINFO_INIT_CLASSINFO(info,primitivetype_table[arraytype].arrayclass);
326 #define TYPEINFO_INIT_CLASSINFO(info,cls) \
327 do {if (((info).typeclass = (cls))->vftbl->arraydesc) { \
328 if ((cls)->vftbl->arraydesc->elementvftbl) \
329 (info).elementclass = (cls)->vftbl->arraydesc->elementvftbl->class; \
331 (info).elementclass = NULL; \
332 (info).dimension = (cls)->vftbl->arraydesc->dimension; \
333 (info).elementtype = (cls)->vftbl->arraydesc->elementtype; \
336 (info).elementclass = NULL; \
337 (info).dimension = 0; \
338 (info).elementtype = 0; \
340 (info).merged = NULL;} while(0)
342 #define TYPEINFO_INIT_FROM_FIELDINFO(info,fi) \
343 typeinfo_init_from_descriptor(&(info), \
344 (fi)->descriptor->text,utf_end((fi)->descriptor));
346 /* macros for writing types (destination must have been initialized) ********/
347 /* XXX delete them? */
350 #define TYPEINFO_PUT_NULLTYPE(info) \
351 do {(info).typeclass = pseudo_class_Null;} while(0)
353 #define TYPEINFO_PUT_NON_ARRAY_CLASSINFO(info,cinfo) \
354 do {(info).typeclass = (cinfo);} while(0)
356 #define TYPEINFO_PUT_CLASSINFO(info,cls) \
357 do {if (((info).typeclass = (cls))->vftbl->arraydesc) { \
358 if ((cls)->vftbl->arraydesc->elementvftbl) \
359 (info).elementclass = (cls)->vftbl->arraydesc->elementvftbl->class; \
360 (info).dimension = (cls)->vftbl->arraydesc->dimension; \
361 (info).elementtype = (cls)->vftbl->arraydesc->elementtype; \
364 /* srcarray must be an array (not checked) */
365 #define TYPEINFO_PUT_COMPONENT(srcarray,dst) \
366 do {typeinfo_put_component(&(srcarray),&(dst));} while(0)
370 /* macros for copying types (destinition is not checked or freed) ***********/
372 /* TYPEINFO_COPY makes a shallow copy, the merged pointer is simply copied. */
373 #define TYPEINFO_COPY(src,dst) \
374 do {(dst) = (src);} while(0)
376 /* TYPEINFO_CLONE makes a deep copy, the merged list (if any) is duplicated
377 * into a newly allocated array.
379 #define TYPEINFO_CLONE(src,dst) \
381 if ((dst).merged) typeinfo_clone(&(src),&(dst));} while(0)
383 /****************************************************************************/
385 /****************************************************************************/
387 /* typevector functions *****************************************************/
389 /* element read-only access */
390 bool typevectorset_checktype(typevector *set,int index,int type);
391 bool typevectorset_checkreference(typevector *set,int index);
392 bool typevectorset_checkretaddr(typevector *set,int index);
393 int typevectorset_copymergedtype(typevector *set,int index,typeinfo *dst);
394 typeinfo *typevectorset_mergedtypeinfo(typevector *set,int index,typeinfo *temp);
395 int typevectorset_mergedtype(typevector *set,int index,typeinfo *temp,typeinfo **result);
397 /* element write access */
398 void typevectorset_store(typevector *set,int index,int type,typeinfo *info);
399 void typevectorset_store_retaddr(typevector *set,int index,typeinfo *info);
400 void typevectorset_store_twoword(typevector *set,int index,int type);
401 void typevectorset_init_object(typevector *set,void *ins,classinfo *initclass,int size);
403 /* vector functions */
404 bool typevector_separable_from(typevector *a,typevector *b,int size);
405 bool typevector_merge(typevector *dst,typevector *y,int size);
407 /* vector set functions */
408 typevector *typevectorset_copy(typevector *src,int k,int size);
409 /* typevector *typevectorset_copy_select(typevector *src,
410 int retindex,void *retaddr,int size);
411 void typevectorset_copy_select_to(typevector *src,typevector *dst,
412 int retindex,void *retaddr,int size); */
413 /* bool typevectorset_separable(typevector *set,int size); */
414 bool typevectorset_separable_with(typevector *set,typevector *add,int size);
415 bool typevectorset_collapse(typevector *dst,int size);
416 void typevectorset_add(typevector *dst,typevector *v,int size);
417 /* void typevectorset_union(typevector *dst,typevector *v,int size); */
418 typevector *typevectorset_select(typevector **set,int retindex,void *retaddr);
420 /* inquiry functions (read-only) ********************************************/
422 bool typeinfo_is_array(typeinfo *info);
423 bool typeinfo_is_primitive_array(typeinfo *info,int arraytype);
424 bool typeinfo_is_array_of_refs(typeinfo *info);
426 bool typeinfo_implements_interface(typeinfo *info,classinfo *interf);
427 bool typeinfo_is_assignable(typeinfo *value,typeinfo *dest);
429 /* initialization functions *************************************************/
431 void typeinfo_init_from_descriptor(typeinfo *info,char *utf_ptr,char *end_ptr);
432 void typeinfo_init_component(typeinfo *srcarray,typeinfo *dst);
434 int typeinfo_count_method_args(utf *d,bool twoword); /* this not included */
435 void typeinfo_init_from_method_args(utf *desc,u1 *typebuf,
437 int buflen,bool twoword,
438 int *returntype,typeinfo *returntypeinfo);
439 int typedescriptors_init_from_method_args(typedescriptor *td,
441 int buflen,bool twoword,
442 typedescriptor *returntype);
444 void typeinfo_clone(typeinfo *src,typeinfo *dest);
446 /* functions for the type system ********************************************/
448 void typeinfo_free(typeinfo *info);
450 bool typeinfo_merge(typeinfo *dest,typeinfo* y);
452 /* debugging helpers ********************************************************/
454 #ifdef TYPEINFO_DEBUG
458 void typeinfo_test();
459 void typeinfo_init_from_fielddescriptor(typeinfo *info,char *desc);
460 void typeinfo_print(FILE *file,typeinfo *info,int indent);
461 void typeinfo_print_short(FILE *file,typeinfo *info);
462 void typeinfo_print_type(FILE *file,int type,typeinfo *info);
463 void typeinfo_print_stacktype(FILE *file,int type,typeinfo *info);
464 void typedescriptor_print(FILE *file,typedescriptor *td);
465 void typevector_print(FILE *file,typevector *vec,int size);
466 void typevectorset_print(FILE *file,typevector *set,int size);
468 #endif /* TYPEINFO_DEBUG */
470 #endif /* _TYPEINFO_H */
474 * These are local overrides for various environment variables in Emacs.
475 * Please do not remove this and leave it at the end of the file, where
476 * Emacs will automagically detect them.
477 * ---------------------------------------------------------------------
480 * indent-tabs-mode: t