added uninitialized object typecheck
[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 719 2003-12-08 14:26:05Z edwin $
30
31 */
32
33
34 #ifndef _TYPEINFO_H
35 #define _TYPEINFO_H
36
37 #include <stdio.h>
38 #include "global.h"
39
40 /* resolve typedef cycles *****************************************************/
41
42 typedef struct typeinfo typeinfo;
43 typedef struct typeinfo_mergedlist typeinfo_mergedlist;
44
45 /* global variables ***********************************************************/
46
47 /* XXX move this documentation to global.h */
48 /* The following classinfo pointers are used internally by the type system.
49  * Please do not use them directly, use the TYPEINFO_ macros instead.
50  */
51
52 /*
53  * pseudo_class_Arraystub
54  *     (extends Object implements Cloneable, java.io.Serializable)
55  *
56  *     If two arrays of incompatible component types are merged,
57  *     the resulting reference has no accessible components.
58  *     The result does, however, implement the interfaces Cloneable
59  *     and java.io.Serializable. This pseudo class is used internally
60  *     to represent such results. (They are *not* considered arrays!)
61  *
62  * pseudo_class_Null
63  *
64  *     This pseudo class is used internally to represent the
65  *     null type.
66  */
67
68 /* data structures for the type system ****************************************/
69
70 /* The typeinfo structure stores detailed information on reference types.
71  * (stack elements, variables, etc. with type == TYPE_ADR.)
72  * XXX: exclude ReturnAddresses?
73  *
74  * For primitive types either there is no typeinfo allocated or the
75  * typeclass pointer in the typeinfo struct is NULL.
76  *
77  * CAUTION: The typeinfo structure should be considered opaque outside of
78  *          typeinfo.[ch]. Please use the macros and functions defined here to
79  *          access typeinfo structures!
80  */
81
82 /* At all times *exactly one* of the following conditions is true for
83  * a particular typeinfo struct:
84  *
85  * A) typeclass == NULL
86  *
87  *        In this case the other fields of the structure
88  *        are INVALID.
89  *
90  * B) typeclass == pseudo_class_Null
91  *
92  *        XXX
93  *
94  * C) typeclass is an array class
95  *
96  *        XXX
97  *
98  * D) typeclass == pseudo_class_Arraystub
99  *
100  *        XXX
101  *
102  * E) typeclass is an interface
103  *
104  *        XXX
105  *
106  * F) typeclass is a (non-pseudo-)class != java.lang.Object
107  *
108  *        XXX
109  *        All classinfos in u.merged.list (if any) are
110  *        subclasses of typeclass.
111  *
112  * G) typeclass is java.lang.Object
113  *
114  *        XXX
115  *        In this case u.merged.count and u.merged.list
116  *        are valid and may be non-zero.
117  *        The classinfos in u.merged.list (if any) can be
118  *        classes, interfaces or pseudo classes.
119  */
120
121 /* The following algorithm is used to determine if the type described
122  * by this typeinfo struct supports the interface X:
123  *
124  *     1) If typeclass is X or a subinterface of X the answer is "yes".
125  *     2) If typeclass is a (pseudo) class implementing X the answer is "yes".
126  *     3) XXX If typeclass is not an array and u.merged.count>0
127  *        and all classes/interfaces in u.merged.list implement X
128  *        the answer is "yes".
129  *     4) If none of the above is true the answer is "no".
130  */
131
132 /*
133  * CAUTION: The typeinfo structure should be considered opaque outside of
134  *          typeinfo.[ch]. Please use the macros and functions defined here to
135  *          access typeinfo structures!
136  */
137 struct typeinfo {
138         classinfo           *typeclass;
139         classinfo           *elementclass; /* valid if dimension>0 */
140         typeinfo_mergedlist *merged;
141         u1                   dimension;
142         u1                   elementtype;  /* valid if dimension>0 */
143 };
144
145 struct typeinfo_mergedlist {
146         s4         count;
147         classinfo *list[1]; /* variable length! */
148 };
149
150 /****************************************************************************/
151 /* MACROS                                                                   */
152 /****************************************************************************/
153
154 /* NOTE: These macros take typeinfo *structs* not pointers as arguments.
155  *       You have to dereference any pointers.
156  */
157
158 /* internally used macros ***************************************************/
159
160 /* internal, don't use this explicitly! */
161 #define TYPEINFO_ALLOCMERGED(mergedlist,count)                  \
162     do {(mergedlist) = (typeinfo_mergedlist*)dump_alloc(        \
163             sizeof(typeinfo_mergedlist)                         \
164             + ((count)-1)*sizeof(classinfo*));} while(0)
165
166 /* internal, don't use this explicitly! */
167 #define TYPEINFO_FREEMERGED(mergedlist)
168
169 /* internal, don't use this explicitly! */
170 #define TYPEINFO_FREEMERGED_IF_ANY(mergedlist)
171
172 /* macros for type queries **************************************************/
173
174 #define TYPEINFO_IS_PRIMITIVE(info)                             \
175             ((info).typeclass == NULL)
176
177 #define TYPEINFO_IS_REFERENCE(info)                             \
178             ((info).typeclass != NULL)
179
180 #define TYPEINFO_IS_NULLTYPE(info)                              \
181             ((info).typeclass == pseudo_class_Null)
182
183 #define TYPEINFO_IS_NEWOBJECT(info)                             \
184             ((info).typeclass == pseudo_class_New)
185
186 /* only use this if TYPEINFO_IS_NEWOBJECT returned true! */
187 #define TYPEINFO_NEWOBJECT_INSTRUCTION(info)                    \
188             ((void *)(info).elementclass)
189
190 /* macros for array type queries ********************************************/
191
192 #define TYPEINFO_IS_ARRAY(info)                                 \
193             ( TYPEINFO_IS_REFERENCE(info)                       \
194               && ((info).dimension != 0) )
195
196 #define TYPEINFO_IS_SIMPLE_ARRAY(info)                          \
197             ( ((info).dimension == 1) )
198
199 #define TYPEINFO_IS_ARRAY_ARRAY(info)                           \
200             ( ((info).dimension >= 2) )
201
202 #define TYPEINFO_IS_PRIMITIVE_ARRAY(info,arraytype)             \
203             ( TYPEINFO_IS_SIMPLE_ARRAY(info)                    \
204               && ((info).elementtype == (arraytype)) )
205
206 #define TYPEINFO_IS_OBJECT_ARRAY(info)                          \
207             ( TYPEINFO_IS_SIMPLE_ARRAY(info)                    \
208               && ((info).elementclass != NULL) )
209
210 /* assumes that info describes an array type */
211 #define TYPEINFO_IS_ARRAY_OF_REFS_NOCHECK(info)                 \
212             ( ((info).elementclass != NULL)                     \
213               || ((info).dimension >= 2) )
214
215 #define TYPEINFO_IS_ARRAY_OF_REFS(info)                         \
216             ( TYPEINFO_IS_ARRAY(info)                           \
217               && TYPEINFO_IS_ARRAY_OF_REFS_NOCHECK(info) )
218
219 /* queries allowing the null type ********************************************/
220
221 #define TYPEINFO_MAYBE_ARRAY(info)                              \
222     (TYPEINFO_IS_ARRAY(info) || TYPEINFO_IS_NULLTYPE(info))
223
224 #define TYPEINFO_MAYBE_PRIMITIVE_ARRAY(info,at)                 \
225     (TYPEINFO_IS_PRIMITIVE_ARRAY(info,at) || TYPEINFO_IS_NULLTYPE(info))
226
227 #define TYPEINFO_MAYBE_ARRAY_OF_REFS(info)                      \
228     (TYPEINFO_IS_ARRAY_OF_REFS(info) || TYPEINFO_IS_NULLTYPE(info))
229
230 /* macros for initializing typeinfo structures ******************************/
231
232 #define TYPEINFO_INIT_PRIMITIVE(info)                           \
233          do {(info).typeclass = NULL;                           \
234              (info).elementclass = NULL;                        \
235              (info).merged = NULL;                              \
236              (info).dimension = 0;                              \
237              (info).elementtype = 0;} while(0)
238
239 #define TYPEINFO_INIT_NON_ARRAY_CLASSINFO(info,cinfo)   \
240          do {(info).typeclass = (cinfo);                \
241              (info).elementclass = NULL;                \
242              (info).merged = NULL;                      \
243              (info).dimension = 0;                      \
244              (info).elementtype = 0;} while(0)
245
246 #define TYPEINFO_INIT_NULLTYPE(info)                            \
247             TYPEINFO_INIT_CLASSINFO(info,pseudo_class_Null)
248
249 #define TYPEINFO_INIT_NEWOBJECT(info,instr)             \
250          do {(info).typeclass = pseudo_class_New;       \
251              (info).elementclass = (classinfo*) (instr);\
252              (info).merged = NULL;                      \
253              (info).dimension = 0;                      \
254              (info).elementtype = 0;} while(0)
255
256 #define TYPEINFO_INIT_PRIMITIVE_ARRAY(info,arraytype)                   \
257     TYPEINFO_INIT_CLASSINFO(info,primitivetype_table[arraytype].arrayclass);
258
259 #define TYPEINFO_INIT_CLASSINFO(info,cls)                               \
260         do {if (((info).typeclass = (cls))->vftbl->arraydesc) {         \
261                 if ((cls)->vftbl->arraydesc->elementvftbl)              \
262                     (info).elementclass = (cls)->vftbl->arraydesc->elementvftbl->class; \
263                 else                                                    \
264                     (info).elementclass = NULL;                         \
265                 (info).dimension = (cls)->vftbl->arraydesc->dimension;  \
266                 (info).elementtype = (cls)->vftbl->arraydesc->elementtype; \
267             }                                                           \
268             else {                                                      \
269                 (info).elementclass = NULL;                             \
270                 (info).dimension = 0;                                   \
271                 (info).elementtype = 0;                                 \
272             }                                                           \
273             (info).merged = NULL;} while(0)
274
275 #define TYPEINFO_INIT_FROM_FIELDINFO(info,fi)                   \
276             typeinfo_init_from_descriptor(&(info),              \
277                 (fi)->descriptor->text,utf_end((fi)->descriptor));
278
279 /* macros for writing types (destination must have been initialized) ********/
280 /* XXX delete them? */
281 #if 0
282
283 #define TYPEINFO_PUT_NULLTYPE(info)                             \
284     do {(info).typeclass = pseudo_class_Null;} while(0)
285
286 #define TYPEINFO_PUT_NON_ARRAY_CLASSINFO(info,cinfo)            \
287     do {(info).typeclass = (cinfo);} while(0)
288
289 #define TYPEINFO_PUT_CLASSINFO(info,cls)                                \
290     do {if (((info).typeclass = (cls))->vftbl->arraydesc) {             \
291                 if ((cls)->vftbl->arraydesc->elementvftbl)                \
292                     (info).elementclass = (cls)->vftbl->arraydesc->elementvftbl->class; \
293                 (info).dimension = (cls)->vftbl->arraydesc->dimension;    \
294                 (info).elementtype = (cls)->vftbl->arraydesc->elementtype; \
295         }} while(0)
296
297 /* srcarray must be an array (not checked) */
298 #define TYPEINFO_PUT_COMPONENT(srcarray,dst)                    \
299     do {typeinfo_put_component(&(srcarray),&(dst));} while(0)
300
301 #endif
302
303 /* macros for copying types (destinition is not checked or freed) ***********/
304
305 /* TYPEINFO_COPY makes a shallow copy, the merged pointer is simply copied. */
306 #define TYPEINFO_COPY(src,dst)                                  \
307     do {(dst) = (src);} while(0)
308
309 /* TYPEINFO_CLONE makes a deep copy, the merged list (if any) is duplicated
310  * into a newly allocated array.
311  */
312 #define TYPEINFO_CLONE(src,dst)                                 \
313     do {(dst) = (src);                                          \
314         if ((dst).merged) typeinfo_clone(&(src),&(dst));} while(0)
315
316 /****************************************************************************/
317 /* FUNCTIONS                                                                */
318 /****************************************************************************/
319
320 /* inquiry functions (read-only) ********************************************/
321
322 bool typeinfo_is_array(typeinfo *info);
323 bool typeinfo_is_primitive_array(typeinfo *info,int arraytype);
324 bool typeinfo_is_array_of_refs(typeinfo *info);
325
326 bool typeinfo_implements_interface(typeinfo *info,classinfo *interf);
327 bool typeinfo_is_assignable(typeinfo *value,typeinfo *dest);
328
329 /* initialization functions *************************************************/
330
331 void typeinfo_init_from_descriptor(typeinfo *info,char *utf_ptr,char *end_ptr);
332 void typeinfo_init_component(typeinfo *srcarray,typeinfo *dst);
333
334 int  typeinfo_count_method_args(utf *d,bool twoword); /* this not included */
335 void typeinfo_init_from_method_args(utf *desc,u1 *typebuf,
336                                     typeinfo *infobuf,
337                                     int buflen,bool twoword,
338                                     int *returntype,typeinfo *returntypeinfo);
339
340 void typeinfo_clone(typeinfo *src,typeinfo *dest);
341
342 /* functions for the type system ********************************************/
343
344 void typeinfo_free(typeinfo *info);
345
346 bool typeinfo_merge(typeinfo *dest,typeinfo* y);
347
348 /* debugging helpers ********************************************************/
349
350 #ifdef TYPEINFO_DEBUG
351
352 void typeinfo_test();
353 void typeinfo_init_from_fielddescriptor(typeinfo *info,char *desc);
354 void typeinfo_print(FILE *file,typeinfo *info,int indent);
355 void typeinfo_print_short(FILE *file,typeinfo *info);
356 void typeinfo_print_type(FILE *file,int type,typeinfo *info);
357
358 #endif // TYPEINFO_DEBUG
359
360 #endif /* _TYPEINFO_H */
361
362
363 /*
364  * These are local overrides for various environment variables in Emacs.
365  * Please do not remove this and leave it at the end of the file, where
366  * Emacs will automagically detect them.
367  * ---------------------------------------------------------------------
368  * Local variables:
369  * mode: c
370  * indent-tabs-mode: t
371  * c-basic-offset: 4
372  * tab-width: 4
373  * End:
374  */