CACAO
typecheck-builtins.inc
Go to the documentation of this file.
1 /* src/vm/jit/verify/typecheck-builtins.inc - type checking for ICMD_BUILTIN
2 
3  Copyright (C) 1996-2014
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  dv->typeinfo.init_class(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  dv->typeinfo.init_newobject(state->iptr);
45 #endif
46  }
47  else if (ISBUILTIN(BUILTIN_newarray_boolean)) {
49  dv->type = TYPE_ADR;
50  dv->typeinfo.init_primitive_array(ARRAYTYPE_BOOLEAN);
51  }
52  else if (ISBUILTIN(BUILTIN_newarray_char)) {
54  dv->type = TYPE_ADR;
55  dv->typeinfo.init_primitive_array(ARRAYTYPE_CHAR);
56  }
57  else if (ISBUILTIN(BUILTIN_newarray_float)) {
59  dv->type = TYPE_ADR;
60  dv->typeinfo.init_primitive_array(ARRAYTYPE_FLOAT);
61  }
62  else if (ISBUILTIN(BUILTIN_newarray_double)) {
64  dv->type = TYPE_ADR;
65  dv->typeinfo.init_primitive_array(ARRAYTYPE_DOUBLE);
66  }
67  else if (ISBUILTIN(BUILTIN_newarray_byte)) {
69  dv->type = TYPE_ADR;
70  dv->typeinfo.init_primitive_array(ARRAYTYPE_BYTE);
71  }
72  else if (ISBUILTIN(BUILTIN_newarray_short)) {
74  dv->type = TYPE_ADR;
75  dv->typeinfo.init_primitive_array(ARRAYTYPE_SHORT);
76  }
77  else if (ISBUILTIN(BUILTIN_newarray_int)) {
79  dv->type = TYPE_ADR;
80  dv->typeinfo.init_primitive_array(ARRAYTYPE_INT);
81  }
82  else if (ISBUILTIN(BUILTIN_newarray_long)) {
84  dv->type = TYPE_ADR;
85  dv->typeinfo.init_primitive_array(ARRAYTYPE_LONG);
86  }
87  else if (ISBUILTIN(BUILTIN_newarray))
88  {
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  dv->typeinfo.init_class(state->iptr[-1].sx.val.c);
95  }
96  else if (ISBUILTIN(BUILTIN_arrayinstanceof))
97  {
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  Type 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 != utf8::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 (!dv->typeinfo.init_from_typedesc(&md->returntype, NULL))
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  */
#define TYPECHECK_COUNT(cnt)
methoddesc * md
Definition: builtin.hpp:71
#define BUILTIN_newarray_float
Definition: builtin.hpp:186
#define BUILTIN_newarray_long
Definition: builtin.hpp:196
Type type
Definition: reg.hpp:44
#define BUILTIN_newarray_char
Definition: builtin.hpp:184
#define VAR(i)
Definition: jit.hpp:252
Definition: reg.hpp:43
#define BUILTIN_newarray_byte
Definition: builtin.hpp:190
typedesc paramtypes[1]
Definition: descriptor.hpp:167
#define IS_2_WORD_TYPE(a)
Definition: global.hpp:132
alloc::list< PassInfo::IDTy >::type & stack
#define BUILTIN_newarray_boolean
Definition: builtin.hpp:182
Type
Types used internally by JITTED code.
Definition: global.hpp:117
void exceptions_throw_internalerror(const char *message,...)
Definition: exceptions.cpp:805
#define TYPECHECK_VERIFYERROR_bool(msg)
#define BUILTIN_new
Definition: builtin.hpp:163
MIIterator i
typedesc returntype
Definition: descriptor.hpp:166
int32_t s4
Definition: types.hpp:45
#define BUILTIN_newarray
Definition: builtin.hpp:179
#define BUILTIN_arrayinstanceof
Definition: builtin.hpp:146
#define BUILTIN_newarray_int
Definition: builtin.hpp:194
#define TYPECHECK_ADR(s)
#define BUILTIN_newarray_double
Definition: builtin.hpp:188
#define OP1
Definition: builtin.hpp:60
#define BUILTIN_newarray_short
Definition: builtin.hpp:192
const Utf8String name
Definition: references.hpp:48
constant_classref * classref
Definition: descriptor.hpp:135
#define TYPECHECK_INT(s)