* configure.ac: New switch for disabling -O2 (--disable-optimizations).
[cacao.git] / src / vm / jit / verify / typecheck-builtins.inc
1 /* src/vm/jit/verify/typecheck-builtins.inc - type checking for ICMD_BUILTIN
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
26 #define ISBUILTIN(v)   (bte->fp == (functionptr) (v))
27
28 {
29         builtintable_entry *bte;
30
31         bte = state->iptr->sx.s23.s3.bte;
32
33         /* XXX this is an ugly if-chain but twisti did not want a function */
34         /* pointer in builtintable_entry for this, so here you go.. ;)     */
35
36         if (ISBUILTIN(BUILTIN_new)) {
37                 dv->type = TYPE_ADR;
38 #if defined(TYPECHECK_TYPEINFERER)
39                 assert(state->iptr[-1].opc == ICMD_ACONST);
40                 typeinfo_init_class(&(dv->typeinfo), state->iptr[-1].sx.val.c);
41 #else
42                 if (state->iptr[-1].opc != ICMD_ACONST)
43                         TYPECHECK_VERIFYERROR_bool("illegal instruction: builtin_new without class");
44                 TYPEINFO_INIT_NEWOBJECT(dv->typeinfo,state->iptr);
45 #endif
46         }
47         else if (ISBUILTIN(BUILTIN_newarray_boolean)) {
48                 TYPECHECK_INT(OP1);
49                 dv->type = TYPE_ADR;
50                 TYPEINFO_INIT_PRIMITIVE_ARRAY(dv->typeinfo,ARRAYTYPE_BOOLEAN);
51         }
52         else if (ISBUILTIN(BUILTIN_newarray_char)) {
53                 TYPECHECK_INT(OP1);
54                 dv->type = TYPE_ADR;
55                 TYPEINFO_INIT_PRIMITIVE_ARRAY(dv->typeinfo,ARRAYTYPE_CHAR);
56         }
57         else if (ISBUILTIN(BUILTIN_newarray_float)) {
58                 TYPECHECK_INT(OP1);
59                 dv->type = TYPE_ADR;
60                 TYPEINFO_INIT_PRIMITIVE_ARRAY(dv->typeinfo,ARRAYTYPE_FLOAT);
61         }
62         else if (ISBUILTIN(BUILTIN_newarray_double)) {
63                 TYPECHECK_INT(OP1);
64                 dv->type = TYPE_ADR;
65                 TYPEINFO_INIT_PRIMITIVE_ARRAY(dv->typeinfo,ARRAYTYPE_DOUBLE);
66         }
67         else if (ISBUILTIN(BUILTIN_newarray_byte)) {
68                 TYPECHECK_INT(OP1);
69                 dv->type = TYPE_ADR;
70                 TYPEINFO_INIT_PRIMITIVE_ARRAY(dv->typeinfo,ARRAYTYPE_BYTE);
71         }
72         else if (ISBUILTIN(BUILTIN_newarray_short)) {
73                 TYPECHECK_INT(OP1);
74                 dv->type = TYPE_ADR;
75                 TYPEINFO_INIT_PRIMITIVE_ARRAY(dv->typeinfo,ARRAYTYPE_SHORT);
76         }
77         else if (ISBUILTIN(BUILTIN_newarray_int)) {
78                 TYPECHECK_INT(OP1);
79                 dv->type = TYPE_ADR;
80                 TYPEINFO_INIT_PRIMITIVE_ARRAY(dv->typeinfo,ARRAYTYPE_INT);
81         }
82         else if (ISBUILTIN(BUILTIN_newarray_long)) {
83                 TYPECHECK_INT(OP1);
84                 dv->type = TYPE_ADR;
85                 TYPEINFO_INIT_PRIMITIVE_ARRAY(dv->typeinfo,ARRAYTYPE_LONG);
86         }
87         else if (ISBUILTIN(BUILTIN_newarray))
88         {
89                 TYPECHECK_INT(OP1);
90                 if (state->iptr[-1].opc != ICMD_ACONST)
91                         TYPECHECK_VERIFYERROR_bool("illegal instruction: builtin_newarray without class");
92                 /* XXX check that it is an array class(ref) */
93                 dv->type = TYPE_ADR;
94                 typeinfo_init_class(&(dv->typeinfo),state->iptr[-1].sx.val.c);
95         }
96         else if (ISBUILTIN(BUILTIN_arrayinstanceof))
97         {
98                 TYPECHECK_ADR(OP1);
99                 if (state->iptr[-1].opc != ICMD_ACONST)
100                         TYPECHECK_VERIFYERROR_bool("illegal instruction: builtin_arrayinstanceof without class");
101                 dv->type = TYPE_INT;
102                 /* XXX check that it is an array class(ref) */
103         }
104         else {
105                 methoddesc *md;
106                 u1 rtype;
107 #if !defined(TYPECHECK_TYPEINFERER)
108                 s4 i;
109 #endif
110 #if defined(TYPECHECK_STACKBASED)
111                 typedescriptor_t *av;
112 #endif
113
114                 /* verify a generic builtin call */
115
116                 TYPECHECK_COUNT(stat_ins_builtin_gen);
117
118                 md = bte->md;
119 #if !defined(TYPECHECK_TYPEINFERER)
120                 i = md->paramcount;
121
122                 /* check the types of the arguments on the stack */
123
124 #if defined(TYPECHECK_STACKBASED)
125                 av = stack - (md->paramslots - 1);
126 #endif
127
128                 for (i--; i >= 0; i--) {
129 #if defined(TYPECHECK_VARIABLESBASED)
130                         varinfo *av = VAR(state->iptr->sx.s23.s2.args[i]);
131 #endif
132
133                         if (av->type != md->paramtypes[i].type) {
134                                 TYPECHECK_VERIFYERROR_bool("parameter type mismatch for builtin method");
135                         }
136
137 #ifdef TYPECHECK_DEBUG
138                         /* generic builtins may only take primitive types and java.lang.Object references */
139                         if (av->type == TYPE_ADR && md->paramtypes[i].classref->name != utf_java_lang_Object) {
140                                 exceptions_throw_internalerror("generic builtin method with non-generic reference parameter");
141                                 return false;
142                         }
143 #endif
144
145 #if defined(TYPECHECK_STACKBASED)
146                         av += (IS_2_WORD_TYPE(av->type)) ? 2 : 1;
147 #endif
148                 }
149 #endif /* !defined(TYPECHECK_TYPEINFERER) */
150
151                 /* set the return type */
152
153                 rtype = md->returntype.type;
154                 if (rtype != TYPE_VOID) {
155                         dv->type = rtype;
156                         if (!typeinfo_init_from_typedesc(&(md->returntype),NULL,&(dv->typeinfo)))
157                                 return false;
158                 }
159         }
160 }
161
162 #undef ISBUILTIN
163
164 /*
165  * These are local overrides for various environment variables in Emacs.
166  * Please do not remove this and leave it at the end of the file, where
167  * Emacs will automagically detect them.
168  * ---------------------------------------------------------------------
169  * Local variables:
170  * mode: c
171  * indent-tabs-mode: t
172  * c-basic-offset: 4
173  * tab-width: 4
174  * End:
175  * vim:noexpandtab:sw=4:ts=4:filetype=c:
176  */