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