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 795 2003-12-16 22:27:52Z edwin $
39 /* resolve typedef cycles *****************************************************/
41 typedef struct typeinfo typeinfo;
42 typedef struct typeinfo_mergedlist typeinfo_mergedlist;
44 /* global variables ***********************************************************/
46 /* XXX move this documentation to global.h */
47 /* The following classinfo pointers are used internally by the type system.
48 * Please do not use them directly, use the TYPEINFO_ macros instead.
52 * pseudo_class_Arraystub
53 * (extends Object implements Cloneable, java.io.Serializable)
55 * If two arrays of incompatible component types are merged,
56 * the resulting reference has no accessible components.
57 * The result does, however, implement the interfaces Cloneable
58 * and java.io.Serializable. This pseudo class is used internally
59 * to represent such results. (They are *not* considered arrays!)
63 * This pseudo class is used internally to represent the
67 /* data structures for the type system ****************************************/
69 /* The typeinfo structure stores detailed information on reference types.
70 * (stack elements, variables, etc. with type == TYPE_ADR.)
71 * XXX: exclude ReturnAddresses?
73 * For primitive types either there is no typeinfo allocated or the
74 * typeclass pointer in the typeinfo struct is NULL.
76 * CAUTION: The typeinfo structure should be considered opaque outside of
77 * typeinfo.[ch]. Please use the macros and functions defined here to
78 * access typeinfo structures!
81 /* At all times *exactly one* of the following conditions is true for
82 * a particular typeinfo struct:
84 * A) typeclass == NULL
86 * In this case the other fields of the structure
89 * B) typeclass == pseudo_class_Null
93 * C) typeclass is an array class
97 * D) typeclass == pseudo_class_Arraystub
101 * E) typeclass is an interface
105 * F) typeclass is a (non-pseudo-)class != java.lang.Object
108 * All classinfos in u.merged.list (if any) are
109 * subclasses of typeclass.
111 * G) typeclass is java.lang.Object
114 * In this case u.merged.count and u.merged.list
115 * are valid and may be non-zero.
116 * The classinfos in u.merged.list (if any) can be
117 * classes, interfaces or pseudo classes.
120 /* The following algorithm is used to determine if the type described
121 * by this typeinfo struct supports the interface X:
123 * 1) If typeclass is X or a subinterface of X the answer is "yes".
124 * 2) If typeclass is a (pseudo) class implementing X the answer is "yes".
125 * 3) XXX If typeclass is not an array and u.merged.count>0
126 * and all classes/interfaces in u.merged.list implement X
127 * the answer is "yes".
128 * 4) If none of the above is true the answer is "no".
132 * CAUTION: The typeinfo structure should be considered opaque outside of
133 * typeinfo.[ch]. Please use the macros and functions defined here to
134 * access typeinfo structures!
137 classinfo *typeclass;
138 classinfo *elementclass; /* valid if dimension>0 */
139 typeinfo_mergedlist *merged;
141 u1 elementtype; /* valid if dimension>0 */
144 struct typeinfo_mergedlist {
146 classinfo *list[1]; /* variable length! */
149 /****************************************************************************/
151 /****************************************************************************/
153 /* NOTE: These macros take typeinfo *structs* not pointers as arguments.
154 * You have to dereference any pointers.
157 /* internally used macros ***************************************************/
159 /* internal, don't use this explicitly! */
160 #define TYPEINFO_ALLOCMERGED(mergedlist,count) \
161 do {(mergedlist) = (typeinfo_mergedlist*)dump_alloc( \
162 sizeof(typeinfo_mergedlist) \
163 + ((count)-1)*sizeof(classinfo*));} while(0)
165 /* internal, don't use this explicitly! */
166 #define TYPEINFO_FREEMERGED(mergedlist)
168 /* internal, don't use this explicitly! */
169 #define TYPEINFO_FREEMERGED_IF_ANY(mergedlist)
171 /* macros for type queries **************************************************/
173 #define TYPEINFO_IS_PRIMITIVE(info) \
174 ((info).typeclass == NULL)
176 #define TYPEINFO_IS_REFERENCE(info) \
177 ((info).typeclass != NULL)
179 #define TYPEINFO_IS_NULLTYPE(info) \
180 ((info).typeclass == pseudo_class_Null)
182 #define TYPEINFO_IS_NEWOBJECT(info) \
183 ((info).typeclass == pseudo_class_New)
185 /* only use this if TYPEINFO_IS_NEWOBJECT returned true! */
186 #define TYPEINFO_NEWOBJECT_INSTRUCTION(info) \
187 ((void *)(info).elementclass)
189 /* macros for array type queries ********************************************/
191 #define TYPEINFO_IS_ARRAY(info) \
192 ( TYPEINFO_IS_REFERENCE(info) \
193 && ((info).dimension != 0) )
195 #define TYPEINFO_IS_SIMPLE_ARRAY(info) \
196 ( ((info).dimension == 1) )
198 #define TYPEINFO_IS_ARRAY_ARRAY(info) \
199 ( ((info).dimension >= 2) )
201 #define TYPEINFO_IS_PRIMITIVE_ARRAY(info,arraytype) \
202 ( TYPEINFO_IS_SIMPLE_ARRAY(info) \
203 && ((info).elementtype == (arraytype)) )
205 #define TYPEINFO_IS_OBJECT_ARRAY(info) \
206 ( TYPEINFO_IS_SIMPLE_ARRAY(info) \
207 && ((info).elementclass != NULL) )
209 /* assumes that info describes an array type */
210 #define TYPEINFO_IS_ARRAY_OF_REFS_NOCHECK(info) \
211 ( ((info).elementclass != NULL) \
212 || ((info).dimension >= 2) )
214 #define TYPEINFO_IS_ARRAY_OF_REFS(info) \
215 ( TYPEINFO_IS_ARRAY(info) \
216 && TYPEINFO_IS_ARRAY_OF_REFS_NOCHECK(info) )
218 /* queries allowing the null type ********************************************/
220 #define TYPEINFO_MAYBE_ARRAY(info) \
221 (TYPEINFO_IS_ARRAY(info) || TYPEINFO_IS_NULLTYPE(info))
223 #define TYPEINFO_MAYBE_PRIMITIVE_ARRAY(info,at) \
224 (TYPEINFO_IS_PRIMITIVE_ARRAY(info,at) || TYPEINFO_IS_NULLTYPE(info))
226 #define TYPEINFO_MAYBE_ARRAY_OF_REFS(info) \
227 (TYPEINFO_IS_ARRAY_OF_REFS(info) || TYPEINFO_IS_NULLTYPE(info))
229 /* macros for initializing typeinfo structures ******************************/
231 #define TYPEINFO_INIT_PRIMITIVE(info) \
232 do {(info).typeclass = NULL; \
233 (info).elementclass = NULL; \
234 (info).merged = NULL; \
235 (info).dimension = 0; \
236 (info).elementtype = 0;} while(0)
238 #define TYPEINFO_INIT_NON_ARRAY_CLASSINFO(info,cinfo) \
239 do {(info).typeclass = (cinfo); \
240 (info).elementclass = NULL; \
241 (info).merged = NULL; \
242 (info).dimension = 0; \
243 (info).elementtype = 0;} while(0)
245 #define TYPEINFO_INIT_NULLTYPE(info) \
246 TYPEINFO_INIT_CLASSINFO(info,pseudo_class_Null)
248 #define TYPEINFO_INIT_NEWOBJECT(info,instr) \
249 do {(info).typeclass = pseudo_class_New; \
250 (info).elementclass = (classinfo*) (instr);\
251 (info).merged = NULL; \
252 (info).dimension = 0; \
253 (info).elementtype = 0;} while(0)
255 #define TYPEINFO_INIT_PRIMITIVE_ARRAY(info,arraytype) \
256 TYPEINFO_INIT_CLASSINFO(info,primitivetype_table[arraytype].arrayclass);
258 #define TYPEINFO_INIT_CLASSINFO(info,cls) \
259 do {if (((info).typeclass = (cls))->vftbl->arraydesc) { \
260 if ((cls)->vftbl->arraydesc->elementvftbl) \
261 (info).elementclass = (cls)->vftbl->arraydesc->elementvftbl->class; \
263 (info).elementclass = NULL; \
264 (info).dimension = (cls)->vftbl->arraydesc->dimension; \
265 (info).elementtype = (cls)->vftbl->arraydesc->elementtype; \
268 (info).elementclass = NULL; \
269 (info).dimension = 0; \
270 (info).elementtype = 0; \
272 (info).merged = NULL;} while(0)
274 #define TYPEINFO_INIT_FROM_FIELDINFO(info,fi) \
275 typeinfo_init_from_descriptor(&(info), \
276 (fi)->descriptor->text,utf_end((fi)->descriptor));
278 /* macros for writing types (destination must have been initialized) ********/
279 /* XXX delete them? */
282 #define TYPEINFO_PUT_NULLTYPE(info) \
283 do {(info).typeclass = pseudo_class_Null;} while(0)
285 #define TYPEINFO_PUT_NON_ARRAY_CLASSINFO(info,cinfo) \
286 do {(info).typeclass = (cinfo);} while(0)
288 #define TYPEINFO_PUT_CLASSINFO(info,cls) \
289 do {if (((info).typeclass = (cls))->vftbl->arraydesc) { \
290 if ((cls)->vftbl->arraydesc->elementvftbl) \
291 (info).elementclass = (cls)->vftbl->arraydesc->elementvftbl->class; \
292 (info).dimension = (cls)->vftbl->arraydesc->dimension; \
293 (info).elementtype = (cls)->vftbl->arraydesc->elementtype; \
296 /* srcarray must be an array (not checked) */
297 #define TYPEINFO_PUT_COMPONENT(srcarray,dst) \
298 do {typeinfo_put_component(&(srcarray),&(dst));} while(0)
302 /* macros for copying types (destinition is not checked or freed) ***********/
304 /* TYPEINFO_COPY makes a shallow copy, the merged pointer is simply copied. */
305 #define TYPEINFO_COPY(src,dst) \
306 do {(dst) = (src);} while(0)
308 /* TYPEINFO_CLONE makes a deep copy, the merged list (if any) is duplicated
309 * into a newly allocated array.
311 #define TYPEINFO_CLONE(src,dst) \
313 if ((dst).merged) typeinfo_clone(&(src),&(dst));} while(0)
315 /****************************************************************************/
317 /****************************************************************************/
319 /* inquiry functions (read-only) ********************************************/
321 bool typeinfo_is_array(typeinfo *info);
322 bool typeinfo_is_primitive_array(typeinfo *info,int arraytype);
323 bool typeinfo_is_array_of_refs(typeinfo *info);
325 bool typeinfo_implements_interface(typeinfo *info,classinfo *interf);
326 bool typeinfo_is_assignable(typeinfo *value,typeinfo *dest);
328 /* initialization functions *************************************************/
330 void typeinfo_init_from_descriptor(typeinfo *info,char *utf_ptr,char *end_ptr);
331 void typeinfo_init_component(typeinfo *srcarray,typeinfo *dst);
333 int typeinfo_count_method_args(utf *d,bool twoword); /* this not included */
334 void typeinfo_init_from_method_args(utf *desc,u1 *typebuf,
336 int buflen,bool twoword,
337 int *returntype,typeinfo *returntypeinfo);
339 void typeinfo_clone(typeinfo *src,typeinfo *dest);
341 /* functions for the type system ********************************************/
343 void typeinfo_free(typeinfo *info);
345 bool typeinfo_merge(typeinfo *dest,typeinfo* y);
347 /* debugging helpers ********************************************************/
349 #ifdef TYPEINFO_DEBUG
353 void typeinfo_test();
354 void typeinfo_init_from_fielddescriptor(typeinfo *info,char *desc);
355 void typeinfo_print(FILE *file,typeinfo *info,int indent);
356 void typeinfo_print_short(FILE *file,typeinfo *info);
357 void typeinfo_print_type(FILE *file,int type,typeinfo *info);
359 #endif /* TYPEINFO_DEBUG */
361 #endif /* _TYPEINFO_H */
365 * These are local overrides for various environment variables in Emacs.
366 * Please do not remove this and leave it at the end of the file, where
367 * Emacs will automagically detect them.
368 * ---------------------------------------------------------------------
371 * indent-tabs-mode: t