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