* src/vmcore/field.h (fieldinfo): Renamed class to clazz.
[cacao.git] / src / vm / jit / intrp / patcher.c
1 /* src/vm/jit/intrp/patcher.c - Interpreter code patching functions
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 #include "config.h"
27 #include "vm/types.h"
28
29 #include "mm/memory.h"
30
31 #include "native/native.h"
32
33 #include "vm/builtin.h"
34 #include "vm/initialize.h"
35
36 #include "vm/jit/asmpart.h"
37 #include "vm/jit/patcher.h"
38
39 #include "vmcore/class.h"
40 #include "vmcore/field.h"
41 #include "vmcore/options.h"
42 #include "vm/resolve.h"
43 #include "vmcore/references.h"
44
45
46 /* patcher_get_putstatic *******************************************************
47
48    Machine code:
49
50 *******************************************************************************/
51
52 bool intrp_patcher_get_putstatic(u1 *sp)
53 {
54         ptrint            *ip;
55         unresolved_field  *uf;
56         fieldinfo         *fi;
57
58         ip = (ptrint *) sp;
59         uf = (unresolved_field *) ip[2];
60
61         /* get the fieldinfo */
62
63         if (!(fi = resolve_field_eager(uf)))
64                 return false;
65
66         /* check if the field's class is initialized */
67
68         if (!(fi->clazz->state & CLASS_INITIALIZED))
69                 if (!initialize_class(fi->clazz))
70                         return false;
71
72         /* patch the field's address */
73
74         ip[1] = (ptrint) &(fi->value);
75
76         return true;
77 }
78
79
80 /* patcher_get_putstatic_clinit ************************************************
81
82    This patcher is used if we already have the resolved fieldinfo but the
83    class of the field has not been initialized, yet.
84    
85    Machine code:
86
87 *******************************************************************************/
88
89 bool intrp_patcher_get_putstatic_clinit(u1 *sp)
90 {
91         ptrint            *ip;
92         fieldinfo         *fi;
93
94         /* get the fieldinfo */
95
96         ip = (ptrint *) sp;
97         fi = (fieldinfo *) ip[2];
98
99         /* check if the field's class is initialized */
100
101         if (!(fi->clazz->state & CLASS_INITIALIZED))
102                 if (!initialize_class(fi->clazz))
103                         return false;
104
105         /* patch the field's address */
106
107         ip[1] = (ptrint) &(fi->value);
108
109         return true;
110 }
111
112
113 /* patcher_get_putfield ********************************************************
114
115    Machine code:
116
117 *******************************************************************************/
118
119 bool intrp_patcher_get_putfield(u1 *sp)
120 {
121         ptrint            *ip;
122         unresolved_field  *uf;
123         fieldinfo         *fi;
124
125         ip = (ptrint *) sp;
126         uf = (unresolved_field *) ip[2];
127
128         /* get the fieldinfo */
129
130         if (!(fi = resolve_field_eager(uf)))
131                 return false;
132
133         /* patch the field's offset */
134
135         ip[1] = fi->offset;
136
137         return true;
138 }
139
140
141 /* patcher_aconst **************************************************************
142
143    Machine code:
144
145 *******************************************************************************/
146
147 bool intrp_patcher_aconst(u1 *sp)
148 {
149         ptrint            *ip;
150         constant_classref *cr;
151         classinfo         *c;
152
153         ip = (ptrint *) sp;
154         cr = (constant_classref *) ip[2];
155         
156         /* get the classinfo */
157
158         if (!(c = resolve_classref_eager(cr)))
159                 return false;
160
161         /* patch the classinfo pointer */
162
163         ip[1] = (ptrint) c;
164
165         return true;
166 }
167
168
169 /* patcher_builtin_multianewarray **********************************************
170
171    Machine code:
172
173 *******************************************************************************/
174
175 bool intrp_patcher_builtin_multianewarray(u1 *sp)
176 {
177         ptrint            *ip;
178         constant_classref *cr;
179         classinfo         *c;
180
181         ip = (ptrint *) sp;
182         cr = (constant_classref *) ip[3];
183
184         /* get the classinfo */
185
186         if (!(c = resolve_classref_eager(cr)))
187                 return false;
188
189         /* patch the classinfo pointer */
190
191         ip[1] = (ptrint) c;
192
193         return true;
194 }
195
196
197 /* patcher_builtin_arraycheckcast **********************************************
198
199    Machine code:
200
201 *******************************************************************************/
202
203 bool intrp_patcher_builtin_arraycheckcast(u1 *sp)
204 {
205         ptrint            *ip;
206         constant_classref *cr;
207         classinfo         *c;
208
209         ip = (ptrint *) sp;
210         cr = (constant_classref *) ip[2];
211
212         /* get the classinfo */
213
214         if (!(c = resolve_classref_eager(cr)))
215                 return false;
216
217         /* patch the classinfo pointer */
218
219         ip[1] = (ptrint) c;
220
221         return true;
222 }
223
224
225 /* patcher_invokestatic_special ************************************************
226
227    Machine code:
228
229 ******************************************************************************/
230
231 bool intrp_patcher_invokestatic_special(u1 *sp)
232 {
233         ptrint            *ip;
234         unresolved_method *um;
235         methodinfo        *m;
236
237         ip = (ptrint *) sp;
238         um = (unresolved_method *) ip[3];
239
240         /* get the fieldinfo */
241
242         if (!(m = resolve_method_eager(um)))
243                 return false;
244
245         /* patch methodinfo and stubroutine */
246
247         ip[3] = (ptrint) m;
248         ip[1] = (ptrint) m->stubroutine;
249
250         return true;
251 }
252
253
254 /* patcher_invokevirtual *******************************************************
255
256    Machine code:
257
258 *******************************************************************************/
259
260 bool intrp_patcher_invokevirtual(u1 *sp)
261 {
262         ptrint            *ip;
263         unresolved_method *um;
264         methodinfo        *m;
265
266         ip = (ptrint *) sp;
267         um = (unresolved_method *) ip[3];
268
269         /* get the fieldinfo */
270
271         if (!(m = resolve_method_eager(um)))
272                 return false;
273
274         /* patch methodinfo and vftbl index */
275
276         ip[3] = (ptrint) m;
277         ip[1] = (OFFSET(vftbl_t, table[0]) + sizeof(methodptr) * m->vftblindex);
278
279         return true;
280 }
281
282
283 /* patcher_invokeinterface *****************************************************
284
285    Machine code:
286
287 *******************************************************************************/
288
289 bool intrp_patcher_invokeinterface(u1 *sp)
290 {
291         ptrint            *ip;
292         unresolved_method *um;
293         methodinfo        *m;
294
295         ip = (ptrint *) sp;
296         um = (unresolved_method *) ip[4];
297
298         /* get the methodinfo */
299
300         if (!(m = resolve_method_eager(um)))
301                 return false;
302
303         /* patch interfacetable index */
304
305         ip[1] = (OFFSET(vftbl_t, interfacetable[0]) -
306                          sizeof(methodptr*) * m->clazz->index);
307
308         /* patch methodinfo and method offset */
309
310         ip[4] = (ptrint) m;
311         ip[2] = (sizeof(methodptr) * (m - m->clazz->methods));
312
313         return true;
314 }
315
316
317 /* patcher_checkcast_instanceof ************************************************
318
319    Machine code:
320
321 *******************************************************************************/
322
323 bool intrp_patcher_checkcast_instanceof(u1 *sp)
324 {
325         ptrint            *ip;
326         constant_classref *cr;
327         classinfo         *c;
328
329         ip = (ptrint *) sp;
330         cr = (constant_classref *) ip[2];
331
332         /* get the classinfo */
333
334         if (!(c = resolve_classref_eager(cr)))
335                 return false;
336
337         /* patch super class pointer */
338
339         ip[1] = (ptrint) c;
340
341         return true;
342 }
343
344
345 /* patcher_resolve_native ******************************************************
346
347    XXX
348
349 *******************************************************************************/
350
351 bool intrp_patcher_resolve_native(u1 *sp)
352 {
353         ptrint      *ip;
354         methodinfo  *m;
355         functionptr  f;
356
357         ip = (ptrint *) sp;
358         m = (methodinfo *) ip[1];
359
360         /* resolve native function */
361
362         if (!(f = native_resolve_function(m)))
363                 return false;
364
365         /* patch native function pointer */
366
367         ip[2] = (ptrint) f;
368
369         return true;
370 }
371
372
373 /*
374  * These are local overrides for various environment variables in Emacs.
375  * Please do not remove this and leave it at the end of the file, where
376  * Emacs will automagically detect them.
377  * ---------------------------------------------------------------------
378  * Local variables:
379  * mode: c
380  * indent-tabs-mode: t
381  * c-basic-offset: 4
382  * tab-width: 4
383  * End:
384  * vim:noexpandtab:sw=4:ts=4:
385  */