-sa bugfix in patcher_builtin_checkarraycast,
[cacao.git] / src / vm / jit / x86_64 / patcher.c
1 /* src/vm/jit/x86_64/patcher.c - x86_64 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 2410 2005-04-28 13:31:55Z twisti $
32
33 */
34
35
36 #include "vm/jit/x86_64/types.h"
37 #include "vm/builtin.h"
38 #include "vm/field.h"
39 #include "vm/initialize.h"
40 #include "vm/options.h"
41 #include "vm/references.h"
42 #include "vm/jit/helper.h"
43 #include "vm/exceptions.h"
44
45
46 /* patcher_get_putstatic *******************************************************
47
48    Machine code:
49
50    <patched call position>
51    4d 8b 15 86 fe ff ff             mov    -378(%rip),%r10
52
53 *******************************************************************************/
54
55 bool patcher_get_putstatic(u1 *sp)
56 {
57         u1               *ra;
58         u8                mcode;
59         unresolved_field *uf;
60         fieldinfo        *fi;
61         s4                offset;
62         void             *beginJavaStack;
63         /* get stuff from the stack */
64
65         ra    = (u1 *)               *((ptrint *) (sp + 2 * 8));
66         mcode =                      *((u8 *)     (sp + 1 * 8));
67         uf    = (unresolved_field *) *((ptrint *) (sp + 0 * 8));
68         beginJavaStack=              (void*)(sp+2*8);
69         /* calculate and set the new return address */
70
71         ra = ra - 5;
72         *((ptrint *) (sp + 2 * 8)) = (ptrint) ra;
73
74         *dontfillinexceptionstacktrace=true;
75         /* get the fieldinfo */
76         if (!(fi = helper_resolve_fieldinfo(uf)))
77         {
78                 *dontfillinexceptionstacktrace=false;
79                 return false;
80         }
81
82         /* check if the field's class is initialized */
83         *dontfillinexceptionstacktrace=false;
84         if (!fi->class->initialized) {
85                 bool init;
86                 {
87                         /*struct native_stackframeinfo {
88                                 void *oldThreadspecificHeadValue;
89                                 void **addressOfThreadspecificHead;
90                                 methodinfo *method;
91                                 void *beginOfJavaStackframe; only used if != 0
92                                 void *returnToFromNative;
93                         }*/
94                         /* more or less the same as the above sfi setup is done in the assembler code by the prepare/remove functions*/
95                         native_stackframeinfo sfi;
96                         sfi.returnToFromNative=(void*)ra;
97                         sfi.beginOfJavaStackframe=beginJavaStack;
98                         sfi.method=0; /*internal*/
99                         sfi.addressOfThreadspecificHead=builtin_asm_get_stackframeinfo();
100                         sfi.oldThreadspecificHeadValue=*(sfi.addressOfThreadspecificHead);
101                         *(sfi.addressOfThreadspecificHead)=&sfi;
102
103                         init=initialize_class(fi->class);
104
105                         *(sfi.addressOfThreadspecificHead)=sfi.oldThreadspecificHeadValue;
106                 }
107                 if (!init)
108                 {
109                         return false;
110                 }
111         }
112
113         *dontfillinexceptionstacktrace=false;
114
115         /* patch back original code */
116
117         *((u8 *) ra) = mcode;
118
119         /* if we show disassembly, we have to skip the nop's */
120
121         if (showdisassemble)
122                 ra = ra + 5;
123
124         /* get RIP offset from machine instruction */
125
126         offset = *((u4 *) (ra + 3));
127
128         /* patch the field value's address (+ 7: is the size of the RIP move) */
129
130         *((ptrint *) (ra + 7 + offset)) = (ptrint) &(fi->value);
131
132         return true;
133 }
134
135
136 /* patcher_get_putfield ********************************************************
137
138    Machine code:
139
140    <patched call position>
141    45 8b 8f 00 00 00 00             mov    0x0(%r15),%r9d
142
143 *******************************************************************************/
144
145 bool patcher_get_putfield(u1 *sp)
146 {
147         u1               *ra;
148         u8                mcode;
149         unresolved_field *uf;
150         fieldinfo        *fi;
151
152         /* get stuff from the stack */
153
154         ra    = (u1 *)               *((ptrint *) (sp + 2 * 8));
155         mcode =                      *((u8 *)     (sp + 1 * 8));
156         uf    = (unresolved_field *) *((ptrint *) (sp + 0 * 8));
157
158         /* calculate and set the new return address */
159
160         ra = ra - 5;
161         *((ptrint *) (sp + 2 * 8)) = (ptrint) ra;
162
163         *dontfillinexceptionstacktrace=true;
164
165
166         /* get the fieldinfo */
167
168         if (!(fi = helper_resolve_fieldinfo(uf)))
169         {
170                 *dontfillinexceptionstacktrace=false;
171                 return false;
172         }
173
174         /* patch back original code */
175
176         *((u8 *) ra) = mcode;
177
178         /* if we show disassembly, we have to skip the nop's */
179
180         if (showdisassemble)
181                 ra = ra + 5;
182
183         /* patch the field's offset: we check for the field type, because the     */
184         /* instructions have different lengths                                    */
185
186         if (IS_FLT_DBL_TYPE(fi->type)) {
187                 *((u4 *) (ra + 5)) = (u4) (fi->offset);
188
189         } else {
190                 u1 byte;
191
192                 /* check for special case: %rsp or %r12 as base register */
193
194                 byte = *(ra + 3);
195
196                 if (byte == 0x24)
197                         *((u4 *) (ra + 4)) = (u4) (fi->offset);
198                 else
199                         *((u4 *) (ra + 3)) = (u4) (fi->offset);
200         }
201
202         *dontfillinexceptionstacktrace=false;
203         return true;
204 }
205
206
207 /* patcher_builtin_new *********************************************************
208
209    Machine code:
210
211    48 bf a0 f0 92 00 00 00 00 00    mov    $0x92f0a0,%rdi
212    <patched call position>
213    48 b8 00 00 00 00 00 00 00 00    mov    $0x0,%rax
214    48 ff d0                         callq  *%rax
215
216 *******************************************************************************/
217
218 bool patcher_builtin_new(u1 *sp)
219 {
220         u1                *ra;
221         u8                 mcode;
222         constant_classref *cr;
223         classinfo         *c;
224
225         /* get stuff from the stack */
226
227         ra    = (u1 *)                *((ptrint *) (sp + 2 * 8));
228         mcode =                       *((u8 *)     (sp + 1 * 8));
229         cr    = (constant_classref *) *((ptrint *) (sp + 0 * 8));
230
231         /* calculate and set the new return address */
232
233         ra = ra - (10 + 5);
234         *((ptrint *) (sp + 2 * 8)) = (ptrint) ra;
235
236         *dontfillinexceptionstacktrace=true;
237
238         /* get the classinfo */
239
240         if (!(c = helper_resolve_classinfo(cr)))
241         {
242                 *dontfillinexceptionstacktrace=false;
243                 return false;
244         }
245
246         /* patch back original code */
247
248         *((u8 *) (ra + 10)) = mcode;
249
250         /* patch the classinfo pointer */
251
252         *((ptrint *) (ra + 2)) = (ptrint) c;
253
254         /* if we show disassembly, we have to skip the nop's */
255
256         if (showdisassemble)
257                 ra = ra + 5;
258
259         /* patch new function address */
260
261         *((ptrint *) (ra + 10 + 2)) = (ptrint) BUILTIN_new;
262
263         *dontfillinexceptionstacktrace=false;
264         return true;
265 }
266
267
268 /* patcher_builtin_newarray ****************************************************
269
270    Machine code:
271
272    48 be 88 13 9b 00 00 00 00 00    mov    $0x9b1388,%rsi
273    <patched call position>
274    48 b8 00 00 00 00 00 00 00 00    mov    $0x0,%rax
275    48 ff d0                         callq  *%rax
276
277 *******************************************************************************/
278
279 bool patcher_builtin_newarray(u1 *sp)
280 {
281         u1                *ra;
282         u8                 mcode;
283         constant_classref *cr;
284         classinfo         *c;
285
286         /* get stuff from the stack */
287
288         ra    = (u1 *)                *((ptrint *) (sp + 2 * 8));
289         mcode =                       *((u8 *)     (sp + 1 * 8));
290         cr    = (constant_classref *) *((ptrint *) (sp + 0 * 8));
291
292         /* calculate and set the new return address */
293
294         ra = ra - (10 + 5);
295         *((ptrint *) (sp + 2 * 8)) = (ptrint) ra;
296
297         *dontfillinexceptionstacktrace=true;
298
299         /* get the classinfo */
300
301         if (!(c = helper_resolve_classinfo(cr))) {
302                 *dontfillinexceptionstacktrace=false;
303                 return false;
304         }
305
306         /* patch back original code */
307
308         *((u8 *) (ra + 10)) = mcode;
309
310         /* patch the class' vftbl pointer */
311
312         *((ptrint *) (ra + 2)) = (ptrint) c->vftbl;
313
314         /* if we show disassembly, we have to skip the nop's */
315
316         if (showdisassemble)
317                 ra = ra + 5;
318
319         /* patch new function address */
320
321         *((ptrint *) (ra + 10 + 2)) = (ptrint) BUILTIN_newarray;
322
323         *dontfillinexceptionstacktrace=false;
324         return true;
325 }
326
327
328 /* patcher_builtin_multianewarray **********************************************
329
330    Machine code:
331
332    <patched call position>
333    48 bf 02 00 00 00 00 00 00 00    mov    $0x2,%rdi
334    48 be 30 40 b2 00 00 00 00 00    mov    $0xb24030,%rsi
335    48 89 e2                         mov    %rsp,%rdx
336    48 b8 7c 96 4b 00 00 00 00 00    mov    $0x4b967c,%rax
337    48 ff d0                         callq  *%rax
338
339 *******************************************************************************/
340
341 bool patcher_builtin_multianewarray(u1 *sp)
342 {
343         u1                *ra;
344         u8                 mcode;
345         constant_classref *cr;
346         classinfo         *c;
347
348         /* get stuff from the stack */
349
350         ra    = (u1 *)                *((ptrint *) (sp + 2 * 8));
351         mcode =                       *((u8 *)     (sp + 1 * 8));
352         cr    = (constant_classref *) *((ptrint *) (sp + 0 * 8));
353
354         /* calculate and set the new return address */
355
356         ra = ra - 5;
357         *((ptrint *) (sp + 2 * 8)) = (ptrint) ra;
358
359         *dontfillinexceptionstacktrace=true;
360
361         /* get the classinfo */
362
363         if (!(c = helper_resolve_classinfo(cr))) {
364                 *dontfillinexceptionstacktrace=false;
365                 return false;
366         }
367
368         /* patch back original code */
369
370         *((u8 *) ra) = mcode;
371
372         /* if we show disassembly, we have to skip the nop's */
373
374         if (showdisassemble)
375                 ra = ra + 5;
376
377         /* patch the class' vftbl pointer */
378
379         *((ptrint *) (ra + 10 + 2)) = (ptrint) c->vftbl;
380
381         /* patch new function address */
382
383         *((ptrint *) (ra + 10 + 10 + 3 + 2)) = (ptrint) BUILTIN_multianewarray;
384
385         *dontfillinexceptionstacktrace=false;
386         return true;
387 }
388
389
390 /* patcher_builtin_checkarraycast **********************************************
391
392    Machine code:
393
394    48 be b8 3f b2 00 00 00 00 00    mov    $0xb23fb8,%rsi
395    <patched call position>
396    48 b8 00 00 00 00 00 00 00 00    mov    $0x0,%rax
397    48 ff d0                         callq  *%rax
398
399 *******************************************************************************/
400
401 bool patcher_builtin_checkarraycast(u1 *sp)
402 {
403         u1                *ra;
404         u8                 mcode;
405         constant_classref *cr;
406         classinfo         *c;
407
408         /* get stuff from the stack */
409
410         ra    = (u1 *)                *((ptrint *) (sp + 2 * 8));
411         mcode =                       *((u8 *)     (sp + 1 * 8));
412         cr    = (constant_classref *) *((ptrint *) (sp + 0 * 8));
413
414         /* calculate and set the new return address */
415
416         ra = ra - (10 + 5);
417         *((ptrint *) (sp + 2 * 8)) = (ptrint) ra;
418
419         *dontfillinexceptionstacktrace=true;
420
421         /* get the classinfo */
422
423         if (!(c = helper_resolve_classinfo(cr))) {
424                 *dontfillinexceptionstacktrace=false;
425                 return false;
426         }
427
428         /* patch back original code */
429
430         *((u8 *) (ra + 10)) = mcode;
431
432         /* patch the class' vftbl pointer */
433
434         *((ptrint *) (ra + 2)) = (ptrint) c->vftbl;
435
436         /* if we show disassembly, we have to skip the nop's */
437
438         if (showdisassemble)
439                 ra = ra + 5;
440
441         /* patch new function address */
442
443         *((ptrint *) (ra + 10 + 2)) = (ptrint) BUILTIN_checkarraycast;
444
445         *dontfillinexceptionstacktrace=false;
446         return true;
447 }
448
449
450 /* patcher_builtin_arrayinstanceof *********************************************
451
452    Machine code:
453
454    48 be 30 3c b2 00 00 00 00 00    mov    $0xb23c30,%rsi
455    <patched call position>
456    48 b8 00 00 00 00 00 00 00 00    mov    $0x0,%rax
457    48 ff d0                         callq  *%rax
458
459 *******************************************************************************/
460
461 bool patcher_builtin_arrayinstanceof(u1 *sp)
462 {
463         u1                *ra;
464         u8                 mcode;
465         constant_classref *cr;
466         classinfo         *c;
467
468         /* get stuff from the stack */
469
470         ra    = (u1 *)                *((ptrint *) (sp + 2 * 8));
471         mcode =                       *((u8 *)     (sp + 1 * 8));
472         cr    = (constant_classref *) *((ptrint *) (sp + 0 * 8));
473
474         /* calculate and set the new return address */
475
476         ra = ra - (10 + 5);
477         *((ptrint *) (sp + 2 * 8)) = (ptrint) ra;
478
479         *dontfillinexceptionstacktrace=true;
480
481         /* get the classinfo */
482
483         if (!(c = helper_resolve_classinfo(cr))) {
484                 *dontfillinexceptionstacktrace=false;
485                 return false;
486         }
487
488         /* patch back original code */
489
490         *((u8 *) (ra + 10)) = mcode;
491
492         /* patch the class' vftbl pointer */
493
494         *((ptrint *) (ra + 2)) = (ptrint) c->vftbl;
495
496         /* if we show disassembly, we have to skip the nop's */
497
498         if (showdisassemble)
499                 ra = ra + 5;
500
501         /* patch new function address */
502
503         *((ptrint *) (ra + 10 + 2)) = (ptrint) BUILTIN_arrayinstanceof;
504
505         *dontfillinexceptionstacktrace=false;
506         return true;
507 }
508
509
510 /* patcher_invokestatic_special ************************************************
511
512    XXX
513
514 *******************************************************************************/
515
516 bool patcher_invokestatic_special(u1 *sp)
517 {
518         u1                *ra;
519         u8                 mcode;
520         unresolved_method *um;
521         methodinfo        *m;
522
523         /* get stuff from the stack */
524
525         ra    = (u1 *)                *((ptrint *) (sp + 2 * 8));
526         mcode =                       *((u8 *)     (sp + 1 * 8));
527         um    = (unresolved_method *) *((ptrint *) (sp + 0 * 8));
528
529         /* calculate and set the new return address */
530
531         ra = ra - 5;
532         *((ptrint *) (sp + 2 * 8)) = (ptrint) ra;
533
534         *dontfillinexceptionstacktrace=true;
535
536
537         /* get the fieldinfo */
538
539         if (!(m = helper_resolve_methodinfo(um)))
540         {
541                 *dontfillinexceptionstacktrace=false;
542                 return false;
543         }
544         /* patch back original code */
545
546         *((u8 *) ra) = mcode;
547
548         /* if we show disassembly, we have to skip the nop's */
549
550         if (showdisassemble)
551                 ra = ra + 5;
552
553         /* patch stubroutine */
554
555         *((ptrint *) (ra + 2)) = (ptrint) m->stubroutine;
556
557         *dontfillinexceptionstacktrace=false;
558         return true;
559 }
560
561
562 /* patcher_invokevirtual *******************************************************
563
564    XXX
565
566 *******************************************************************************/
567
568 bool patcher_invokevirtual(u1 *sp)
569 {
570         u1                *ra;
571         u8                 mcode;
572         unresolved_method *um;
573         methodinfo        *m;
574
575         /* get stuff from the stack */
576
577         ra    = (u1 *)                *((ptrint *) (sp + 2 * 8));
578         mcode =                       *((u8 *)     (sp + 1 * 8));
579         um    = (unresolved_method *) *((ptrint *) (sp + 0 * 8));
580
581         /* calculate and set the new return address */
582
583         ra = ra - 5;
584         *((ptrint *) (sp + 2 * 8)) = (ptrint) ra;
585
586         *dontfillinexceptionstacktrace=true;
587
588         /* get the fieldinfo */
589
590         if (!(m = helper_resolve_methodinfo(um)))
591         {
592                 *dontfillinexceptionstacktrace=false;
593                 return false;
594         }
595
596         /* patch back original code */
597
598         *((u8 *) ra) = mcode;
599
600         /* if we show disassembly, we have to skip the nop's */
601
602         if (showdisassemble)
603                 ra = ra + 5;
604
605         /* patch vftbl index */
606
607         *((s4 *) (ra + 3 + 3)) = (s4) (OFFSET(vftbl_t, table[0]) +
608                                                                    sizeof(methodptr) * m->vftblindex);
609
610         *dontfillinexceptionstacktrace=false;
611         return true;
612 }
613
614
615 /* patcher_invokeinterface *****************************************************
616
617    XXX
618
619 *******************************************************************************/
620
621 bool patcher_invokeinterface(u1 *sp)
622 {
623         u1                *ra;
624         u8                 mcode;
625         unresolved_method *um;
626         methodinfo        *m;
627
628         /* get stuff from the stack */
629
630         ra    = (u1 *)                *((ptrint *) (sp + 2 * 8));
631         mcode =                       *((u8 *)     (sp + 1 * 8));
632         um    = (unresolved_method *) *((ptrint *) (sp + 0 * 8));
633
634         /* calculate and set the new return address */
635
636         ra = ra - 5;
637         *((ptrint *) (sp + 2 * 8)) = (ptrint) ra;
638
639         *dontfillinexceptionstacktrace=true;
640
641         /* get the fieldinfo */
642
643         if (!(m = helper_resolve_methodinfo(um)))
644         {
645                 *dontfillinexceptionstacktrace=false;
646                 return false;
647         }
648
649         /* patch back original code */
650
651         *((u8 *) ra) = mcode;
652
653         /* if we show disassembly, we have to skip the nop's */
654
655         if (showdisassemble)
656                 ra = ra + 5;
657
658         /* patch interfacetable index */
659
660         *((s4 *) (ra + 3 + 3)) = (s4) (OFFSET(vftbl_t, interfacetable[0]) -
661                                                                    sizeof(methodptr) * m->class->index);
662
663         /* patch method offset */
664
665         *((s4 *) (ra + 3 + 7 + 3)) =
666                 (s4) (sizeof(methodptr) * (m - m->class->methods));
667
668         *dontfillinexceptionstacktrace=false;
669         return true;
670 }
671
672
673 /* patcher_checkcast_instanceof_flags ******************************************
674
675    XXX
676
677 *******************************************************************************/
678
679 bool patcher_checkcast_instanceof_flags(u1 *sp)
680 {
681         u1                *ra;
682         u8                 mcode;
683         constant_classref *cr;
684         classinfo         *c;
685
686         /* get stuff from the stack */
687
688         ra    = (u1 *)                *((ptrint *) (sp + 2 * 8));
689         mcode =                       *((u8 *)     (sp + 1 * 8));
690         cr    = (constant_classref *) *((ptrint *) (sp + 0 * 8));
691
692         /* calculate and set the new return address */
693
694         ra = ra - 5;
695         *((ptrint *) (sp + 2 * 8)) = (ptrint) ra;
696
697         *dontfillinexceptionstacktrace=true;
698
699         /* get the fieldinfo */
700
701         if (!(c = helper_resolve_classinfo(cr))) {
702                 *dontfillinexceptionstacktrace=false;
703                 return false;
704         }
705
706         /* patch back original code */
707
708         *((u8 *) ra) = mcode;
709
710         /* if we show disassembly, we have to skip the nop's */
711
712         if (showdisassemble)
713                 ra = ra + 5;
714
715         /* patch class flags */
716
717         *((s4 *) (ra + 2)) = (s4) c->flags;
718
719         *dontfillinexceptionstacktrace=false;
720         return true;
721 }
722
723
724 /* patcher_checkcast_instanceof_interface **************************************
725
726    XXX
727
728 *******************************************************************************/
729
730 bool patcher_checkcast_instanceof_interface(u1 *sp)
731 {
732         u1                *ra;
733         u8                 mcode;
734         constant_classref *cr;
735         classinfo         *c;
736
737         /* get stuff from the stack */
738
739         ra    = (u1 *)                *((ptrint *) (sp + 2 * 8));
740         mcode =                       *((u8 *)     (sp + 1 * 8));
741         cr    = (constant_classref *) *((ptrint *) (sp + 0 * 8));
742
743         /* calculate and set the new return address */
744
745         ra = ra - 5;
746         *((ptrint *) (sp + 2 * 8)) = (ptrint) ra;
747
748         *dontfillinexceptionstacktrace=true;
749
750         /* get the fieldinfo */
751
752         if (!(c = helper_resolve_classinfo(cr))) {
753                 *dontfillinexceptionstacktrace=false;
754                 return false;
755         }
756
757         /* patch back original code */
758
759         *((u8 *) ra) = mcode;
760
761         /* if we show disassembly, we have to skip the nop's */
762
763         if (showdisassemble)
764                 ra = ra + 5;
765
766         /* patch super class index */
767
768         *((s4 *) (ra + 7 + 3)) = (s4) c->index;
769
770         *((s4 *) (ra + 7 + 7 + 3 + 6 + 3)) =
771                 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
772                           c->index * sizeof(methodptr*));
773
774         *dontfillinexceptionstacktrace=false;
775         return true;
776 }
777
778
779 /* patcher_checkcast_class *****************************************************
780
781    XXX
782
783 *******************************************************************************/
784
785 bool patcher_checkcast_class(u1 *sp)
786 {
787         u1                *ra;
788         u8                 mcode;
789         constant_classref *cr;
790         classinfo         *c;
791
792         /* get stuff from the stack */
793
794         ra    = (u1 *)                *((ptrint *) (sp + 2 * 8));
795         mcode =                       *((u8 *)     (sp + 1 * 8));
796         cr    = (constant_classref *) *((ptrint *) (sp + 0 * 8));
797
798         /* calculate and set the new return address */
799
800         ra = ra - 5;
801         *((ptrint *) (sp + 2 * 8)) = (ptrint) ra;
802
803         *dontfillinexceptionstacktrace=true;
804
805         /* get the fieldinfo */
806
807         if (!(c = helper_resolve_classinfo(cr))) {
808                 *dontfillinexceptionstacktrace=false;
809                 return false;
810         }
811
812         /* patch back original code */
813
814         *((u8 *) ra) = mcode;
815
816         /* if we show disassembly, we have to skip the nop's */
817
818         if (showdisassemble)
819                 ra = ra + 5;
820
821         /* patch super class' vftbl */
822
823         *((ptrint *) (ra + 2)) = (ptrint) c->vftbl;
824         *((ptrint *) (ra + 10 + 7 + 7 + 3 + 2)) = (ptrint) c->vftbl;
825
826         *dontfillinexceptionstacktrace=false;
827         return true;
828 }
829
830
831 /* patcher_instanceof_class ****************************************************
832
833    XXX
834
835 *******************************************************************************/
836
837 bool patcher_instanceof_class(u1 *sp)
838 {
839         u1                *ra;
840         u8                 mcode;
841         constant_classref *cr;
842         classinfo         *c;
843
844         /* get stuff from the stack */
845
846         ra    = (u1 *)                *((ptrint *) (sp + 2 * 8));
847         mcode =                       *((u8 *)     (sp + 1 * 8));
848         cr    = (constant_classref *) *((ptrint *) (sp + 0 * 8));
849
850         /* calculate and set the new return address */
851
852         ra = ra - 5;
853         *((ptrint *) (sp + 2 * 8)) = (ptrint) ra;
854
855         *dontfillinexceptionstacktrace=true;
856
857         /* get the fieldinfo */
858
859         if (!(c = helper_resolve_classinfo(cr))) {
860                 *dontfillinexceptionstacktrace=false;
861                 return false;
862         }
863
864         /* patch back original code */
865
866         *((u8 *) ra) = mcode;
867
868         /* if we show disassembly, we have to skip the nop's */
869
870         if (showdisassemble)
871                 ra = ra + 5;
872
873         /* patch super class' vftbl */
874
875         *((ptrint *) (ra + 2)) = (ptrint) c->vftbl;
876
877         *dontfillinexceptionstacktrace=false;
878         return true;
879 }
880
881
882 /* patcher_clinit **************************************************************
883
884    XXX
885
886 *******************************************************************************/
887
888 bool patcher_clinit(u1 *sp)
889 {
890         u1        *ra;
891         u8         mcode;
892         classinfo *c;
893         void      *beginJavaStack;
894
895         /* get stuff from the stack */
896
897         ra    = (u1 *)        *((ptrint *) (sp + 2 * 8));
898         mcode =               *((u8 *)     (sp + 1 * 8));
899         c     = (classinfo *) *((ptrint *) (sp + 0 * 8));
900         beginJavaStack =      (void*) (sp+2*8);
901
902         /*printf("beginJavaStack: %p, ra %p\n",beginJavaStack,ra);*/
903         /* calculate and set the new return address */
904
905         ra = ra - 5;
906         *((ptrint *) (sp + 2 * 8)) = (ptrint) ra;
907
908         /* check if the class is initialized */
909
910         if (!c->initialized) {
911                 bool init;
912                 {
913                         /*struct native_stackframeinfo {
914                                 void *oldThreadspecificHeadValue;
915                                 void **addressOfThreadspecificHead;
916                                 methodinfo *method;
917                                 void *beginOfJavaStackframe; only used if != 0
918                                 void *returnToFromNative;
919                         }*/
920                         /* more or less the same as the above sfi setup is done in the assembler code by the prepare/remove functions*/
921                         native_stackframeinfo sfi;
922                         sfi.returnToFromNative=(void*)ra;
923                         sfi.beginOfJavaStackframe=beginJavaStack;
924                         sfi.method=0; /*internal*/
925                         sfi.addressOfThreadspecificHead=builtin_asm_get_stackframeinfo();
926                         sfi.oldThreadspecificHeadValue=*(sfi.addressOfThreadspecificHead);
927                         *(sfi.addressOfThreadspecificHead)=&sfi;
928
929                         init=initialize_class(c);
930
931                         *(sfi.addressOfThreadspecificHead)=sfi.oldThreadspecificHeadValue;
932                 }
933                 if (!init)
934                 {
935                         return false;
936                 }
937         }
938
939         /* patch back original code */
940
941         *((u8 *) ra) = mcode;
942
943         return true;
944 }
945
946
947 /*
948  * These are local overrides for various environment variables in Emacs.
949  * Please do not remove this and leave it at the end of the file, where
950  * Emacs will automagically detect them.
951  * ---------------------------------------------------------------------
952  * Local variables:
953  * mode: c
954  * indent-tabs-mode: t
955  * c-basic-offset: 4
956  * tab-width: 4
957  * End:
958  * vim:noexpandtab:sw=4:ts=4:
959  */