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