* src/threads/thread.cpp (threads_thread_is_alive): Recognize parked states.
[cacao.git] / src / vm / jit / verify / typeinfo.h
1 /* src/vm/jit/verify/typeinfo.h - type system used by the type checker
2
3    Copyright (C) 1996-2005, 2006, 2007, 2008
4    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5
6    This file is part of CACAO.
7
8    This program is free software; you can redistribute it and/or
9    modify it under the terms of the GNU General Public License as
10    published by the Free Software Foundation; either version 2, or (at
11    your option) any later version.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16    General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22
23 */
24
25 #ifndef _TYPEINFO_H
26 #define _TYPEINFO_H
27
28 /* resolve typedef cycles *****************************************************/
29
30 typedef struct typeinfo            typeinfo_t;
31 typedef struct typeinfo_mergedlist typeinfo_mergedlist_t;
32 typedef struct typedescriptor      typedescriptor_t;
33
34 #include "config.h"
35 #include "vm/types.h"
36
37 #include "vm/global.h"
38 #include "vm/references.h"
39
40
41 /* configuration **************************************************************/
42
43 /*
44  * TYPECHECK_STATISTICS activates gathering statistical information.
45  * TYPEINFO_DEBUG activates debug checks and debug helpers in typeinfo.c
46  * TYPECHECK_DEBUG activates debug checks in typecheck.c
47  * TYPEINFO_DEBUG_TEST activates the typeinfo test at startup.
48  * TYPECHECK_VERBOSE_IMPORTANT activates important debug messages
49  * TYPECHECK_VERBOSE activates all debug messages
50  * TYPEINFO_VERBOSE activates debug prints in typeinfo.c
51  */
52 #ifdef ENABLE_VERIFIER
53 #ifndef NDEBUG
54 /*#define TYPECHECK_STATISTICS*/
55 #define TYPEINFO_DEBUG
56 /*#define TYPEINFO_VERBOSE*/
57 #define TYPECHECK_DEBUG
58 /*#define TYPEINFO_DEBUG_TEST*/
59 /*#define TYPECHECK_VERBOSE*/
60 /*#define TYPECHECK_VERBOSE_IMPORTANT*/
61 #if defined(TYPECHECK_VERBOSE) || defined(TYPECHECK_VERBOSE_IMPORTANT)
62 #define TYPECHECK_VERBOSE_OPT
63 #endif
64 #endif
65 #endif
66
67 #ifdef TYPECHECK_VERBOSE_OPT
68 extern bool opt_typecheckverbose;
69 #endif
70
71 /* types **********************************************************************/
72
73 /* typecheck_result - return type for boolean and tristate  functions     */
74 /*                    which may also throw exceptions (typecheck_FAIL).   */
75
76 /* NOTE: Use the enum values, not the uppercase #define macros!          */
77 #define TYPECHECK_MAYBE  0x02
78 #define TYPECHECK_FAIL   0x04
79
80 typedef enum {
81         typecheck_FALSE = false,
82         typecheck_TRUE  = true,
83         typecheck_MAYBE = TYPECHECK_MAYBE,
84         typecheck_FAIL  = TYPECHECK_FAIL
85 } typecheck_result;
86
87 /* check that typecheck_MAYBE is not ambiguous */
88 #if TYPECHECK_MAYBE == true
89 #error "`typecheck_MAYBE` must not be the same as `true`"
90 #endif
91 #if TYPECHECK_MAYBE == false
92 #error "`typecheck_MAYBE` must not be the same as `false`"
93 #endif
94
95 /* check that typecheck_FAIL is not ambiguous */
96 #if (true & TYPECHECK_FAIL) != 0
97 #error "`true` must not have bit 0x02 set (conflicts with typecheck_FAIL)"
98 #endif
99
100 /* data structures for the type system ****************************************/
101
102 /* The typeinfo structure stores detailed information on address types.
103  * (stack elements, variables, etc. with type == TYPE_ADR.)
104  *
105  * There are two kinds of address types which can be distinguished by
106  * the value of the typeclass field:
107  *
108  * 1) typeclass == NULL: returnAddress type
109  *                       use TYPEINFO_IS_PRIMITIVE to test for this
110  *
111  * 2) typeclass != NULL: reference type
112  *                       use TYPEINFO_IS_REFERENCE to test for this
113  *
114  * Note: For non-address types either there is no typeinfo allocated
115  * or the fields of the typeinfo struct contain undefined values!
116  * DO NOT access the typeinfo for non-address types!
117  *
118  * CAUTION: The typeinfo structure should be considered opaque outside of
119  *          typeinfo.[ch]. Please use the macros and functions defined here to
120  *          access typeinfo structures!
121  */
122
123 /* At all times *exactly one* of the following conditions is true for
124  * a particular typeinfo struct:
125  *
126  * A) typeclass == NULL
127  *
128  *        This is a returnAddress type.
129  *
130  *        Use TYPEINFO_IS_PRIMITIVE to check for this.
131  *        Use TYPEINFO_RETURNADDRESS to access the pointer in elementclass.
132  *        Don't access other fields of the struct.
133  *
134  * B) typeclass == pseudo_class_Null
135  *
136  *        This is the null-reference type. 
137  *        Use TYPEINFO_IS_NULLTYPE to check for this.
138  *        Don't access other fields of the struct.
139  *
140  * C) typeclass == pseudo_class_New
141  *
142  *        This is an 'uninitialized object' type. elementclass can be
143  *        cast to instruction* and points to the NEW instruction
144  *        responsible for creating this type.
145  *
146  *        Use TYPEINFO_NEWOBJECT_INSTRUCTION to access the pointer in
147  *        elementclass.
148  *        Don't access other fields of the struct.
149  *
150  * D) typeclass == pseudo_class_Arraystub
151  *
152  *        This type is used to represent the result of merging array types
153  *        with incompatible component types. An arraystub allows no access
154  *        to its components (since their type is undefined), but it allows
155  *        operations which act directly on an arbitrary array type (such as
156  *        requesting the array size).
157  *
158  *        NOTE: An array stub does *not* count as an array. It has dimension
159  *              zero.
160  *
161  *        Otherwise like a normal class reference type.
162  *        Don't access other fields of the struct.
163  *
164  * E) typeclass is an array class
165  *
166  *        An array reference.
167  *            elementclass...typeclass of the element type
168  *            dimension......dimension of the array (>=1)
169  *            elementtype....element type (ARRAYTYPE_...)
170  *            merged.........mergedlist of the element type
171  *
172  *        Use TYPEINFO_IS_ARRAY to check for this case.
173  *
174  *        The elementclass may be one of the following:
175  *        1) pseudo_class_Arraystub
176  *        2) an unresolved type
177  *        3) a loaded interface
178  *        4) a loaded (non-pseudo-,non-array-)class != (BOOTSTRAP)java.lang.Object
179  *                Note: `merged` may be used
180  *        5) (BOOTSTRAP)java.lang.Object
181  *                Note: `merged` may be used
182  *
183  *        For the semantics of the merged field in cases 4) and 5) consult the 
184  *        corresponding descriptions with `elementclass` replaced by `typeclass`.
185  *
186  * F) typeclass is an unresolved type (a symbolic class/interface reference)
187  *
188  *        The type has not been resolved yet. (Meaning it corresponds to an
189  *        unloaded class or interface).
190  *        Don't access other fields of the struct.
191  *
192  * G) typeclass is a loaded interface
193  *
194  *        An interface reference type.
195  *        Don't access other fields of the struct.
196  *
197  * H) typeclass is a loaded (non-pseudo-,non-array-)class != (BOOTSTRAP)java.lang.Object
198  *
199  *        A loaded class type.
200  *        All classref_or_classinfos in u.merged.list (if any) are
201  *        loaded subclasses of typeclass (no interfaces, array classes, or
202  *        unresolved types).
203  *        Don't access other fields of the struct.
204  *
205  * I) typeclass is (BOOTSTRAP)java.lang.Object
206  *
207  *        The most general kind of reference type.
208  *        In this case u.merged.count and u.merged.list
209  *        are valid and may be non-zero.
210  *        The classref_or_classinfos in u.merged.list (if any) may be
211  *        classes, interfaces, pseudo classes or unresolved types.
212  *        Don't access other fields of the struct.
213  */
214
215 /* The following algorithm is used to determine if the type described
216  * by this typeinfo struct supports the interface X:  * XXX add MAYBE *
217  *
218  *     1) If typeclass is X or a subinterface of X the answer is "yes".
219  *     2) If typeclass is a (pseudo) class implementing X the answer is "yes".
220  *     3) If typeclass is not an array and u.merged.count>0
221  *        and all classes/interfaces in u.merged.list implement X
222  *        the answer is "yes".
223  *     4) If none of the above is true the answer is "no".
224  */
225
226 /*
227  * CAUTION: The typeinfo structure should be considered opaque outside of
228  *          typeinfo.[ch]. Please use the macros and functions defined here to
229  *          access typeinfo structures!
230  */
231 struct typeinfo {
232         classref_or_classinfo  typeclass;
233         classref_or_classinfo  elementclass; /* valid if dimension>0 */ /* various uses! */
234         typeinfo_mergedlist_t *merged;
235         u1                     dimension;
236         u1                     elementtype;  /* valid if dimension>0           */
237 };
238
239 struct typeinfo_mergedlist {
240         s4                    count;
241         classref_or_classinfo list[1];       /* variable length!                        */
242 };
243
244 /* a type descriptor stores a basic type and the typeinfo                */
245 /* this is used for storing the type of a local variable, and for        */
246 /* storing types in the signature of a method                            */
247
248 struct typedescriptor {
249         typeinfo_t      typeinfo; /* valid if type == TYPE_ADR               */
250         u1              type;     /* basic type (TYPE_INT, ...)              */
251 };
252
253 /****************************************************************************/
254 /* MACROS                                                                   */
255 /****************************************************************************/
256
257 /* NOTE: The TYPEINFO macros take typeinfo *structs*, not pointers as
258  *       arguments.  You have to dereference any pointers.
259  */
260
261 /* typevectors **************************************************************/
262
263 #define TYPEVECTOR_SIZE(size)                                           \
264     ((size) * sizeof(varinfo)) 
265
266 #define DNEW_TYPEVECTOR(size)                                           \
267     ((varinfo *) DMNEW(uint8_t, TYPEVECTOR_SIZE(size)))
268
269 #define DMNEW_TYPEVECTOR(num,size)                                              \
270     ((void *) DMNEW(uint8_t, (num) * TYPEVECTOR_SIZE(size)))
271
272 #define MGET_TYPEVECTOR(array,index,size) \
273     ((varinfo*) (((u1*)(array)) + TYPEVECTOR_SIZE(size) * (index)))
274
275 /* internally used macros ***************************************************/
276
277 /* internal, don't use this explicitly! */
278 #define TYPEINFO_ALLOCMERGED(mergedlist,count)                                  \
279     do {(mergedlist) = (typeinfo_mergedlist_t *) DMNEW(uint8_t, \
280             sizeof(typeinfo_mergedlist_t)                       \
281             + ((count)-1)*sizeof(classinfo*));} while(0)
282
283 /* internal, don't use this explicitly! */
284 #define TYPEINFO_FREEMERGED(mergedlist)
285
286 /* internal, don't use this explicitly! */
287 #define TYPEINFO_FREEMERGED_IF_ANY(mergedlist)
288
289 /* macros for type queries **************************************************/
290
291 #define TYPEINFO_IS_PRIMITIVE(info)                             \
292             ((info).typeclass.any == NULL)
293
294 #define TYPEINFO_IS_REFERENCE(info)                             \
295             ((info).typeclass.any != NULL)
296
297 #define TYPEINFO_IS_NULLTYPE(info)                              \
298             ((info).typeclass.cls == pseudo_class_Null)
299
300 #define TYPEINFO_IS_NEWOBJECT(info)                             \
301             ((info).typeclass.cls == pseudo_class_New)
302
303 #define TYPEINFO_IS_JAVA_LANG_CLASS(info)                       \
304             ((info).typeclass.cls == class_java_lang_Class)
305
306 /* only use this if TYPEINFO_IS_PRIMITIVE returned true! */
307 #define TYPEINFO_RETURNADDRESS(info)                            \
308             ((info).elementclass.any)
309
310 /* only use this if TYPEINFO_IS_NEWOBJECT returned true! */
311 #define TYPEINFO_NEWOBJECT_INSTRUCTION(info)                    \
312                 ((info).elementclass.any)
313
314 /* only use this if TYPEINFO_IS_JAVA_LANG_CLASS returned true! */
315 #define TYPEINFO_JAVA_LANG_CLASS_CLASSREF(info)                 \
316                 ((info).elementclass.ref)
317
318 /* macros for array type queries ********************************************/
319
320 #define TYPEINFO_IS_ARRAY(info)                                 \
321             ( TYPEINFO_IS_REFERENCE(info)                       \
322               && ((info).dimension != 0) )
323
324 #define TYPEINFO_IS_SIMPLE_ARRAY(info)                          \
325             ( ((info).dimension == 1) )
326
327 #define TYPEINFO_IS_ARRAY_ARRAY(info)                           \
328             ( ((info).dimension >= 2) )
329
330 #define TYPEINFO_IS_PRIMITIVE_ARRAY(info,arraytype)             \
331             ( TYPEINFO_IS_SIMPLE_ARRAY(info)                    \
332               && ((info).elementtype == (arraytype)) )
333
334 #define TYPEINFO_IS_OBJECT_ARRAY(info)                          \
335             ( TYPEINFO_IS_SIMPLE_ARRAY(info)                    \
336               && ((info).elementclass.any != NULL) )
337
338 /* assumes that info describes an array type */
339 #define TYPEINFO_IS_ARRAY_OF_REFS_NOCHECK(info)                 \
340             ( ((info).elementclass.any != NULL)                 \
341               || ((info).dimension >= 2) )
342
343 #define TYPEINFO_IS_ARRAY_OF_REFS(info)                         \
344             ( TYPEINFO_IS_ARRAY(info)                           \
345               && TYPEINFO_IS_ARRAY_OF_REFS_NOCHECK(info) )
346
347 #define TYPE_IS_RETURNADDRESS(type,info)                        \
348             ( ((type)==TYPE_RET)                                \
349               && TYPEINFO_IS_PRIMITIVE(info) )
350
351 #define TYPE_IS_REFERENCE(type,info)                            \
352             ( ((type)==TYPE_ADR)                                \
353               && !TYPEINFO_IS_PRIMITIVE(info) )
354
355 #define TYPEDESC_IS_RETURNADDRESS(td)                           \
356             TYPE_IS_RETURNADDRESS((td).type,(td).typeinfo)
357
358 #define TYPEDESC_IS_REFERENCE(td)                               \
359             TYPE_IS_REFERENCE((td).type,(td).typeinfo)
360
361 /* queries allowing the null type ********************************************/
362
363 #define TYPEINFO_MAYBE_ARRAY(info)                              \
364     (TYPEINFO_IS_ARRAY(info) || TYPEINFO_IS_NULLTYPE(info))
365
366 #define TYPEINFO_MAYBE_PRIMITIVE_ARRAY(info,at)                 \
367     (TYPEINFO_IS_PRIMITIVE_ARRAY(info,at) || TYPEINFO_IS_NULLTYPE(info))
368
369 #define TYPEINFO_MAYBE_ARRAY_OF_REFS(info)                      \
370     (TYPEINFO_IS_ARRAY_OF_REFS(info) || TYPEINFO_IS_NULLTYPE(info))
371
372 /* macros for initializing typeinfo structures ******************************/
373
374 #define TYPEINFO_INIT_PRIMITIVE(info)                           \
375          do {(info).typeclass.any = NULL;                       \
376              (info).elementclass.any = NULL;                    \
377              (info).merged = NULL;                              \
378              (info).dimension = 0;                              \
379              (info).elementtype = 0;} while(0)
380
381 #define TYPEINFO_INIT_RETURNADDRESS(info,adr)                   \
382          do {(info).typeclass.any = NULL;                       \
383              (info).elementclass.any = (adr);                   \
384              (info).merged = NULL;                              \
385              (info).dimension = 0;                              \
386              (info).elementtype = 0;} while(0)
387
388 #define TYPEINFO_INIT_NON_ARRAY_CLASSINFO(info,cinfo)   \
389          do {(info).typeclass.cls = (cinfo);            \
390              (info).elementclass.any = NULL;            \
391              (info).merged = NULL;                      \
392              (info).dimension = 0;                      \
393              (info).elementtype = 0;} while(0)
394
395 #define TYPEINFO_INIT_JAVA_LANG_CLASS(info,c)                   \
396          do {(info).typeclass.any = class_java_lang_Class;      \
397              (info).elementclass = (c);                         \
398              (info).merged = NULL;                              \
399              (info).dimension = 0;                              \
400              (info).elementtype = 0;} while(0)
401
402 #define TYPEINFO_INIT_NULLTYPE(info)                            \
403             TYPEINFO_INIT_NON_ARRAY_CLASSINFO(info,pseudo_class_Null)
404
405 #define TYPEINFO_INIT_NEWOBJECT(info,instr)             \
406          do {(info).typeclass.cls = pseudo_class_New;   \
407              (info).elementclass.any = (instr);         \
408              (info).merged = NULL;                      \
409              (info).dimension = 0;                      \
410              (info).elementtype = 0;} while(0)
411
412 #define TYPEINFO_INIT_PRIMITIVE_ARRAY(info,arraytype)                   \
413     typeinfo_init_classinfo(&(info),primitivetype_table[arraytype].arrayclass);
414
415 /* macros for copying types (destinition is not checked or freed) ***********/
416
417 /* TYPEINFO_COPY makes a shallow copy, the merged pointer is simply copied. */
418 #define TYPEINFO_COPY(src,dst)                                  \
419     do {(dst) = (src);} while(0)
420
421 /* TYPEINFO_CLONE makes a deep copy, the merged list (if any) is duplicated
422  * into a newly allocated array.
423  */
424 #define TYPEINFO_CLONE(src,dst)                                 \
425     do {(dst) = (src);                                          \
426         if ((dst).merged) typeinfo_clone(&(src),&(dst));} while(0)
427
428 /****************************************************************************/
429 /* FUNCTIONS                                                                */
430 /****************************************************************************/
431
432 #ifdef __cplusplus
433 extern "C" { 
434 #endif
435
436 /* typevector functions *****************************************************/
437
438 /* element read-only access */
439 bool typevector_checktype(varinfo *set,int index,int type);
440 bool typevector_checkreference(varinfo *set,int index);
441 bool typevector_checkretaddr(varinfo *set,int index);
442
443 /* element write access */
444 void typevector_store(varinfo *set,int index,int type,typeinfo_t *info);
445 void typevector_store_retaddr(varinfo *set,int index,typeinfo_t *info);
446 bool typevector_init_object(varinfo *set,void *ins,classref_or_classinfo initclass,int size);
447
448 /* vector functions */
449 varinfo *typevector_copy(varinfo *src,int size);
450 void typevector_copy_inplace(varinfo *src,varinfo *dst,int size);
451 typecheck_result typevector_merge(methodinfo *m,varinfo *dst,varinfo *y,int size);
452
453 /* inquiry functions (read-only) ********************************************/
454
455 bool typeinfo_is_array(typeinfo_t *info);
456 bool typeinfo_is_primitive_array(typeinfo_t *info,int arraytype);
457 bool typeinfo_is_array_of_refs(typeinfo_t *info);
458
459 typecheck_result typeinfo_is_assignable(typeinfo_t *value,typeinfo_t *dest);
460 typecheck_result typeinfo_is_assignable_to_class(typeinfo_t *value,classref_or_classinfo dest);
461
462 /* initialization functions *************************************************/
463
464 /* RETURN VALUE (bool):
465  *     true.............ok,
466  *     false............an exception has been thrown.
467  *
468  * RETURN VALUE (int):
469  *     >= 0.............ok,
470  *     -1...............an exception has been thrown.
471  */
472 void typeinfo_init_classinfo(typeinfo_t *info,classinfo *c);
473 bool typeinfo_init_class(typeinfo_t *info,classref_or_classinfo c);
474 bool typeinfo_init_component(typeinfo_t *srcarray,typeinfo_t *dst);
475
476 bool typeinfo_init_from_typedesc(typedesc *desc,u1 *type,typeinfo_t *info);
477 bool typeinfos_init_from_methoddesc(methoddesc *desc,u1 *typebuf,
478                                    typeinfo_t *infobuf,
479                                    int buflen,bool twoword,
480                                    u1 *returntype,typeinfo_t *returntypeinfo);
481 bool  typedescriptor_init_from_typedesc(typedescriptor_t *td,
482                                                                             typedesc *desc);
483 bool  typeinfo_init_varinfo_from_typedesc(varinfo *var,
484                                                                             typedesc *desc);
485 int  typedescriptors_init_from_methoddesc(typedescriptor_t *td,
486                                                                                   methoddesc *desc,
487                                                                                   int buflen,bool twoword,int startindex,
488                                                                                   typedescriptor_t *returntype);
489 bool typeinfo_init_varinfos_from_methoddesc(varinfo *vars,
490                                                                                   methoddesc *desc,
491                                                                                   int buflen, int startindex,
492                                                                                   s4 *map,
493                                                                                   typedescriptor_t *returntype);
494
495 void typeinfo_clone(typeinfo_t *src,typeinfo_t *dest);
496
497 /* freeing memory ***********************************************************/
498
499 void typeinfo_free(typeinfo_t *info);
500
501 /* functions for merging types **********************************************/
502
503 typecheck_result typeinfo_merge(methodinfo *m,typeinfo_t *dest,typeinfo_t* y);
504
505 /* debugging helpers ********************************************************/
506
507 #ifdef TYPEINFO_DEBUG
508
509 #include <stdio.h>
510
511 void typeinfo_test();
512 void typeinfo_print_class(FILE *file,classref_or_classinfo c);
513 void typeinfo_print(FILE *file,typeinfo_t *info,int indent);
514 void typeinfo_print_short(FILE *file,typeinfo_t *info);
515 void typeinfo_print_type(FILE *file,int type,typeinfo_t *info);
516 void typedescriptor_print(FILE *file,typedescriptor_t *td);
517 void typevector_print(FILE *file,varinfo *vec,int size);
518
519 #endif /* TYPEINFO_DEBUG */
520
521 #ifdef __cplusplus
522
523 #endif
524
525 #endif /* _TYPEINFO_H */
526
527
528 /*
529  * These are local overrides for various environment variables in Emacs.
530  * Please do not remove this and leave it at the end of the file, where
531  * Emacs will automagically detect them.
532  * ---------------------------------------------------------------------
533  * Local variables:
534  * mode: c
535  * indent-tabs-mode: t
536  * c-basic-offset: 4
537  * tab-width: 4
538  * End:
539  */