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