implemented subroutine verification (Coglio's method) + several verifier fixes
[cacao.git] / src / vm / jit / verify / 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 868 2004-01-10 20:12:10Z 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
70 /* data structures for the type system ****************************************/
71
72 /* The typeinfo structure stores detailed information on reference types.
73  * (stack elements, variables, etc. with type == TYPE_ADR.)
74  * XXX: exclude ReturnAddresses?
75  *
76  * For primitive types either there is no typeinfo allocated or the
77  * typeclass pointer in the typeinfo struct is NULL.
78  *
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!
82  */
83
84 /* At all times *exactly one* of the following conditions is true for
85  * a particular typeinfo struct:
86  *
87  * A) typeclass == NULL
88  *
89  *        In this case the other fields of the structure
90  *        are INVALID.
91  *
92  * B) typeclass == pseudo_class_Null
93  *
94  *        XXX
95  *
96  * C) typeclass is an array class
97  *
98  *        XXX
99  *
100  * D) typeclass == pseudo_class_Arraystub
101  *
102  *        XXX
103  *
104  * E) typeclass is an interface
105  *
106  *        XXX
107  *
108  * F) typeclass is a (non-pseudo-)class != java.lang.Object
109  *
110  *        XXX
111  *        All classinfos in u.merged.list (if any) are
112  *        subclasses of typeclass.
113  *
114  * G) typeclass is java.lang.Object
115  *
116  *        XXX
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.
121  */
122
123 /* The following algorithm is used to determine if the type described
124  * by this typeinfo struct supports the interface X:
125  *
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".
132  */
133
134 /*
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!
138  */
139 struct typeinfo {
140         classinfo           *typeclass;
141         classinfo           *elementclass; /* valid if dimension>0 */ /* XXX various uses */
142         typeinfo_mergedlist *merged;
143         u1                   dimension;
144         u1                   elementtype;  /* valid if dimension>0 */
145 };
146
147 struct typeinfo_mergedlist {
148         s4         count;
149         classinfo *list[1];       /* variable length!                        */
150 };
151
152 struct typeinfo_retaddr_set {
153         typeinfo_retaddr_set *alt;  /* next alternative in set               */
154         void                 *addr; /* return address                        */
155 };
156
157 struct typedescriptor {
158         typeinfo        info;     /* valid if type == TYPE_ADR               */
159         u1              type;     /* basic type (TYPE_INT, ...)              */
160 };
161
162 /* typevectors are used to store the types of local variables */
163
164 struct typevector {
165         typevector      *alt;     /* next alternative in typevector set */
166         int              k;       /* for lining up with the stack set   */
167         typedescriptor   td[1];   /* variable length!                   */
168 };
169
170 /****************************************************************************/
171 /* MACROS                                                                   */
172 /****************************************************************************/
173
174 /* NOTE: The TYPEINFO macros take typeinfo *structs*, not pointers as
175  *       arguments.  You have to dereference any pointers.
176  */
177
178 /* typevectors **************************************************************/
179
180 #define TYPEVECTOR_SIZE(size)                                           \
181     ((sizeof(typevector) - sizeof(typedescriptor))      \
182      + (size)*sizeof(typedescriptor))
183
184 #define DNEW_TYPEVECTOR(size)                                           \
185     ((typevector*)dump_alloc(TYPEVECTOR_SIZE(size)))
186
187 #define DMNEW_TYPEVECTOR(num,size)                                              \
188     ((void*)dump_alloc((num) * TYPEVECTOR_SIZE(size)))
189
190 #define MGET_TYPEVECTOR(array,index,size) \
191     ((typevector*) (((u1*)(array)) + TYPEVECTOR_SIZE(size) * (index)))
192
193 #define COPY_TYPEVECTORSET(src,dst,size)                                                \
194     do {memcpy(dst,src,TYPEVECTOR_SIZE(size));                                  \
195         dst->k = 0;                                             \
196         if ((src)->alt) {                                                                               \
197                 (dst)->alt = typevectorset_copy((src)->alt,1,size);     \
198         }} while(0)
199
200 /* internally used macros ***************************************************/
201
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)
207
208 /* internal, don't use this explicitly! */
209 #define TYPEINFO_FREEMERGED(mergedlist)
210
211 /* internal, don't use this explicitly! */
212 #define TYPEINFO_FREEMERGED_IF_ANY(mergedlist)
213
214 /* macros for type queries **************************************************/
215
216 #define TYPEINFO_IS_PRIMITIVE(info)                             \
217             ((info).typeclass == NULL)
218
219 #define TYPEINFO_IS_REFERENCE(info)                             \
220             ((info).typeclass != NULL)
221
222 #define TYPEINFO_IS_NULLTYPE(info)                              \
223             ((info).typeclass == pseudo_class_Null)
224
225 #define TYPEINFO_IS_NEWOBJECT(info)                             \
226             ((info).typeclass == pseudo_class_New)
227
228 /* only use this if TYPEINFO_IS_PRIMITIVE returned true! */
229 #define TYPEINFO_RETURNADDRESS(info)                            \
230             ((void *)(info).elementclass)
231
232 /* only use this if TYPEINFO_IS_NEWOBJECT returned true! */
233 #define TYPEINFO_NEWOBJECT_INSTRUCTION(info)                    \
234             ((void *)(info).elementclass)
235
236 /* macros for array type queries ********************************************/
237
238 #define TYPEINFO_IS_ARRAY(info)                                 \
239             ( TYPEINFO_IS_REFERENCE(info)                       \
240               && ((info).dimension != 0) )
241
242 #define TYPEINFO_IS_SIMPLE_ARRAY(info)                          \
243             ( ((info).dimension == 1) )
244
245 #define TYPEINFO_IS_ARRAY_ARRAY(info)                           \
246             ( ((info).dimension >= 2) )
247
248 #define TYPEINFO_IS_PRIMITIVE_ARRAY(info,arraytype)             \
249             ( TYPEINFO_IS_SIMPLE_ARRAY(info)                    \
250               && ((info).elementtype == (arraytype)) )
251
252 #define TYPEINFO_IS_OBJECT_ARRAY(info)                          \
253             ( TYPEINFO_IS_SIMPLE_ARRAY(info)                    \
254               && ((info).elementclass != NULL) )
255
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) )
260
261 #define TYPEINFO_IS_ARRAY_OF_REFS(info)                         \
262             ( TYPEINFO_IS_ARRAY(info)                           \
263               && TYPEINFO_IS_ARRAY_OF_REFS_NOCHECK(info) )
264
265 #define TYPE_IS_RETURNADDRESS(type,info)                        \
266             ( ((type)==TYPE_ADDRESS)                            \
267               && TYPEINFO_IS_PRIMITIVE(info) )
268
269 #define TYPE_IS_REFERENCE(type,info)                            \
270             ( ((type)==TYPE_ADDRESS)                            \
271               && !TYPEINFO_IS_PRIMITIVE(info) )
272
273 #define TYPEDESC_IS_RETURNADDRESS(td)                           \
274             TYPE_IS_RETURNADDRESS((td).type,(td).info)
275
276 #define TYPEDESC_IS_REFERENCE(td)                               \
277             TYPE_IS_REFERENCE((td).type,(td).info)
278
279 /* queries allowing the null type ********************************************/
280
281 #define TYPEINFO_MAYBE_ARRAY(info)                              \
282     (TYPEINFO_IS_ARRAY(info) || TYPEINFO_IS_NULLTYPE(info))
283
284 #define TYPEINFO_MAYBE_PRIMITIVE_ARRAY(info,at)                 \
285     (TYPEINFO_IS_PRIMITIVE_ARRAY(info,at) || TYPEINFO_IS_NULLTYPE(info))
286
287 #define TYPEINFO_MAYBE_ARRAY_OF_REFS(info)                      \
288     (TYPEINFO_IS_ARRAY_OF_REFS(info) || TYPEINFO_IS_NULLTYPE(info))
289
290 /* macros for initializing typeinfo structures ******************************/
291
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)
298
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)
305
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)
312
313 #define TYPEINFO_INIT_NULLTYPE(info)                            \
314             TYPEINFO_INIT_CLASSINFO(info,pseudo_class_Null)
315
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)
322
323 #define TYPEINFO_INIT_PRIMITIVE_ARRAY(info,arraytype)                   \
324     TYPEINFO_INIT_CLASSINFO(info,primitivetype_table[arraytype].arrayclass);
325
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; \
330                 else                                                    \
331                     (info).elementclass = NULL;                         \
332                 (info).dimension = (cls)->vftbl->arraydesc->dimension;  \
333                 (info).elementtype = (cls)->vftbl->arraydesc->elementtype; \
334             }                                                           \
335             else {                                                      \
336                 (info).elementclass = NULL;                             \
337                 (info).dimension = 0;                                   \
338                 (info).elementtype = 0;                                 \
339             }                                                           \
340             (info).merged = NULL;} while(0)
341
342 #define TYPEINFO_INIT_FROM_FIELDINFO(info,fi)                   \
343             typeinfo_init_from_descriptor(&(info),              \
344                 (fi)->descriptor->text,utf_end((fi)->descriptor));
345
346 /* macros for writing types (destination must have been initialized) ********/
347 /* XXX delete them? */
348 #if 0
349
350 #define TYPEINFO_PUT_NULLTYPE(info)                             \
351     do {(info).typeclass = pseudo_class_Null;} while(0)
352
353 #define TYPEINFO_PUT_NON_ARRAY_CLASSINFO(info,cinfo)            \
354     do {(info).typeclass = (cinfo);} while(0)
355
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; \
362         }} while(0)
363
364 /* srcarray must be an array (not checked) */
365 #define TYPEINFO_PUT_COMPONENT(srcarray,dst)                    \
366     do {typeinfo_put_component(&(srcarray),&(dst));} while(0)
367
368 #endif
369
370 /* macros for copying types (destinition is not checked or freed) ***********/
371
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)
375
376 /* TYPEINFO_CLONE makes a deep copy, the merged list (if any) is duplicated
377  * into a newly allocated array.
378  */
379 #define TYPEINFO_CLONE(src,dst)                                 \
380     do {(dst) = (src);                                          \
381         if ((dst).merged) typeinfo_clone(&(src),&(dst));} while(0)
382
383 /****************************************************************************/
384 /* FUNCTIONS                                                                */
385 /****************************************************************************/
386
387 /* typevector functions *****************************************************/
388
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);
396
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);
402
403 /* vector functions */
404 bool typevector_separable_from(typevector *a,typevector *b,int size);
405 bool typevector_merge(typevector *dst,typevector *y,int size);
406
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);
419
420 /* inquiry functions (read-only) ********************************************/
421
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);
425
426 bool typeinfo_implements_interface(typeinfo *info,classinfo *interf);
427 bool typeinfo_is_assignable(typeinfo *value,typeinfo *dest);
428
429 /* initialization functions *************************************************/
430
431 void typeinfo_init_from_descriptor(typeinfo *info,char *utf_ptr,char *end_ptr);
432 void typeinfo_init_component(typeinfo *srcarray,typeinfo *dst);
433
434 int  typeinfo_count_method_args(utf *d,bool twoword); /* this not included */
435 void typeinfo_init_from_method_args(utf *desc,u1 *typebuf,
436                                     typeinfo *infobuf,
437                                     int buflen,bool twoword,
438                                     int *returntype,typeinfo *returntypeinfo);
439 int  typedescriptors_init_from_method_args(typedescriptor *td,
440                                                                                    utf *desc,
441                                                                                    int buflen,bool twoword,
442                                                                                    typedescriptor *returntype);
443
444 void typeinfo_clone(typeinfo *src,typeinfo *dest);
445
446 /* functions for the type system ********************************************/
447
448 void typeinfo_free(typeinfo *info);
449
450 bool typeinfo_merge(typeinfo *dest,typeinfo* y);
451
452 /* debugging helpers ********************************************************/
453
454 #ifdef TYPEINFO_DEBUG
455
456 #include <stdio.h>
457
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);
467
468 #endif /* TYPEINFO_DEBUG */
469
470 #endif /* _TYPEINFO_H */
471
472
473 /*
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  * ---------------------------------------------------------------------
478  * Local variables:
479  * mode: c
480  * indent-tabs-mode: t
481  * c-basic-offset: 4
482  * tab-width: 4
483  * End:
484  */