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