verifier documentation
[cacao.git] / typeinfo.h
1 /* typeinfo.h - type system used by the type checker
2
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
7
8    This file is part of CACAO.
9
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.
14
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.
19
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
23    02111-1307, USA.
24
25    Contact: cacao@complang.tuwien.ac.at
26
27    Authors: Edwin Steiner
28
29    $Id: typeinfo.h 870 2004-01-10 22:49:32Z edwin $
30
31 */
32
33
34 #ifndef _TYPEINFO_H
35 #define _TYPEINFO_H
36
37 #include "global.h"
38
39 /* resolve typedef cycles *****************************************************/
40
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;
46
47 /* global variables ***********************************************************/
48
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.
52  */
53
54 /*
55  * pseudo_class_Arraystub
56  *     (extends Object implements Cloneable, java.io.Serializable)
57  *
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!)
63  *
64  * pseudo_class_Null
65  *
66  *     This pseudo class is used internally to represent the
67  *     null type.
68  *
69  * pseudo_class_New
70  *
71  *     This pseudo class is used internally to represent the
72  *     the uninitialized object type.
73  */
74
75 /* data structures for the type system ****************************************/
76
77 /* The typeinfo structure stores detailed information on reference types.
78  * (stack elements, variables, etc. with type == TYPE_ADR.)
79  * XXX: exclude ReturnAddresses?
80  *
81  * XXX
82  * For primitive types either there is no typeinfo allocated or the
83  * typeclass pointer in the typeinfo struct is NULL.
84  *
85  * CAUTION: The typeinfo structure should be considered opaque outside of
86  *          typeinfo.[ch]. Please use the macros and functions defined here to
87  *          access typeinfo structures!
88  */
89
90 /* At all times *exactly one* of the following conditions is true for
91  * a particular typeinfo struct:
92  *
93  * A) typeclass == NULL
94  *
95  *        In this case the other fields of the structure
96  *        are INVALID. XXX
97  *
98  * B) typeclass == pseudo_class_Null
99  *
100  *        XXX
101  *
102  * C) typeclass == pseudo_class_New
103  *
104  *        XXX
105  *
106  * D) typeclass == pseudo_class_Arraystub
107  *
108  *        XXX
109  *
110  * E) typeclass is an array class
111  *
112  *        XXX
113  *
114  * F) typeclass is an interface
115  *
116  *        XXX
117  *
118  * G) typeclass is a (non-pseudo-)class != java.lang.Object
119  *
120  *        XXX
121  *        All classinfos in u.merged.list (if any) are
122  *        subclasses of typeclass.
123  *
124  * H) typeclass is java.lang.Object
125  *
126  *        XXX
127  *        In this case u.merged.count and u.merged.list
128  *        are valid and may be non-zero.
129  *        The classinfos in u.merged.list (if any) can be
130  *        classes, interfaces or pseudo classes.
131  */
132
133 /* The following algorithm is used to determine if the type described
134  * by this typeinfo struct supports the interface X:
135  *
136  *     1) If typeclass is X or a subinterface of X the answer is "yes".
137  *     2) If typeclass is a (pseudo) class implementing X the answer is "yes".
138  *     3) XXX If typeclass is not an array and u.merged.count>0
139  *        and all classes/interfaces in u.merged.list implement X
140  *        the answer is "yes".
141  *     4) If none of the above is true the answer is "no".
142  */
143
144 /*
145  * CAUTION: The typeinfo structure should be considered opaque outside of
146  *          typeinfo.[ch]. Please use the macros and functions defined here to
147  *          access typeinfo structures!
148  */
149 struct typeinfo {
150         classinfo           *typeclass;
151         classinfo           *elementclass; /* valid if dimension>0 */ /* XXX various uses */
152         typeinfo_mergedlist *merged;
153         u1                   dimension;
154         u1                   elementtype;  /* valid if dimension>0 */
155 };
156
157 struct typeinfo_mergedlist {
158         s4         count;
159         classinfo *list[1];       /* variable length!                        */
160 };
161
162 struct typeinfo_retaddr_set {
163         typeinfo_retaddr_set *alt;  /* next alternative in set               */
164         void                 *addr; /* return address                        */
165 };
166
167 struct typedescriptor {
168         typeinfo        info;     /* valid if type == TYPE_ADR               */
169         u1              type;     /* basic type (TYPE_INT, ...)              */
170 };
171
172 /* typevectors are used to store the types of local variables */
173
174 struct typevector {
175         typevector      *alt;     /* next alternative in typevector set */
176         int              k;       /* for lining up with the stack set   */
177         typedescriptor   td[1];   /* variable length!                   */
178 };
179
180 /****************************************************************************/
181 /* MACROS                                                                   */
182 /****************************************************************************/
183
184 /* NOTE: The TYPEINFO macros take typeinfo *structs*, not pointers as
185  *       arguments.  You have to dereference any pointers.
186  */
187
188 /* typevectors **************************************************************/
189
190 #define TYPEVECTOR_SIZE(size)                                           \
191     ((sizeof(typevector) - sizeof(typedescriptor))      \
192      + (size)*sizeof(typedescriptor))
193
194 #define DNEW_TYPEVECTOR(size)                                           \
195     ((typevector*)dump_alloc(TYPEVECTOR_SIZE(size)))
196
197 #define DMNEW_TYPEVECTOR(num,size)                                              \
198     ((void*)dump_alloc((num) * TYPEVECTOR_SIZE(size)))
199
200 #define MGET_TYPEVECTOR(array,index,size) \
201     ((typevector*) (((u1*)(array)) + TYPEVECTOR_SIZE(size) * (index)))
202
203 #define COPY_TYPEVECTORSET(src,dst,size)                                                \
204     do {memcpy(dst,src,TYPEVECTOR_SIZE(size));                                  \
205         dst->k = 0;                                             \
206         if ((src)->alt) {                                                                               \
207                 (dst)->alt = typevectorset_copy((src)->alt,1,size);     \
208         }} while(0)
209
210 /* internally used macros ***************************************************/
211
212 /* internal, don't use this explicitly! */
213 #define TYPEINFO_ALLOCMERGED(mergedlist,count)                  \
214     do {(mergedlist) = (typeinfo_mergedlist*)dump_alloc(        \
215             sizeof(typeinfo_mergedlist)                         \
216             + ((count)-1)*sizeof(classinfo*));} while(0)
217
218 /* internal, don't use this explicitly! */
219 #define TYPEINFO_FREEMERGED(mergedlist)
220
221 /* internal, don't use this explicitly! */
222 #define TYPEINFO_FREEMERGED_IF_ANY(mergedlist)
223
224 /* macros for type queries **************************************************/
225
226 #define TYPEINFO_IS_PRIMITIVE(info)                             \
227             ((info).typeclass == NULL)
228
229 #define TYPEINFO_IS_REFERENCE(info)                             \
230             ((info).typeclass != NULL)
231
232 #define TYPEINFO_IS_NULLTYPE(info)                              \
233             ((info).typeclass == pseudo_class_Null)
234
235 #define TYPEINFO_IS_NEWOBJECT(info)                             \
236             ((info).typeclass == pseudo_class_New)
237
238 /* only use this if TYPEINFO_IS_PRIMITIVE returned true! */
239 #define TYPEINFO_RETURNADDRESS(info)                            \
240             ((void *)(info).elementclass)
241
242 /* only use this if TYPEINFO_IS_NEWOBJECT returned true! */
243 #define TYPEINFO_NEWOBJECT_INSTRUCTION(info)                    \
244             ((void *)(info).elementclass)
245
246 /* macros for array type queries ********************************************/
247
248 #define TYPEINFO_IS_ARRAY(info)                                 \
249             ( TYPEINFO_IS_REFERENCE(info)                       \
250               && ((info).dimension != 0) )
251
252 #define TYPEINFO_IS_SIMPLE_ARRAY(info)                          \
253             ( ((info).dimension == 1) )
254
255 #define TYPEINFO_IS_ARRAY_ARRAY(info)                           \
256             ( ((info).dimension >= 2) )
257
258 #define TYPEINFO_IS_PRIMITIVE_ARRAY(info,arraytype)             \
259             ( TYPEINFO_IS_SIMPLE_ARRAY(info)                    \
260               && ((info).elementtype == (arraytype)) )
261
262 #define TYPEINFO_IS_OBJECT_ARRAY(info)                          \
263             ( TYPEINFO_IS_SIMPLE_ARRAY(info)                    \
264               && ((info).elementclass != NULL) )
265
266 /* assumes that info describes an array type */
267 #define TYPEINFO_IS_ARRAY_OF_REFS_NOCHECK(info)                 \
268             ( ((info).elementclass != NULL)                     \
269               || ((info).dimension >= 2) )
270
271 #define TYPEINFO_IS_ARRAY_OF_REFS(info)                         \
272             ( TYPEINFO_IS_ARRAY(info)                           \
273               && TYPEINFO_IS_ARRAY_OF_REFS_NOCHECK(info) )
274
275 #define TYPE_IS_RETURNADDRESS(type,info)                        \
276             ( ((type)==TYPE_ADDRESS)                            \
277               && TYPEINFO_IS_PRIMITIVE(info) )
278
279 #define TYPE_IS_REFERENCE(type,info)                            \
280             ( ((type)==TYPE_ADDRESS)                            \
281               && !TYPEINFO_IS_PRIMITIVE(info) )
282
283 #define TYPEDESC_IS_RETURNADDRESS(td)                           \
284             TYPE_IS_RETURNADDRESS((td).type,(td).info)
285
286 #define TYPEDESC_IS_REFERENCE(td)                               \
287             TYPE_IS_REFERENCE((td).type,(td).info)
288
289 /* queries allowing the null type ********************************************/
290
291 #define TYPEINFO_MAYBE_ARRAY(info)                              \
292     (TYPEINFO_IS_ARRAY(info) || TYPEINFO_IS_NULLTYPE(info))
293
294 #define TYPEINFO_MAYBE_PRIMITIVE_ARRAY(info,at)                 \
295     (TYPEINFO_IS_PRIMITIVE_ARRAY(info,at) || TYPEINFO_IS_NULLTYPE(info))
296
297 #define TYPEINFO_MAYBE_ARRAY_OF_REFS(info)                      \
298     (TYPEINFO_IS_ARRAY_OF_REFS(info) || TYPEINFO_IS_NULLTYPE(info))
299
300 /* macros for initializing typeinfo structures ******************************/
301
302 #define TYPEINFO_INIT_PRIMITIVE(info)                           \
303          do {(info).typeclass = NULL;                           \
304              (info).elementclass = NULL;                        \
305              (info).merged = NULL;                              \
306              (info).dimension = 0;                              \
307              (info).elementtype = 0;} while(0)
308
309 #define TYPEINFO_INIT_RETURNADDRESS(info,adr)                   \
310          do {(info).typeclass = NULL;                           \
311              (info).elementclass = (classinfo*) (adr);          \
312              (info).merged = NULL;                              \
313              (info).dimension = 0;                              \
314              (info).elementtype = 0;} while(0)
315
316 #define TYPEINFO_INIT_NON_ARRAY_CLASSINFO(info,cinfo)   \
317          do {(info).typeclass = (cinfo);                \
318              (info).elementclass = NULL;                \
319              (info).merged = NULL;                      \
320              (info).dimension = 0;                      \
321              (info).elementtype = 0;} while(0)
322
323 #define TYPEINFO_INIT_NULLTYPE(info)                            \
324             TYPEINFO_INIT_CLASSINFO(info,pseudo_class_Null)
325
326 #define TYPEINFO_INIT_NEWOBJECT(info,instr)             \
327          do {(info).typeclass = pseudo_class_New;       \
328              (info).elementclass = (classinfo*) (instr);\
329              (info).merged = NULL;                      \
330              (info).dimension = 0;                      \
331              (info).elementtype = 0;} while(0)
332
333 #define TYPEINFO_INIT_PRIMITIVE_ARRAY(info,arraytype)                   \
334     TYPEINFO_INIT_CLASSINFO(info,primitivetype_table[arraytype].arrayclass);
335
336 #define TYPEINFO_INIT_CLASSINFO(info,cls)                               \
337         do {if (((info).typeclass = (cls))->vftbl->arraydesc) {         \
338                 if ((cls)->vftbl->arraydesc->elementvftbl)              \
339                     (info).elementclass = (cls)->vftbl->arraydesc->elementvftbl->class; \
340                 else                                                    \
341                     (info).elementclass = NULL;                         \
342                 (info).dimension = (cls)->vftbl->arraydesc->dimension;  \
343                 (info).elementtype = (cls)->vftbl->arraydesc->elementtype; \
344             }                                                           \
345             else {                                                      \
346                 (info).elementclass = NULL;                             \
347                 (info).dimension = 0;                                   \
348                 (info).elementtype = 0;                                 \
349             }                                                           \
350             (info).merged = NULL;} while(0)
351
352 #define TYPEINFO_INIT_FROM_FIELDINFO(info,fi)                   \
353             typeinfo_init_from_descriptor(&(info),              \
354                 (fi)->descriptor->text,utf_end((fi)->descriptor));
355
356 /* macros for writing types (destination must have been initialized) ********/
357 /* XXX delete them? */
358 #if 0
359
360 #define TYPEINFO_PUT_NULLTYPE(info)                             \
361     do {(info).typeclass = pseudo_class_Null;} while(0)
362
363 #define TYPEINFO_PUT_NON_ARRAY_CLASSINFO(info,cinfo)            \
364     do {(info).typeclass = (cinfo);} while(0)
365
366 #define TYPEINFO_PUT_CLASSINFO(info,cls)                                \
367     do {if (((info).typeclass = (cls))->vftbl->arraydesc) {             \
368                 if ((cls)->vftbl->arraydesc->elementvftbl)                \
369                     (info).elementclass = (cls)->vftbl->arraydesc->elementvftbl->class; \
370                 (info).dimension = (cls)->vftbl->arraydesc->dimension;    \
371                 (info).elementtype = (cls)->vftbl->arraydesc->elementtype; \
372         }} while(0)
373
374 /* srcarray must be an array (not checked) */
375 #define TYPEINFO_PUT_COMPONENT(srcarray,dst)                    \
376     do {typeinfo_put_component(&(srcarray),&(dst));} while(0)
377
378 #endif
379
380 /* macros for copying types (destinition is not checked or freed) ***********/
381
382 /* TYPEINFO_COPY makes a shallow copy, the merged pointer is simply copied. */
383 #define TYPEINFO_COPY(src,dst)                                  \
384     do {(dst) = (src);} while(0)
385
386 /* TYPEINFO_CLONE makes a deep copy, the merged list (if any) is duplicated
387  * into a newly allocated array.
388  */
389 #define TYPEINFO_CLONE(src,dst)                                 \
390     do {(dst) = (src);                                          \
391         if ((dst).merged) typeinfo_clone(&(src),&(dst));} while(0)
392
393 /****************************************************************************/
394 /* FUNCTIONS                                                                */
395 /****************************************************************************/
396
397 /* typevector functions *****************************************************/
398
399 /* element read-only access */
400 bool typevectorset_checktype(typevector *set,int index,int type);
401 bool typevectorset_checkreference(typevector *set,int index);
402 bool typevectorset_checkretaddr(typevector *set,int index);
403 int typevectorset_copymergedtype(typevector *set,int index,typeinfo *dst);
404 typeinfo *typevectorset_mergedtypeinfo(typevector *set,int index,typeinfo *temp);
405 int typevectorset_mergedtype(typevector *set,int index,typeinfo *temp,typeinfo **result);
406
407 /* element write access */
408 void typevectorset_store(typevector *set,int index,int type,typeinfo *info);
409 void typevectorset_store_retaddr(typevector *set,int index,typeinfo *info);
410 void typevectorset_store_twoword(typevector *set,int index,int type);
411 void typevectorset_init_object(typevector *set,void *ins,classinfo *initclass,int size);
412
413 /* vector functions */
414 bool typevector_separable_from(typevector *a,typevector *b,int size);
415 bool typevector_merge(typevector *dst,typevector *y,int size);
416
417 /* vector set functions */
418 typevector *typevectorset_copy(typevector *src,int k,int size);
419 bool typevectorset_separable_with(typevector *set,typevector *add,int size);
420 bool typevectorset_collapse(typevector *dst,int size);
421 void typevectorset_add(typevector *dst,typevector *v,int size);
422 typevector *typevectorset_select(typevector **set,int retindex,void *retaddr);
423
424 /* inquiry functions (read-only) ********************************************/
425
426 bool typeinfo_is_array(typeinfo *info);
427 bool typeinfo_is_primitive_array(typeinfo *info,int arraytype);
428 bool typeinfo_is_array_of_refs(typeinfo *info);
429
430 bool typeinfo_implements_interface(typeinfo *info,classinfo *interf);
431 bool typeinfo_is_assignable(typeinfo *value,typeinfo *dest);
432 bool typeinfo_is_assignable_to_classinfo(typeinfo *value,classinfo *dest);
433
434 /* initialization functions *************************************************/
435
436 void typeinfo_init_from_descriptor(typeinfo *info,char *utf_ptr,char *end_ptr);
437 void typeinfo_init_component(typeinfo *srcarray,typeinfo *dst);
438
439 int  typeinfo_count_method_args(utf *d,bool twoword); /* this not included */
440 void typeinfo_init_from_method_args(utf *desc,u1 *typebuf,
441                                     typeinfo *infobuf,
442                                     int buflen,bool twoword,
443                                     int *returntype,typeinfo *returntypeinfo);
444 int  typedescriptors_init_from_method_args(typedescriptor *td,
445                                                                                    utf *desc,
446                                                                                    int buflen,bool twoword,
447                                                                                    typedescriptor *returntype);
448
449 void typeinfo_clone(typeinfo *src,typeinfo *dest);
450
451 /* functions for the type system ********************************************/
452
453 void typeinfo_free(typeinfo *info);
454
455 bool typeinfo_merge(typeinfo *dest,typeinfo* y);
456
457 /* debugging helpers ********************************************************/
458
459 #ifdef TYPEINFO_DEBUG
460
461 #include <stdio.h>
462
463 void typeinfo_test();
464 void typeinfo_init_from_fielddescriptor(typeinfo *info,char *desc);
465 void typeinfo_print(FILE *file,typeinfo *info,int indent);
466 void typeinfo_print_short(FILE *file,typeinfo *info);
467 void typeinfo_print_type(FILE *file,int type,typeinfo *info);
468 void typeinfo_print_stacktype(FILE *file,int type,typeinfo *info);
469 void typedescriptor_print(FILE *file,typedescriptor *td);
470 void typevector_print(FILE *file,typevector *vec,int size);
471 void typevectorset_print(FILE *file,typevector *set,int size);
472
473 #endif /* TYPEINFO_DEBUG */
474
475 #endif /* _TYPEINFO_H */
476
477
478 /*
479  * These are local overrides for various environment variables in Emacs.
480  * Please do not remove this and leave it at the end of the file, where
481  * Emacs will automagically detect them.
482  * ---------------------------------------------------------------------
483  * Local variables:
484  * mode: c
485  * indent-tabs-mode: t
486  * c-basic-offset: 4
487  * tab-width: 4
488  * End:
489  */