2 \ JVM instruction specs
4 \ This file contains primitive specifications in the following format:
6 \ name ( stack effect ) [ number ]
12 \ Note: Fields in brackets are optional. Word specifications have to
13 \ be separated by at least one empty line
15 \ Both name and stack items (in the stack effect) must
16 \ conform to the C identifier syntax or the C compiler will complain.
17 \ The branch field can be one of "branch", "cond", "indirect", or empty.
19 \ These specifications are automatically translated into C-code for the
20 \ interpreter and into some other files. I hope that your C compiler has
21 \ decent optimization, otherwise the automatically generated code will
22 \ be somewhat slow. The Forth version of the code is included for manual
23 \ compilers, so they will need to compile only the important words.
25 \ Note that stack pointer adjustment is performed according to stack
26 \ effect by automatically generated code and NEXT is automatically
27 \ appended to the C code. Also, you can use the names in the stack
28 \ effect in the C code. Stack access is automatic. One exception: if
29 \ your code does not fall through, the results are not stored into the
30 \ stack. Use different names on both sides of the '--', if you change a
31 \ value (some stores to the stack are optimized away).
34 \E stack data-stack sp Cell
36 \E s" u4" single data-stack type-prefix ui
37 \E s" Cell" single data-stack type-prefix v
38 \E s" s4" single data-stack type-prefix b \ byte
39 \E s" s4" single data-stack type-prefix s \ short
40 \E s" s4" single data-stack type-prefix i
41 \E s" s8" double data-stack type-prefix l
42 \E s" float" single data-stack type-prefix f
43 \E s" double" double data-stack type-prefix d
45 \ we use a lot of types for the former "a" (address) type; this gives
46 \ better typechecking in the C code, and allows better output from the
47 \ disassembler and the tracer.
49 \E s" java_objectheader *" single data-stack type-prefix aRef
50 \E s" java_arrayheader *" single data-stack type-prefix aArray
51 \E s" Inst **" single data-stack type-prefix aaTarget
52 \E s" classinfo *" single data-stack type-prefix aClass
53 \E s" constant_classref *" single data-stack type-prefix acr
54 \E s" u1 *" single data-stack type-prefix addr
55 \E s" functionptr" single data-stack type-prefix af
56 \E s" methodinfo *" single data-stack type-prefix am
57 \E s" Cell *" single data-stack type-prefix acell
58 \E s" Inst *" single data-stack type-prefix ainst
59 \E s" unresolved_field *" single data-stack type-prefix auf
60 \E s" unresolved_method *" single data-stack type-prefix aum
61 \E s" vftbl_t *" single data-stack type-prefix avftbl
62 \E inst-stream stack-prefix #
64 \ The stack variables have the following types:
78 \ Starting a name with # indicates an inline argument instead of a stack
79 \ argument; the rest of the name matches as usual.
83 \ How does prims2x know the length of each instruction,
84 \ where the instruction has immediate operands. We need
85 \ some way to communicate this or compute it.
87 \ Some instructions don't care about the type of the
88 \ values that they work with. For example, POP doesn't
89 \ care what type the value on the top of the stack is.
90 \ We need to communicate this.
91 \ I'll add a type v (for void, or variable, whichever you
92 \ prefer) which just means there's one element of the normal
93 \ size on the stack, and we don't care what its type is.
97 \ Define the following macros before including this file.
99 \ # define instr(name,opcode,label,len,syntax,body)
100 \ # define undef(name,opcode,label,len,syntax,body)
101 \ # define custm(name,opcode,label,len,syntax,body)
104 \ To avoid race conditions, rewriting proceeds as follows:
105 \ 1) the needed operands are fetched from the orignal byte code
106 \ 2) the new operands are written
107 \ 3) the new operator is written
108 \ 4) the quick-version of the instruction is executed.
110 \ Note: the byte code remains unchanged.
116 \E register IPTOS Cell
117 \E register spTOS Cell
119 \E create IPregs IPTOS ,
120 \E create regs spTOS ,
122 \E IPregs 1 0 stack-state IPss1
123 \E regs 1 0 stack-state ss0
125 \ the first of these is the default state
128 \E ss0 data-stack S0 set-ss
130 \E IPss1 inst-stream S0 set-ss
132 \E data-stack to cache-stack
133 \E here 1 cache-states 2! s0 ,
135 \ !! the following should be automatic
136 \E S0 to state-default
137 \E state-default to state-in
138 \E state-default to state-out
140 \E s" codegendata *" threaded-code-pointer-type 2!
142 \ This is stub code for methods that we have not yet translated.
143 \ Initially, the code for each method is set to this stub. The
144 \ first time the method is called, the code in the stub runs, which
145 \ translates the bytecode, and replaces the stub with the threaded code.
147 \ instr(NOP, 0, nop, 1, op, {})
149 ICONST ( #vConst -- vConst ) opt
151 LCONST ( #l -- l ) opt
153 ACONST ( #aRef -- aRef ) opt
155 ACONST1 ( #aRef #acrUnused -- aRef ) opt
157 PATCHER_ACONST ( #aRef #acr ... -- )
161 stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
162 result = intrp_patcher_aconst((u1 *) (IP - 3));
163 stacktrace_remove_stackframeinfo(&sfi);
167 STORE_ORDER_BARRIER();
168 IP[-3] = INST_ADDR(ACONST1);
170 patchersuper_rewrite(IP);
172 ILOAD ( #vLocal -- vResult ) 0x15
174 vResult = access_local_int(vLocal);
177 LLOAD ( #vLocal -- lResult ) 0x16
179 vm_twoCell2l(access_local_cell(vLocal), access_local_cell(vLocal-SIZEOF_VOID_P), lResult);
182 ALOAD ( #vLocal -- aRef ) 0x19
184 aRef = (java_objectheader *)access_local_cell(vLocal);
187 IALOAD ( aArray iIndex -- vResult ) 0x2e
189 CHECK_NULL_PTR(aArray);
190 CHECK_OUT_OF_BOUNDS(aArray, iIndex);
192 vResult = access_array_int(aArray, iIndex);
195 FALOAD ( aArray iIndex -- fResult ) 0x2e
197 CHECK_NULL_PTR(aArray);
198 CHECK_OUT_OF_BOUNDS(aArray, iIndex);
200 fResult = access_array_float(aArray, iIndex);
203 LALOAD ( aArray iIndex -- lResult ) 0x2f
205 CHECK_NULL_PTR(aArray);
206 CHECK_OUT_OF_BOUNDS(aArray, iIndex);
208 lResult = access_array_long(aArray, iIndex);
211 AALOAD ( aArray iIndex -- aRef ) 0x32
213 CHECK_NULL_PTR(aArray);
214 CHECK_OUT_OF_BOUNDS(aArray, iIndex);
216 aRef = access_array_addr(aArray, iIndex);
219 BALOAD ( aArray iIndex -- vResult ) 0x33
221 CHECK_NULL_PTR(aArray);
222 CHECK_OUT_OF_BOUNDS(aArray, iIndex);
224 vResult = access_array_byte(aArray, iIndex);
227 CALOAD ( aArray iIndex -- vResult ) 0x34
229 CHECK_NULL_PTR(aArray);
230 CHECK_OUT_OF_BOUNDS(aArray, iIndex);
232 vResult = access_array_char(aArray, iIndex);
235 SALOAD ( aArray iIndex -- vResult ) 0x35
237 CHECK_NULL_PTR(aArray);
238 CHECK_OUT_OF_BOUNDS(aArray, iIndex);
240 vResult = access_array_short(aArray, iIndex);
243 ISTORE ( #vLocal vValue -- ) 0x36
245 access_local_int(vLocal) = vValue;
248 LSTORE ( #vLocal lValue -- ) 0x37
250 vm_l2twoCell(lValue, access_local_cell(vLocal), access_local_cell(vLocal-SIZEOF_VOID_P));
253 ASTORE ( #vLocal aRef -- ) 0x3a
255 access_local_cell(vLocal) = (Cell)aRef;
258 IASTORE ( aArray iIndex iValue -- ) 0x4f
260 CHECK_NULL_PTR(aArray);
261 CHECK_OUT_OF_BOUNDS(aArray, iIndex);
263 access_array_int(aArray, iIndex) = iValue;
266 FASTORE ( aArray iIndex fValue -- ) 0x4f
268 CHECK_NULL_PTR(aArray);
269 CHECK_OUT_OF_BOUNDS(aArray, iIndex);
271 access_array_float(aArray, iIndex) = fValue;
274 LASTORE ( aArray iIndex lValue -- ) 0x50
276 CHECK_NULL_PTR(aArray);
277 CHECK_OUT_OF_BOUNDS(aArray, iIndex);
279 access_array_long(aArray, iIndex) = lValue;
282 AASTORE ( aArray iIndex aRef -- ) 0x53
284 CHECK_NULL_PTR(aArray);
285 CHECK_OUT_OF_BOUNDS(aArray, iIndex);
286 if (!builtin_canstore((java_objectarray *)aArray, aRef))
287 THROW(arraystoreexception);
288 access_array_addr(aArray, iIndex) = aRef;
291 BASTORE ( aArray iIndex iValue -- ) 0x54
293 CHECK_NULL_PTR(aArray);
294 CHECK_OUT_OF_BOUNDS(aArray, iIndex);
296 access_array_byte(aArray, iIndex) = iValue;
299 CASTORE ( aArray iIndex iValue -- ) 0x55
301 CHECK_NULL_PTR(aArray);
302 CHECK_OUT_OF_BOUNDS(aArray, iIndex);
304 access_array_char(aArray, iIndex) = iValue;
307 POP ( vValue -- ) 0x57
309 POP2 ( vValue vValue -- ) 0x58
311 DUP ( vValue -- vValue vValue ) 0x59
313 DUP_X1 ( vValue2 vValue1 -- vValue1 vValue2 vValue1 ) 0x5a
315 DUP_X2 ( vValue3 vValue2 vValue1 -- vValue1 vValue3 vValue2 vValue1 ) 0x5b
317 DUP2 ( vValue2 vValue1 -- vValue2 vValue1 vValue2 vValue1 ) 0x5c
319 DUP2_X1 (vValue3 vValue2 vValue1 -- vValue2 vValue1 vValue3 vValue2 vValue1 ) 0x5d
321 DUP2_X2 ( vValue4 vValue3 vValue2 vValue1 -- vValue2 vValue1 vValue4 vValue3 vValue2 vValue1 ) 0x5e
323 SWAP ( vValue2 vValue1 -- vValue1 vValue2 ) 0x5f
325 IADD ( vValue1 vValue2 -- vResult ) 0x60
327 vResult = vValue2 + vValue1;
330 LADD ( lValue1 lValue2 -- lResult ) 0x61
332 lResult = lValue2 + lValue1;
335 FADD ( fValue1 fValue2 -- fResult ) 0x62
337 fResult = fValue1 + fValue2;
340 DADD ( dValue1 dValue2 -- dResult ) 0x63
342 dResult = dValue1 + dValue2;
345 ISUB ( vValue1 vValue2 -- vResult ) 0x64
347 vResult = vValue1 - vValue2;
350 LSUB ( lValue1 lValue2 -- lResult ) 0x65
352 lResult = lValue1 - lValue2;
355 FSUB ( fValue1 fValue2 -- fResult ) 0x66
357 fResult = fValue1 - fValue2;
360 DSUB ( dValue1 dValue2 -- dResult ) 0x67
362 dResult = dValue1 - dValue2;
365 IMUL ( vValue1 vValue2 -- vResult ) 0x68
367 vResult = vValue1 * vValue2;
370 LMUL ( lValue1 lValue2 -- lResult ) 0x69
372 lResult = lValue1 * lValue2;
375 FMUL ( fValue1 fValue2 -- fResult ) 0x6a
377 fResult = fValue1 * fValue2;
380 DMUL ( dValue1 dValue2 -- dResult ) 0x6b
382 dResult = dValue1 * dValue2;
385 IDIV ( iValue1 iValue2 -- iResult ) 0x6c
387 CHECK_ZERO_DIVISOR(iValue2);
389 if (iValue1 == 0x80000000 && iValue2 == -1)
392 iResult = iValue1 / iValue2;
395 IDIVPOW2 ( i1 #ishift -- i2 ) opt
398 s4 offset = sign >> (32-ishift);
399 i2=(i1+offset)>>ishift;
402 LDIV ( lValue1 lValue2 -- lResult ) 0x6d
404 CHECK_ZERO_DIVISOR(lValue2);
405 if (lValue1 == 0x8000000000000000LL && lValue2 == -1)
408 lResult = lValue1 / lValue2;
411 LDIVPOW2 ( l1 #ishift -- l2 )
414 s8 offset = sign >> (64-ishift);
415 l2=(l1+offset)>>ishift;
418 FDIV ( fValue1 fValue2 -- fResult ) 0x6e
420 fResult = fValue1 / fValue2;
423 DDIV ( dValue1 dValue2 -- dResult ) 0x6f
425 dResult = dValue1 / dValue2;
429 IREM ( iValue1 iValue2 -- iResult ) 0x70
431 CHECK_ZERO_DIVISOR(iValue2);
432 if (iValue1 == 0x80000000 && iValue2 == -1)
435 iResult = iValue1 % iValue2;
438 IREMPOW2 ( i1 #imask -- i2 )
445 LREM ( lValue1 lValue2 -- lResult ) 0x71
447 CHECK_ZERO_DIVISOR(lValue2);
448 if (lValue1 == 0x8000000000000000LL && lValue2 == -1)
451 lResult = lValue1 % lValue2;
454 LREMPOW2 ( l1 #lmask -- l2 )
461 FREM ( fValue1 fValue2 -- fResult ) 0x72
463 fResult = builtin_frem(fValue1, fValue2);
466 DREM ( dValue1 dValue2 -- dResult ) 0x73
468 dResult = builtin_drem(dValue1, dValue2);
471 INEG ( vValue -- vResult ) 0x74
476 LNEG ( lValue -- lResult ) 0x75
481 FNEG ( fValue -- fResult ) 0x76
486 DNEG ( dValue -- dResult ) 0x77
491 ISHL ( vValue1 vValue2 -- vResult ) 0x78
493 vResult = vValue1 << (vValue2 & 31);
496 LSHL ( lValue1 vValue2 -- lResult ) 0x79
498 lResult = lValue1 << (vValue2 & 63);
501 ISHR ( iValue1 iValue2 -- iResult ) 0x7a
503 iResult = iValue1 >> (iValue2 & 31);
506 LSHR ( lValue1 iValue2 -- lResult ) 0x7b
508 lResult = lValue1 >> (iValue2 & 63);
511 IUSHR ( iValue1 vValue2 -- iResult ) 0x7c
513 iResult = ((unsigned) iValue1) >> (vValue2 & 31);
516 LUSHR ( lValue1 vValue2 -- lResult ) 0x7d
518 lResult = (unsigned long long) lValue1 >> (vValue2 & 63);
521 IAND ( vValue1 vValue2 -- vResult ) 0x7e
523 vResult = vValue1 & vValue2;
526 LAND ( lValue1 lValue2 -- lResult ) 0x7f
528 lResult = lValue1 & lValue2;
531 IOR ( vValue1 vValue2 -- vResult ) 0x80
533 vResult = vValue1 | vValue2;
536 LOR ( lValue1 lValue2 -- lResult ) 0x81
538 lResult = lValue1 | lValue2;
541 IXOR ( vValue1 vValue2 -- vResult ) 0x82
543 vResult = vValue1 ^ vValue2;
546 LXOR ( lValue1 lValue2 -- lResult ) 0x83
548 lResult = lValue1 ^ lValue2;
551 IINC ( #vOffset #iConst -- ) 0x84
553 access_local_int(vOffset) += iConst;
556 I2L ( iValue -- lValue ) 0x85
561 I2F ( iValue -- fValue ) 0x86
563 fValue = (float) iValue;
566 I2D ( iValue -- dValue ) 0x87
568 dValue = (double) iValue;
571 L2I ( lValue -- iValue ) 0x88
576 L2F ( lValue -- fValue ) 0x89
578 fValue = (float) lValue;
581 L2D ( lValue -- dValue ) 0x8a
583 dValue = (double) lValue;
586 F2I ( fValue -- iValue ) 0x8b
588 iValue = builtin_f2i(fValue);
591 F2L ( fValue -- lValue ) 0x8c
593 lValue = builtin_f2l(fValue);
596 F2D ( fValue -- dValue ) 0x8d
601 D2I ( dValue -- iValue ) 0x8e
603 iValue = builtin_d2i(dValue);
606 D2L ( dValue -- lValue ) 0x8f
608 lValue = builtin_d2l(dValue);
611 D2F ( dValue -- fValue ) 0x90
616 INT2BYTE ( iValue -- iResult ) 0x91
618 iResult = (iValue << 24) >> 24; /* XXX: try "(s1)iValue" */
622 INT2CHAR ( iValue -- iResult ) 0x92
624 iResult = iValue & 0xFFFF;
627 INT2SHORT ( iValue -- iResult ) 0x93
629 iResult = (iValue << 16) >> 16; /* XXX: try "(s2)iValue" */
632 LCMP ( lValue1 lValue2 -- vResult ) 0x94
634 vResult = lValue1 < lValue2 ? -1 : lValue1 > lValue2 ? 1 : 0;
637 FCMPL ( fValue1 fValue2 -- vResult ) 0x95
639 vResult = builtin_fcmpl(fValue1, fValue2);
642 FCMPG ( fValue1 fValue2 -- vResult ) 0x96
644 vResult = builtin_fcmpg(fValue1, fValue2);
647 DCMPL ( dValue1 dValue2 -- iResult ) 0x97
649 iResult = builtin_dcmpl(dValue1, dValue2);
652 DCMPG ( dValue1 dValue2 -- iResult ) 0x98
654 iResult = builtin_dcmpg(dValue1, dValue2);
657 IFEQ ( #ainstTarget iValue -- ) 0x99
664 IFNE ( #ainstTarget iValue -- ) 0x9a
671 IFLT ( #ainstTarget iValue -- ) 0x9b
677 IFGE ( #ainstTarget iValue -- ) 0x9c
683 IFGT ( #ainstTarget iValue -- ) 0x9d
689 IFLE ( #ainstTarget iValue -- ) 0x9e
695 IF_ICMPEQ ( #ainstTarget iValue1 iValue2 -- ) 0x9f
697 if ( iValue1 == iValue2 )
701 IF_ICMPNE ( #ainstTarget iValue1 iValue2 -- ) 0xa0
703 if ( iValue1 != iValue2 )
707 IF_ICMPLT ( #ainstTarget iValue1 iValue2 -- ) 0xa1
709 if ( iValue1 < iValue2 )
713 IF_ICMPGE ( #ainstTarget iValue1 iValue2 -- ) 0xa2
715 if ( iValue1 >= iValue2 )
719 IF_ICMPGT ( #ainstTarget iValue1 iValue2 -- ) 0xa3
721 if ( iValue1 > iValue2 )
725 IF_ICMPLE ( #ainstTarget iValue1 iValue2 -- ) 0xa4
727 if ( iValue1 <= iValue2 )
731 IF_LCMPEQ ( #ainstTarget lValue1 lValue2 -- ) opt
733 if ( lValue1 == lValue2 )
737 IF_LCMPNE ( #ainstTarget lValue1 lValue2 -- ) opt
739 if ( lValue1 != lValue2 )
743 IF_LCMPLT ( #ainstTarget lValue1 lValue2 -- ) opt
745 if ( lValue1 < lValue2 )
749 IF_LCMPGE ( #ainstTarget lValue1 lValue2 -- ) opt
751 if ( lValue1 >= lValue2 )
755 IF_LCMPGT ( #ainstTarget lValue1 lValue2 -- ) opt
757 if ( lValue1 > lValue2 )
761 IF_LCMPLE ( #ainstTarget lValue1 lValue2 -- ) opt
763 if ( lValue1 <= lValue2 )
767 IF_ACMPEQ ( #ainstTarget aRef1 aRef2 -- ) 0xa5
769 if ( aRef1 == aRef2 )
773 IF_ACMPNE ( #ainstTarget aRef1 aRef2 -- ) 0xa6
775 if ( aRef1 != aRef2 )
779 GOTO ( #ainstTarget -- ) 0xa7
784 JSR ( #ainstTarget -- ainstRA ) 0xa8
786 /* Warning: The generator already adds 1 to the IP
787 because there is an inline parameter. Thus, instead
788 of writing IP + 1, we write...*/
793 RET ( #vOffset -- ) 0xa9
796 saved_ip = access_local_ref(vOffset);
800 TABLESWITCH ( #iLow #iRange #addrSegment #iOffset #ainstDefault iIndex -- ) 0xaa
802 s4 idx = iIndex - iLow;
803 if ( ((u4) idx) >= iRange ) {
804 SET_IP(ainstDefault);
807 SET_IP(((Inst **)(addrSegment+iOffset))[idx]);
811 LOOKUPSWITCH ( #iNpairs #addrSegment #iOffset #ainstDefault iKey -- ) 0xab
813 /* Note: This code should use a binary search, as
814 the table is sorted. Note also, we reversed the order
817 for ( i = 0; i < iNpairs; i++ ) {
818 Cell *table = (Cell *)(addrSegment+iOffset);
819 if ( iKey == (s4)(table[2 * i]) ) {
820 SET_IP((Inst *)(table[2 * i + 1])); INST_TAIL;
823 /* falls through if no match */
824 SET_IP(ainstDefault);
828 \ Our stack works like this:
829 \ The stack holds locals, the operand stack and the return address stack.
830 \ When we invoke a method, the paramaters are the top N elements
831 \ on the stack. These become the first N local variables.
832 \ Next we have space for the rest of the local variables.
833 \ Next comes a single position on the stack which holds
834 \ the value of the frame pointer for the calling function.
835 \ Another position holds the instruction pointer of the caller.
836 \ Finally, we have space for the elements of the operand stack.
838 \ fp points to the bottom local; since the stack grows downwards, the
839 \ upper end of the frame is fp+1, not fp. That's why the sp updates
840 \ in the returns look like they are off by one.
846 \ sp -> oldip ; at the start, empty stack
847 \ stack0 ;once there is something on the stack
850 IRETURN ( #vOffsetFP ... vValue -- vResult ) 0xac
853 Cell *currentsp = sp;
854 new_ip = (Inst *) access_local_cell(vOffsetFP - SIZEOF_VOID_P);
856 fp = (Cell *) access_local_cell(vOffsetFP);
857 CLEARSTACK(currentsp - 6, sp - 1);
862 LRETURN ( #vOffsetFP ... lValue -- lResult ) 0xad
865 Cell *currentsp = sp;
866 new_ip = (Inst *) access_local_cell(vOffsetFP - SIZEOF_VOID_P);
868 fp = (Cell *) access_local_cell(vOffsetFP);
869 CLEARSTACK(currentsp - 7, sp - 2);
874 RETURN ( #vOffsetFP ... -- ) 0xb1
877 Cell *currentsp = sp;
878 new_ip = (Inst *) access_local_cell(vOffsetFP - SIZEOF_VOID_P);
880 fp = (Cell *) access_local_cell(vOffsetFP);
881 CLEARSTACK(currentsp - 5, sp - 1);
885 GETSTATIC_CELL ( #addr #afi -- vResult ) opt
887 vResult = *(Cell *)addr;
890 GETSTATIC_INT ( #addr #afi -- iResult ) opt
892 iResult = *(s4 *)addr;
895 GETSTATIC_FLOAT ( #addr #afi -- fResult ) opt
897 fResult = *(float *)addr;
900 GETSTATIC_LONG ( #addr #afi -- lResult ) opt
902 lResult = *((s8 *) addr);
905 PUTSTATIC_CELL ( #addr #afi vValue -- ) opt
907 *((Cell *) addr) = vValue;
910 PUTSTATIC_INT ( #addr #afi iValue -- ) opt
912 *((s4 *) addr) = iValue;
915 PUTSTATIC_FLOAT ( #addr #afi fValue -- ) opt
917 *((float *) addr) = fValue;
920 PUTSTATIC_LONG ( #addr #afi lValue -- ) opt
922 *((s8 *) addr) = lValue;
925 GETFIELD_CELL ( #vOffset #afi aRef -- vResult ) opt
927 CHECK_NULL_PTR(aRef);
928 vResult = *((Cell *) (((u1 *)aRef) + vOffset));
931 GETFIELD_INT ( #vOffset #afi aRef -- iResult ) opt
933 CHECK_NULL_PTR(aRef);
934 iResult = *((s4 *) (((u1 *)aRef) + vOffset));
937 GETFIELD_FLOAT ( #vOffset #afi aRef -- fResult ) opt
939 CHECK_NULL_PTR(aRef);
940 fResult = *((float *) (((u1 *) aRef) + vOffset));
943 GETFIELD_LONG ( #vOffset #afi aRef -- lResult ) opt
945 CHECK_NULL_PTR(aRef);
946 lResult = *((s8 *) (((u1 *)aRef) + vOffset));
950 PUTFIELD_CELL ( #vOffset #afi aRef vValue -- ) opt
952 CHECK_NULL_PTR(aRef);
953 *((Cell *) (((u1 *)aRef) + vOffset)) = vValue;
956 PUTFIELD_INT ( #vOffset #afi aRef iValue -- ) opt
958 CHECK_NULL_PTR(aRef);
959 *((s4 *) (((u1 *)aRef) + vOffset)) = iValue;
962 PUTFIELD_FLOAT ( #vOffset #afi aRef fValue -- ) opt
964 CHECK_NULL_PTR(aRef);
965 *((float *) (((u1 *)aRef) + vOffset)) = fValue;
968 PUTFIELD_LONG ( #vOffset #afi aRef lValue -- ) opt
970 CHECK_NULL_PTR(aRef);
971 *((s8 *) (((u1 *)aRef) + vOffset)) = lValue;
974 \ !! called methods have the number of locals at offset -1.
975 \ methods are always called indirectly through the codeptr in the stub
976 \ (see createcompilerstub and TRANSLATE).
978 INVOKEVIRTUAL ( #vOffset #iNargs #am ... -- ... acelloldfp ainstoldip ) 0xd8
980 java_objectheader *aRef = (java_objectheader *)(sp[iNargs - 1]);
984 CHECK_NULL_PTR(aRef);
985 v = (char *)(aRef->vftbl);
986 stub = *(Inst ***)(v+vOffset);
990 fp = sp - 1 + iNargs;
991 sp = fp - MAXLOCALS(stub) + 1;
995 INVOKESTATIC ( #aaTarget #iNargs #am ... -- ... acelloldfp ainstoldip ) 0xb8
996 /* an indirect pointer to target is passed to avoid references to uncompiled code */
998 Inst *target = *aaTarget;
1001 fp = sp - 1 + iNargs; /* !! scale nargs at translation time */
1002 sp = fp - MAXLOCALS(aaTarget) + 1;
1006 INVOKESPECIAL ( #aaTarget #iNargs #am ... -- ... acelloldfp ainstoldip ) 0xb7
1007 /* an indirect pointer to target is passed to avoid references to uncompiled code */
1009 java_objectheader *aRef = (java_objectheader *)(sp[iNargs - 1]);
1010 Inst *target = *aaTarget;
1011 CHECK_NULL_PTR(aRef);
1014 fp = sp - 1 + iNargs; /* !! scale nargs at translation time */
1015 sp = fp - MAXLOCALS(aaTarget) + 1;
1019 INVOKEINTERFACE ( #iInterfaceOffset #vOffset #iNargs #am ... -- ... acelloldfp ainstoldip ) 0xd8
1021 java_objectheader *aRef;
1026 aRef = (java_objectheader *)sp[iNargs - 1];
1027 CHECK_NULL_PTR(aRef);
1028 v = (char *)(aRef->vftbl);
1029 t = *(char **)(v + iInterfaceOffset);
1030 stub = *(Inst ***)(t+vOffset);
1034 fp = sp - 1 + iNargs;
1035 sp = fp - MAXLOCALS(stub) + 1;
1039 \ the BUILTIN functions like NEW get their parameters on the stack
1040 \ instead of through immediate arguments.
1042 \ !! do we need to synchronize the stack here?
1043 \ !! if so, is global_sp right?
1045 NEW ( ... aClass -- ... aRef ) 0xbb
1048 aRef = builtin_new((classinfo *) aClass);
1051 *exceptionptr = stacktrace_inline_fillInStackTrace(NULL, (u1 *) fp, (u1 *) IP, (u1 *) IP);
1060 NEWARRAY_BOOLEAN ( ... iSize -- ... aArray )
1063 aArray = (java_arrayheader *) builtin_newarray_boolean(iSize);
1064 if (aArray == NULL) {
1066 *exceptionptr = stacktrace_inline_fillInStackTrace(NULL, (u1 *) fp, (u1 *) IP, (u1 *) IP);
1073 NEWARRAY_BYTE ( ... iSize -- ... aArray )
1076 aArray = (java_arrayheader *) builtin_newarray_byte(iSize);
1077 if (aArray == NULL) {
1079 *exceptionptr = stacktrace_inline_fillInStackTrace(NULL, (u1 *) fp, (u1 *) IP, (u1 *) IP);
1086 NEWARRAY_CHAR ( ... iSize -- ... aArray )
1089 aArray = (java_arrayheader *) builtin_newarray_char(iSize);
1090 if (aArray == NULL) {
1092 *exceptionptr = stacktrace_inline_fillInStackTrace(NULL, (u1 *) fp, (u1 *) IP, (u1 *) IP);
1099 NEWARRAY_SHORT ( ... iSize -- ... aArray )
1102 aArray = (java_arrayheader *) builtin_newarray_short(iSize);
1103 if (aArray == NULL) {
1105 *exceptionptr = stacktrace_inline_fillInStackTrace(NULL, (u1 *) fp, (u1 *) IP, (u1 *) IP);
1112 NEWARRAY_INT ( ... iSize -- ... aArray )
1115 aArray = (java_arrayheader *) builtin_newarray_int(iSize);
1116 if (aArray == NULL) {
1118 *exceptionptr = stacktrace_inline_fillInStackTrace(NULL, (u1 *) fp, (u1 *) IP, (u1 *) IP);
1125 NEWARRAY_LONG ( ... iSize -- ... aArray )
1128 aArray = (java_arrayheader *) builtin_newarray_long(iSize);
1129 if (aArray == NULL) {
1131 *exceptionptr = stacktrace_inline_fillInStackTrace(NULL, (u1 *) fp, (u1 *) IP, (u1 *) IP);
1138 NEWARRAY_FLOAT ( ... iSize -- ... aArray )
1141 aArray = (java_arrayheader *) builtin_newarray_float(iSize);
1142 if (aArray == NULL) {
1144 *exceptionptr = stacktrace_inline_fillInStackTrace(NULL, (u1 *) fp, (u1 *) IP, (u1 *) IP);
1151 NEWARRAY_DOUBLE ( ... iSize -- ... aArray )
1154 aArray = (java_arrayheader *) builtin_newarray_double(iSize);
1155 if (aArray == NULL) {
1157 *exceptionptr = stacktrace_inline_fillInStackTrace(NULL, (u1 *) fp, (u1 *) IP, (u1 *) IP);
1164 NEWARRAY ( ... iSize aClass -- ... aArray )
1167 aArray = (java_arrayheader *) builtin_newarray(iSize, aClass);
1168 if (aArray == NULL) {
1170 *exceptionptr = stacktrace_inline_fillInStackTrace(NULL, (u1 *) fp, (u1 *) IP, (u1 *) IP);
1177 ARRAYLENGTH ( aArray -- iResult )
1179 CHECK_NULL_PTR(aArray);
1180 iResult = length_array(aArray);
1183 ATHROW ( ... aRef -- ... aRef1 )
1185 Cell *new_sp, *new_fp;
1187 CHECK_NULL_PTR(aRef);
1191 aRef = *exceptionptr;
1192 *exceptionptr = NULL;
1194 new_ip = intrp_asm_handle_exception(IP, aRef, fp, &new_sp, &new_fp);
1195 if (new_ip == NULL) {
1196 /* !! sp = new_sp; ? */
1198 SUPER_END; /* ATHROW may end a basic block */
1207 CHECKCAST ( #aClass #acr aRef -- aRef ) 0xc0
1209 if (!builtin_checkcast((java_objectheader *) aRef, (classinfo *) aClass))
1210 THROW(classcastexception);
1213 ARRAYCHECKCAST ( #aClass #acr aRef -- aRef ) 0xc0
1215 if (!builtin_arraycheckcast(aRef, aClass))
1216 THROW(classcastexception);
1219 PATCHER_ARRAYCHECKCAST ( #avftbl #acr ... -- ) 0xc0
1223 stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
1224 result = intrp_patcher_builtin_arraycheckcast((u1 *) (IP - 3));
1225 stacktrace_remove_stackframeinfo(&sfi);
1229 STORE_ORDER_BARRIER();
1230 IP[-3] = INST_ADDR(ARRAYCHECKCAST);
1232 patchersuper_rewrite(IP);
1234 INSTANCEOF ( #aClass #acr aRef -- iResult )
1236 iResult = builtin_instanceof(aRef, aClass);
1239 ARRAYINSTANCEOF ( aRef aClass -- iResult )
1241 iResult = builtin_arrayinstanceof(aRef, aClass);
1244 MONITORENTER ( aRef -- )
1246 #if defined(ENABLE_THREADS)
1247 /* CHECK_NULL_PTR(aRef); is now done explicitly */
1248 builtin_monitorenter(aRef);
1252 MONITOREXIT ( aRef -- )
1254 #if defined(ENABLE_THREADS)
1255 /* CHECK_NULL_PTR(aRef); cannot happen */
1256 builtin_monitorexit(aRef);
1260 CHECKNULL ( aRef -- aRef )
1262 CHECK_NULL_PTR(aRef);
1265 MULTIANEWARRAY ( #aClass #iSize #acr ... -- aRef )
1270 dims = MNEW(long, iSize);
1272 for (i = 0; i < iSize; i++) {
1273 dims[i] = sp[iSize - i - 1];
1276 aRef = (java_objectheader *) builtin_multianewarray(iSize, aClass, dims);
1278 MFREE(dims, long, iSize);
1282 *exceptionptr = stacktrace_inline_fillInStackTrace(NULL, (u1 *) fp, (u1 *) IP, (u1 *) IP);
1290 IFNULL ( #ainstTarget aRef -- ) 0xc6
1292 if ( aRef == NULL ) {
1293 SET_IP(ainstTarget);
1297 IFNONNULL ( #ainstTarget aRef -- ) 0xc7
1299 if ( aRef != NULL ) {
1300 SET_IP(ainstTarget);
1304 \ patchers for resolving fields
1306 PATCHER_GETSTATIC_INT ( #aRef #auf ... -- )
1310 stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
1311 result = intrp_patcher_get_putstatic((u1 *) (IP - 3));
1312 stacktrace_remove_stackframeinfo(&sfi);
1316 STORE_ORDER_BARRIER();
1317 IP[-3] = INST_ADDR(GETSTATIC_INT);
1319 patchersuper_rewrite(IP);
1321 PATCHER_GETSTATIC_FLOAT ( #aRef #auf ... -- )
1325 stacktrace_create_stackframeinfo(&sfi, NULL, fp, (functionptr) IP);
1326 result = intrp_patcher_get_putstatic((u1 *)(IP-3));
1327 stacktrace_remove_stackframeinfo(&sfi);
1331 STORE_ORDER_BARRIER();
1332 IP[-3] = INST_ADDR(GETSTATIC_FLOAT);
1334 patchersuper_rewrite(IP);
1336 PATCHER_GETSTATIC_LONG ( #aRef #auf ... -- )
1340 stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
1341 result = intrp_patcher_get_putstatic((u1 *) (IP - 3));
1342 stacktrace_remove_stackframeinfo(&sfi);
1346 STORE_ORDER_BARRIER();
1347 IP[-3] = INST_ADDR(GETSTATIC_LONG);
1349 patchersuper_rewrite(IP);
1351 PATCHER_GETSTATIC_CELL ( #aRef #auf ... -- )
1355 stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
1356 result = intrp_patcher_get_putstatic((u1 *) (IP - 3));
1357 stacktrace_remove_stackframeinfo(&sfi);
1361 STORE_ORDER_BARRIER();
1362 IP[-3] = INST_ADDR(GETSTATIC_CELL);
1364 patchersuper_rewrite(IP);
1366 \ patchers for statically initializing classes
1368 PATCHER_GETSTATIC_CLINIT_INT ( #aRef #afi ... -- )
1372 stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
1373 result = intrp_patcher_get_putstatic_clinit((u1 *) (IP - 3));
1374 stacktrace_remove_stackframeinfo(&sfi);
1378 STORE_ORDER_BARRIER();
1379 IP[-3] = INST_ADDR(GETSTATIC_INT);
1381 patchersuper_rewrite(IP);
1383 PATCHER_GETSTATIC_CLINIT_FLOAT ( #aRef #afi ... -- )
1387 stacktrace_create_stackframeinfo(&sfi, NULL, fp, (functionptr) IP);
1388 result = intrp_patcher_get_putstatic_clinit((u1 *)(IP-3));
1389 stacktrace_remove_stackframeinfo(&sfi);
1393 STORE_ORDER_BARRIER();
1394 IP[-3] = INST_ADDR(GETSTATIC_FLOAT);
1396 patchersuper_rewrite(IP);
1398 PATCHER_GETSTATIC_CLINIT_LONG ( #aRef #afi ... -- )
1402 stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
1403 result = intrp_patcher_get_putstatic_clinit((u1 *) (IP - 3));
1404 stacktrace_remove_stackframeinfo(&sfi);
1408 STORE_ORDER_BARRIER();
1409 IP[-3] = INST_ADDR(GETSTATIC_LONG);
1411 patchersuper_rewrite(IP);
1413 PATCHER_GETSTATIC_CLINIT_CELL ( #aRef #afi ... -- )
1417 stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
1418 result = intrp_patcher_get_putstatic_clinit((u1 *) (IP - 3));
1419 stacktrace_remove_stackframeinfo(&sfi);
1423 STORE_ORDER_BARRIER();
1424 IP[-3] = INST_ADDR(GETSTATIC_CELL);
1426 patchersuper_rewrite(IP);
1428 \ patchers for resolving fields
1430 PATCHER_PUTSTATIC_INT ( #aRef #auf ... -- )
1434 stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
1435 result = intrp_patcher_get_putstatic((u1 *) (IP - 3));
1436 stacktrace_remove_stackframeinfo(&sfi);
1440 STORE_ORDER_BARRIER();
1441 IP[-3] = INST_ADDR(PUTSTATIC_INT);
1443 patchersuper_rewrite(IP);
1445 PATCHER_PUTSTATIC_FLOAT ( #aRef #auf ... -- )
1449 stacktrace_create_stackframeinfo(&sfi, NULL, fp, (functionptr) IP);
1450 result = intrp_patcher_get_putstatic((u1 *)(IP-3));
1451 stacktrace_remove_stackframeinfo(&sfi);
1455 STORE_ORDER_BARRIER();
1456 IP[-3] = INST_ADDR(PUTSTATIC_FLOAT);
1458 patchersuper_rewrite(IP);
1460 PATCHER_PUTSTATIC_LONG ( #aRef #auf ... -- )
1464 stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
1465 result = intrp_patcher_get_putstatic((u1 *) (IP - 3));
1466 stacktrace_remove_stackframeinfo(&sfi);
1470 STORE_ORDER_BARRIER();
1471 IP[-3] = INST_ADDR(PUTSTATIC_LONG);
1473 patchersuper_rewrite(IP);
1475 PATCHER_PUTSTATIC_CELL ( #aRef #auf ... -- )
1479 stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
1480 result = intrp_patcher_get_putstatic((u1 *) (IP - 3));
1481 stacktrace_remove_stackframeinfo(&sfi);
1485 STORE_ORDER_BARRIER();
1486 IP[-3] = INST_ADDR(PUTSTATIC_CELL);
1488 patchersuper_rewrite(IP);
1490 \ patchers for statically initializing classes
1492 PATCHER_PUTSTATIC_CLINIT_INT ( #aRef #afi ... -- )
1496 stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
1497 result = intrp_patcher_get_putstatic_clinit((u1 *) (IP - 3));
1498 stacktrace_remove_stackframeinfo(&sfi);
1502 STORE_ORDER_BARRIER();
1503 IP[-3] = INST_ADDR(PUTSTATIC_INT);
1505 patchersuper_rewrite(IP);
1507 PATCHER_PUTSTATIC_CLINIT_FLOAT ( #aRef #afi ... -- )
1511 stacktrace_create_stackframeinfo(&sfi, NULL, fp, (functionptr) IP);
1512 result = intrp_patcher_get_putstatic_clinit((u1 *)(IP-3));
1513 stacktrace_remove_stackframeinfo(&sfi);
1517 STORE_ORDER_BARRIER();
1518 IP[-3] = INST_ADDR(PUTSTATIC_FLOAT);
1520 patchersuper_rewrite(IP);
1522 PATCHER_PUTSTATIC_CLINIT_LONG ( #aRef #afi ... -- )
1526 stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
1527 result = intrp_patcher_get_putstatic_clinit((u1 *) (IP - 3));
1528 stacktrace_remove_stackframeinfo(&sfi);
1532 STORE_ORDER_BARRIER();
1533 IP[-3] = INST_ADDR(PUTSTATIC_LONG);
1535 patchersuper_rewrite(IP);
1537 PATCHER_PUTSTATIC_CLINIT_CELL ( #aRef #afi ... -- )
1541 stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
1542 result = intrp_patcher_get_putstatic_clinit((u1 *) (IP - 3));
1543 stacktrace_remove_stackframeinfo(&sfi);
1547 STORE_ORDER_BARRIER();
1548 IP[-3] = INST_ADDR(PUTSTATIC_CELL);
1550 patchersuper_rewrite(IP);
1552 \ patchers for resolving fields
1554 PATCHER_GETFIELD_INT ( #vOffset #auf ... -- )
1558 stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
1559 result = intrp_patcher_get_putfield((u1 *) (IP - 3));
1560 stacktrace_remove_stackframeinfo(&sfi);
1564 STORE_ORDER_BARRIER();
1565 IP[-3] = INST_ADDR(GETFIELD_INT);
1567 patchersuper_rewrite(IP);
1569 PATCHER_GETFIELD_FLOAT ( #vOffset #auf ... -- )
1573 stacktrace_create_stackframeinfo(&sfi, NULL, fp, (functionptr) IP);
1574 result = intrp_patcher_get_putfield((u1 *)(IP-3));
1575 stacktrace_remove_stackframeinfo(&sfi);
1579 STORE_ORDER_BARRIER();
1580 IP[-3] = INST_ADDR(GETFIELD_FLOAT);
1582 patchersuper_rewrite(IP);
1584 PATCHER_GETFIELD_LONG ( #vOffset #auf ... -- )
1588 stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
1589 result = intrp_patcher_get_putfield((u1 *) (IP - 3));
1590 stacktrace_remove_stackframeinfo(&sfi);
1594 STORE_ORDER_BARRIER();
1595 IP[-3] = INST_ADDR(GETFIELD_LONG);
1597 patchersuper_rewrite(IP);
1599 PATCHER_GETFIELD_CELL ( #vOffset #auf ... -- )
1603 stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
1604 result = intrp_patcher_get_putfield((u1 *) (IP - 3));
1605 stacktrace_remove_stackframeinfo(&sfi);
1609 STORE_ORDER_BARRIER();
1610 IP[-3] = INST_ADDR(GETFIELD_CELL);
1612 patchersuper_rewrite(IP);
1614 PATCHER_PUTFIELD_INT ( #vOffset #auf ... -- )
1618 stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
1619 result = intrp_patcher_get_putfield((u1 *) (IP - 3));
1620 stacktrace_remove_stackframeinfo(&sfi);
1624 STORE_ORDER_BARRIER();
1625 IP[-3] = INST_ADDR(PUTFIELD_INT);
1627 patchersuper_rewrite(IP);
1629 PATCHER_PUTFIELD_FLOAT ( #vOffset #auf ... -- )
1633 stacktrace_create_stackframeinfo(&sfi, NULL, fp, (functionptr) IP);
1634 result = intrp_patcher_get_putfield((u1 *)(IP-3));
1635 stacktrace_remove_stackframeinfo(&sfi);
1639 STORE_ORDER_BARRIER();
1640 IP[-3] = INST_ADDR(PUTFIELD_FLOAT);
1642 patchersuper_rewrite(IP);
1644 PATCHER_PUTFIELD_LONG ( #vOffset #auf ... -- )
1648 stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
1649 result = intrp_patcher_get_putfield((u1 *) (IP - 3));
1650 stacktrace_remove_stackframeinfo(&sfi);
1654 STORE_ORDER_BARRIER();
1655 IP[-3] = INST_ADDR(PUTFIELD_LONG);
1657 patchersuper_rewrite(IP);
1659 PATCHER_PUTFIELD_CELL ( #vOffset #auf ... -- )
1663 stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
1664 result = intrp_patcher_get_putfield((u1 *) (IP - 3));
1665 stacktrace_remove_stackframeinfo(&sfi);
1669 STORE_ORDER_BARRIER();
1670 IP[-3] = INST_ADDR(PUTFIELD_CELL);
1672 patchersuper_rewrite(IP);
1674 \ other patchers for lazy resolving
1676 PATCHER_MULTIANEWARRAY ( #aClass #iSize #acr ... -- )
1680 stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
1681 result = intrp_patcher_builtin_multianewarray((u1 *) (IP - 4));
1682 stacktrace_remove_stackframeinfo(&sfi);
1686 STORE_ORDER_BARRIER();
1687 IP[-4] = INST_ADDR(MULTIANEWARRAY);
1689 patchersuper_rewrite(IP);
1691 PATCHER_INVOKESTATIC ( #aaTarget #iNargs #aum ... -- ) 0xd8
1695 stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
1696 result = intrp_patcher_invokestatic_special((u1 *) (IP - 4));
1697 stacktrace_remove_stackframeinfo(&sfi);
1701 STORE_ORDER_BARRIER();
1702 IP[-4] = INST_ADDR(INVOKESTATIC);
1704 patchersuper_rewrite(IP);
1706 PATCHER_INVOKESPECIAL ( #aaTarget #iNargs #aum ... -- ) 0xd8
1710 stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
1711 result = intrp_patcher_invokestatic_special((u1 *) (IP - 4));
1712 stacktrace_remove_stackframeinfo(&sfi);
1716 STORE_ORDER_BARRIER();
1717 IP[-4] = INST_ADDR(INVOKESPECIAL);
1719 patchersuper_rewrite(IP);
1721 PATCHER_INVOKEVIRTUAL ( #vOffset #iNargs #aum ... -- ) 0xd8
1725 stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
1726 result = intrp_patcher_invokevirtual((u1 *) (IP - 4));
1727 stacktrace_remove_stackframeinfo(&sfi);
1731 STORE_ORDER_BARRIER();
1732 IP[-4] = INST_ADDR(INVOKEVIRTUAL);
1734 patchersuper_rewrite(IP);
1736 PATCHER_INVOKEINTERFACE ( #iInterfaceoffset #vOffset #iNargs #aum ... -- ) 0xd8
1740 stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
1741 result = intrp_patcher_invokeinterface((u1 *) (IP - 5));
1742 stacktrace_remove_stackframeinfo(&sfi);
1746 STORE_ORDER_BARRIER();
1747 IP[-5] = INST_ADDR(INVOKEINTERFACE);
1749 patchersuper_rewrite(IP);
1751 PATCHER_CHECKCAST ( #aClass #acr ... -- ) 0xc
1755 stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
1756 result = intrp_patcher_checkcast_instanceof((u1 *) (IP - 3));
1757 stacktrace_remove_stackframeinfo(&sfi);
1761 STORE_ORDER_BARRIER();
1762 IP[-3] = INST_ADDR(CHECKCAST);
1764 patchersuper_rewrite(IP);
1766 PATCHER_INSTANCEOF ( #aClass #acr ... -- ) 0xc1
1770 stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
1771 result = intrp_patcher_checkcast_instanceof((u1 *) (IP - 3));
1772 stacktrace_remove_stackframeinfo(&sfi);
1776 STORE_ORDER_BARRIER();
1777 IP[-3] = INST_ADDR(INSTANCEOF);
1779 patchersuper_rewrite(IP);
1781 \ This is stub code for methods that we have not yet translated.
1782 \ Initially, the code for each method is set to this stub. The
1783 \ first time the method is called, the code in the stub runs, which
1784 \ translates the bytecode, and replaces the stub with the threaded code.
1786 TRANSLATE ( #am ... -- )
1793 vm_Cell2acell(sp[1],acelloldfp);
1794 vm_Cell2ainst(sp[0],ainstoldip);
1796 stacktrace_create_extern_stackframeinfo(&sfi, NULL, (u1 *) acelloldfp, (u1 *) ainstoldip, (u1 *) ainstoldip);
1797 codeptr = (Inst *) jit_compile(am);
1798 stacktrace_remove_stackframeinfo(&sfi);
1799 if (codeptr == NULL) {
1801 SET_IP(ainstoldip); /* set up ip and fp for throw */
1809 NATIVECALL ( #am #af #addrcif ... acelloldfp ainstoldip -- )
1810 sp = nativecall(af, am, sp, ainstoldip, acelloldfp, addrcif);
1817 TRACENATIVECALL ( #am #af #addrcif ... acelloldfp ainstoldip -- )
1818 sp = nativecall(af, am, sp, ainstoldip, acelloldfp, addrcif);
1825 #if !defined(NDEBUG)
1826 builtin_displaymethodstop(am, (s8) v, f, f);
1832 PATCHER_NATIVECALL ( #am #af #addrcif ... -- )
1833 #if !defined(WITH_STATIC_CLASSPATH)
1837 stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
1838 result = intrp_patcher_resolve_native((u1 *) (IP - 4));
1839 stacktrace_remove_stackframeinfo(&sfi);
1843 STORE_ORDER_BARRIER();
1844 IP[-4] = opt_verbosecall ? INST_ADDR(TRACENATIVECALL) : INST_ADDR(NATIVECALL);
1846 patchersuper_rewrite(IP);
1851 TRACECALL ( #am -- )
1852 #if !defined(NDEBUG)
1854 access_local_cell(0 * -SIZEOF_VOID_P),
1855 access_local_cell(1 * -SIZEOF_VOID_P),
1856 access_local_cell(2 * -SIZEOF_VOID_P),
1857 access_local_cell(3 * -SIZEOF_VOID_P),
1858 #if TRACE_ARGS_NUM > 4
1859 access_local_cell(4 * -SIZEOF_VOID_P),
1860 access_local_cell(5 * -SIZEOF_VOID_P),
1862 #if TRACE_ARGS_NUM == 8
1863 access_local_cell(6 * -SIZEOF_VOID_P),
1864 access_local_cell(7 * -SIZEOF_VOID_P),
1867 #endif /* !defined(NDEBUG) */
1869 TRACERETURN ( #am v -- v )
1872 #if !defined(NDEBUG)
1873 builtin_displaymethodstop(am, (s8) v, f, f);
1876 TRACELRETURN ( #am l -- l )
1879 #if !defined(NDEBUG)
1880 builtin_displaymethodstop(am, l, ds.d, ds.d);
1886 vm_uncount_block(IP); /* undo the count part of SUPER_END,
1887 because there is no fallthrough */
1890 _ALOAD_GETFIELD_CELL_ = ALOAD GETFIELD_CELL
1891 _DUP_ICONST_ = DUP ICONST
1892 _ALOAD_ALOAD_ = ALOAD ALOAD
1893 _ICONST_ICONST_ = ICONST ICONST
1894 _DUP_ICONST_ICONST_ = DUP ICONST ICONST
1895 _ICONST_CASTORE_ = ICONST CASTORE
1896 _ICONST_ICONST_CASTORE_ = ICONST ICONST CASTORE
1897 _DUP_ICONST_ICONST_CASTORE_ = DUP ICONST ICONST CASTORE
1898 _CASTORE_DUP_ = CASTORE DUP
1899 _CASTORE_DUP_ICONST_ = CASTORE DUP ICONST
1900 _DUP_ICONST_ICONST_CASTORE_DUP_ = DUP ICONST ICONST CASTORE DUP
1901 _ICONST_CASTORE_DUP_ = ICONST CASTORE DUP
1902 _ICONST_CASTORE_DUP_ICONST_ = ICONST CASTORE DUP ICONST
1903 _ICONST_ICONST_CASTORE_DUP_ = ICONST ICONST CASTORE DUP
1904 _ICONST_ICONST_CASTORE_DUP_ICONST_ = ICONST ICONST CASTORE DUP ICONST
1905 _CASTORE_DUP_ICONST_ICONST_ = CASTORE DUP ICONST ICONST
1906 _CASTORE_DUP_ICONST_ICONST_CASTORE_ = CASTORE DUP ICONST ICONST CASTORE
1907 _ICONST_CASTORE_DUP_ICONST_ICONST_ = ICONST CASTORE DUP ICONST ICONST
1908 _ASTORE_ALOAD_ = ASTORE ALOAD
1909 _ALOAD_GETFIELD_INT_ = ALOAD GETFIELD_INT
1910 _ALOAD_ILOAD_ = ALOAD ILOAD
1911 _ALOAD_ACONST_ = ALOAD ACONST
1912 _ICONST_ACONST_ = ICONST ACONST
1913 _AASTORE_DUP_ = AASTORE DUP
1914 _AASTORE_DUP_ICONST_ = AASTORE DUP ICONST
1915 _ALOAD_ICONST_ = ALOAD ICONST
1916 _ILOAD_ICONST_ = ILOAD ICONST
1917 _ILOAD_ILOAD_ = ILOAD ILOAD
1918 _DUP_ICONST_ACONST_ = DUP ICONST ACONST
1919 _GETFIELD_CELL_ALOAD_ = GETFIELD_CELL ALOAD
1920 _AASTORE_DUP_ICONST_ACONST_ = AASTORE DUP ICONST ACONST
1921 _ACONST_AASTORE_ = ACONST AASTORE
1922 _ICONST_ACONST_AASTORE_ = ICONST ACONST AASTORE
1923 _DUP_ICONST_ACONST_AASTORE_ = DUP ICONST ACONST AASTORE
1924 _ALOAD_GETFIELD_CELL_ALOAD_ = ALOAD GETFIELD_CELL ALOAD
1925 _ACONST_AASTORE_DUP_ = ACONST AASTORE DUP
1926 _ACONST_AASTORE_DUP_ICONST_ = ACONST AASTORE DUP ICONST
1927 _DUP_ICONST_ACONST_AASTORE_DUP_ = DUP ICONST ACONST AASTORE DUP
1928 _ICONST_ACONST_AASTORE_DUP_ = ICONST ACONST AASTORE DUP
1929 _ICONST_ACONST_AASTORE_DUP_ICONST_ = ICONST ACONST AASTORE DUP ICONST
1930 _AASTORE_DUP_ICONST_ACONST_AASTORE_ = AASTORE DUP ICONST ACONST AASTORE
1931 _DUP_ACONST_ = DUP ACONST
1932 _ACONST_AASTORE_DUP_ICONST_ACONST_ = ACONST AASTORE DUP ICONST ACONST
1933 _PUTFIELD_CELL_ALOAD_ = PUTFIELD_CELL ALOAD
1934 _ILOAD_ALOAD_ = ILOAD ALOAD
1935 _ICONST_ALOAD_ = ICONST ALOAD
1936 _DUP_ALOAD_ = DUP ALOAD
1937 _ICONST_ISTORE_ = ICONST ISTORE
1938 _ASTORE_ALOAD_ALOAD_ = ASTORE ALOAD ALOAD
1939 _ALOAD_PUTFIELD_CELL_ = ALOAD PUTFIELD_CELL
1940 _PUTFIELD_INT_ALOAD_ = PUTFIELD_INT ALOAD
1941 _ALOAD_ALOAD_PUTFIELD_CELL_ = ALOAD ALOAD PUTFIELD_CELL
1942 _ICONST_IADD_ = ICONST IADD
1943 _ISTORE_GOTO_ = ISTORE GOTO
1944 _ACONST_ACONST_ = ACONST ACONST
1945 _POP_ALOAD_ = POP ALOAD
1946 _ACONST_ICONST_ = ACONST ICONST
1947 _ALOAD_ALOAD_ALOAD_ = ALOAD ALOAD ALOAD
1948 _ALOAD_ALOAD_GETFIELD_CELL_ = ALOAD ALOAD GETFIELD_CELL
1949 _ISTORE_ALOAD_ = ISTORE ALOAD
1950 _GETFIELD_CELL_ILOAD_ = GETFIELD_CELL ILOAD
1951 _IINC_ILOAD_ = IINC ILOAD
1952 _ISTORE_ILOAD_ = ISTORE ILOAD
1953 _ALOAD_GETFIELD_CELL_ILOAD_ = ALOAD GETFIELD_CELL ILOAD
1954 _ILOAD_ICONST_IADD_ = ILOAD ICONST IADD
1955 _CHECKCAST_ASTORE_ = CHECKCAST ASTORE
1956 _ASTORE_ACONST_ = ASTORE ACONST
1957 _GETFIELD_INT_ALOAD_ = GETFIELD_INT ALOAD
1958 _ACONST_ALOAD_ = ACONST ALOAD
1959 _ICONST_ISTORE_GOTO_ = ICONST ISTORE GOTO
1960 _CHECKCAST_ASTORE_ALOAD_ = CHECKCAST ASTORE ALOAD
1961 _ASTORE_GOTO_ = ASTORE GOTO
1962 _ALOAD_PUTFIELD_CELL_ALOAD_ = ALOAD PUTFIELD_CELL ALOAD
1963 _ALOAD_ALOAD_PUTFIELD_CELL_ALOAD_ = ALOAD ALOAD PUTFIELD_CELL ALOAD
1964 _ICONST_PUTFIELD_INT_ = ICONST PUTFIELD_INT
1965 _ALOAD_IFNULL_ = ALOAD IFNULL
1966 _ALOAD_IFNONNULL_ = ALOAD IFNONNULL
1967 _ALOAD_ICONST_PUTFIELD_INT_ = ALOAD ICONST PUTFIELD_INT
1968 _ALOAD_GETFIELD_INT_ALOAD_ = ALOAD GETFIELD_INT ALOAD
1969 _ALOAD_ILOAD_ILOAD_ = ALOAD ILOAD ILOAD
1970 _DUP_ICONST_ALOAD_ = DUP ICONST ALOAD
1971 _IADD_ILOAD_ = IADD ILOAD
1972 _GETFIELD_CELL_ICONST_ = GETFIELD_CELL ICONST
1973 _ILOAD_PUTFIELD_INT_ = ILOAD PUTFIELD_INT
1974 _GETFIELD_INT_ALOAD_GETFIELD_INT_ = GETFIELD_INT ALOAD GETFIELD_INT
1975 _GETFIELD_CELL_GETFIELD_CELL_ = GETFIELD_CELL GETFIELD_CELL
1976 _ALOAD_ACONST_ACONST_ = ALOAD ACONST ACONST
1977 _ALOAD_ARRAYLENGTH_ = ALOAD ARRAYLENGTH
1978 _GETFIELD_CELL_IFNULL_ = GETFIELD_CELL IFNULL
1979 _ICONST_ISUB_ = ICONST ISUB
1980 _ALOAD_ILOAD_PUTFIELD_INT_ = ALOAD ILOAD PUTFIELD_INT
1981 _ALOAD_GETFIELD_CELL_GETFIELD_CELL_ = ALOAD GETFIELD_CELL GETFIELD_CELL
1982 _PUTFIELD_CELL_ALOAD_ALOAD_ = PUTFIELD_CELL ALOAD ALOAD
1983 _ILOAD_AALOAD_ = ILOAD AALOAD
1984 _ALOAD_MONITOREXIT_ = ALOAD MONITOREXIT
1985 _ALOAD_CHECKCAST_ = ALOAD CHECKCAST
1986 _ALOAD_GETFIELD_CELL_ICONST_ = ALOAD GETFIELD_CELL ICONST
1987 _ICONST_ILOAD_ = ICONST ILOAD
1988 _ACONST_ICONST_ICONST_ = ACONST ICONST ICONST
1989 _ALOAD_GETFIELD_CELL_IFNULL_ = ALOAD GETFIELD_CELL IFNULL