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" fieldinfo *" single data-stack type-prefix afi
58 \E s" Cell *" single data-stack type-prefix acell
59 \E s" Inst *" single data-stack type-prefix ainst
60 \E s" unresolved_field *" single data-stack type-prefix auf
61 \E s" unresolved_method *" single data-stack type-prefix aum
62 \E s" vftbl_t *" single data-stack type-prefix avftbl
63 \E inst-stream stack-prefix #
65 \ The stack variables have the following types:
79 \ Starting a name with # indicates an inline argument instead of a stack
80 \ argument; the rest of the name matches as usual.
84 \ How does prims2x know the length of each instruction,
85 \ where the instruction has immediate operands. We need
86 \ some way to communicate this or compute it.
88 \ Some instructions don't care about the type of the
89 \ values that they work with. For example, POP doesn't
90 \ care what type the value on the top of the stack is.
91 \ We need to communicate this.
92 \ I'll add a type v (for void, or variable, whichever you
93 \ prefer) which just means there's one element of the normal
94 \ size on the stack, and we don't care what its type is.
98 \ Define the following macros before including this file.
100 \ # define instr(name,opcode,label,len,syntax,body)
101 \ # define undef(name,opcode,label,len,syntax,body)
102 \ # define custm(name,opcode,label,len,syntax,body)
105 \ To avoid race conditions, rewriting proceeds as follows:
106 \ 1) the needed operands are fetched from the orignal byte code
107 \ 2) the new operands are written
108 \ 3) the new operator is written
109 \ 4) the quick-version of the instruction is executed.
111 \ Note: the byte code remains unchanged.
117 \E register IPTOS Cell
118 \E register spTOS Cell
120 \E create IPregs IPTOS ,
121 \E create regs spTOS ,
123 \E IPregs 1 0 stack-state IPss1
124 \E regs 1 0 stack-state ss0
126 \ the first of these is the default state
129 \E ss0 data-stack S0 set-ss
131 \E IPss1 inst-stream S0 set-ss
133 \E data-stack to cache-stack
134 \E here 1 cache-states 2! s0 ,
136 \ !! the following should be automatic
137 \E S0 to state-default
138 \E state-default to state-in
139 \E state-default to state-out
141 \E s" codegendata *" threaded-code-pointer-type 2!
143 \ This is stub code for methods that we have not yet translated.
144 \ Initially, the code for each method is set to this stub. The
145 \ first time the method is called, the code in the stub runs, which
146 \ translates the bytecode, and replaces the stub with the threaded code.
148 \ instr(NOP, 0, nop, 1, op, {})
150 ICONST ( #vConst -- vConst ) opt
152 LCONST ( #l -- l ) opt
154 ACONST ( #aRef -- aRef ) opt
156 ACONST1 ( #aRef #acrUnused -- aRef ) opt
158 PATCHER_ACONST ( #aRef #acr ... -- )
162 stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
163 result = intrp_patcher_aconst((u1 *) (IP - 3));
164 stacktrace_remove_stackframeinfo(&sfi);
168 STORE_ORDER_BARRIER();
169 IP[-3] = INST_ADDR(ACONST1);
171 patchersuper_rewrite(IP);
173 ILOAD ( #vLocal -- vResult ) 0x15
175 vResult = access_local_int(vLocal);
178 LLOAD ( #vLocal -- lResult ) 0x16
180 vm_twoCell2l(access_local_cell(vLocal), access_local_cell(vLocal-SIZEOF_VOID_P), lResult);
183 ALOAD ( #vLocal -- aRef ) 0x19
185 aRef = (java_objectheader *)access_local_cell(vLocal);
188 IALOAD ( aArray iIndex -- vResult ) 0x2e
190 CHECK_NULL_PTR(aArray);
191 CHECK_OUT_OF_BOUNDS(aArray, iIndex);
193 vResult = access_array_int(aArray, iIndex);
196 FALOAD ( aArray iIndex -- fResult ) 0x2e
198 CHECK_NULL_PTR(aArray);
199 CHECK_OUT_OF_BOUNDS(aArray, iIndex);
201 fResult = access_array_float(aArray, iIndex);
204 LALOAD ( aArray iIndex -- lResult ) 0x2f
206 CHECK_NULL_PTR(aArray);
207 CHECK_OUT_OF_BOUNDS(aArray, iIndex);
209 lResult = access_array_long(aArray, iIndex);
212 AALOAD ( aArray iIndex -- aRef ) 0x32
214 CHECK_NULL_PTR(aArray);
215 CHECK_OUT_OF_BOUNDS(aArray, iIndex);
217 aRef = access_array_addr(aArray, iIndex);
220 BALOAD ( aArray iIndex -- vResult ) 0x33
222 CHECK_NULL_PTR(aArray);
223 CHECK_OUT_OF_BOUNDS(aArray, iIndex);
225 vResult = access_array_byte(aArray, iIndex);
228 CALOAD ( aArray iIndex -- vResult ) 0x34
230 CHECK_NULL_PTR(aArray);
231 CHECK_OUT_OF_BOUNDS(aArray, iIndex);
233 vResult = access_array_char(aArray, iIndex);
236 SALOAD ( aArray iIndex -- vResult ) 0x35
238 CHECK_NULL_PTR(aArray);
239 CHECK_OUT_OF_BOUNDS(aArray, iIndex);
241 vResult = access_array_short(aArray, iIndex);
244 ISTORE ( #vLocal vValue -- ) 0x36
246 access_local_int(vLocal) = vValue;
249 LSTORE ( #vLocal lValue -- ) 0x37
251 vm_l2twoCell(lValue, access_local_cell(vLocal), access_local_cell(vLocal-SIZEOF_VOID_P));
254 ASTORE ( #vLocal aRef -- ) 0x3a
256 access_local_cell(vLocal) = (Cell)aRef;
259 IASTORE ( aArray iIndex iValue -- ) 0x4f
261 CHECK_NULL_PTR(aArray);
262 CHECK_OUT_OF_BOUNDS(aArray, iIndex);
264 access_array_int(aArray, iIndex) = iValue;
267 FASTORE ( aArray iIndex fValue -- ) 0x4f
269 CHECK_NULL_PTR(aArray);
270 CHECK_OUT_OF_BOUNDS(aArray, iIndex);
272 access_array_float(aArray, iIndex) = fValue;
275 LASTORE ( aArray iIndex lValue -- ) 0x50
277 CHECK_NULL_PTR(aArray);
278 CHECK_OUT_OF_BOUNDS(aArray, iIndex);
280 access_array_long(aArray, iIndex) = lValue;
283 AASTORE ( aArray iIndex aRef -- ) 0x53
285 CHECK_NULL_PTR(aArray);
286 CHECK_OUT_OF_BOUNDS(aArray, iIndex);
287 if (!builtin_canstore((java_objectarray *)aArray, aRef))
288 THROW(arraystoreexception);
289 access_array_addr(aArray, iIndex) = aRef;
292 BASTORE ( aArray iIndex iValue -- ) 0x54
294 CHECK_NULL_PTR(aArray);
295 CHECK_OUT_OF_BOUNDS(aArray, iIndex);
297 access_array_byte(aArray, iIndex) = iValue;
300 CASTORE ( aArray iIndex iValue -- ) 0x55
302 CHECK_NULL_PTR(aArray);
303 CHECK_OUT_OF_BOUNDS(aArray, iIndex);
305 access_array_char(aArray, iIndex) = iValue;
308 POP ( vValue -- ) 0x57
310 POP2 ( vValue vValue -- ) 0x58
312 DUP ( vValue -- vValue vValue ) 0x59
314 DUP_X1 ( vValue2 vValue1 -- vValue1 vValue2 vValue1 ) 0x5a
316 DUP_X2 ( vValue3 vValue2 vValue1 -- vValue1 vValue3 vValue2 vValue1 ) 0x5b
318 DUP2 ( vValue2 vValue1 -- vValue2 vValue1 vValue2 vValue1 ) 0x5c
320 DUP2_X1 (vValue3 vValue2 vValue1 -- vValue2 vValue1 vValue3 vValue2 vValue1 ) 0x5d
322 DUP2_X2 ( vValue4 vValue3 vValue2 vValue1 -- vValue2 vValue1 vValue4 vValue3 vValue2 vValue1 ) 0x5e
324 SWAP ( vValue2 vValue1 -- vValue1 vValue2 ) 0x5f
326 IADD ( vValue1 vValue2 -- vResult ) 0x60
328 vResult = vValue2 + vValue1;
331 LADD ( lValue1 lValue2 -- lResult ) 0x61
333 lResult = lValue2 + lValue1;
336 FADD ( fValue1 fValue2 -- fResult ) 0x62
338 fResult = fValue1 + fValue2;
341 DADD ( dValue1 dValue2 -- dResult ) 0x63
343 dResult = dValue1 + dValue2;
346 ISUB ( vValue1 vValue2 -- vResult ) 0x64
348 vResult = vValue1 - vValue2;
351 LSUB ( lValue1 lValue2 -- lResult ) 0x65
353 lResult = lValue1 - lValue2;
356 FSUB ( fValue1 fValue2 -- fResult ) 0x66
358 fResult = fValue1 - fValue2;
361 DSUB ( dValue1 dValue2 -- dResult ) 0x67
363 dResult = dValue1 - dValue2;
366 IMUL ( vValue1 vValue2 -- vResult ) 0x68
368 vResult = vValue1 * vValue2;
371 LMUL ( lValue1 lValue2 -- lResult ) 0x69
373 lResult = lValue1 * lValue2;
376 FMUL ( fValue1 fValue2 -- fResult ) 0x6a
378 fResult = fValue1 * fValue2;
381 DMUL ( dValue1 dValue2 -- dResult ) 0x6b
383 dResult = dValue1 * dValue2;
386 IDIV ( iValue1 iValue2 -- iResult ) 0x6c
388 CHECK_ZERO_DIVISOR(iValue2);
390 if (iValue1 == 0x80000000 && iValue2 == -1)
393 iResult = iValue1 / iValue2;
396 IDIVPOW2 ( i1 #ishift -- i2 ) opt
399 s4 offset = sign >> (32-ishift);
400 i2=(i1+offset)>>ishift;
403 LDIV ( lValue1 lValue2 -- lResult ) 0x6d
405 CHECK_ZERO_DIVISOR(lValue2);
406 if (lValue1 == 0x8000000000000000LL && lValue2 == -1)
409 lResult = lValue1 / lValue2;
412 LDIVPOW2 ( l1 #ishift -- l2 )
415 s8 offset = sign >> (64-ishift);
416 l2=(l1+offset)>>ishift;
419 FDIV ( fValue1 fValue2 -- fResult ) 0x6e
421 fResult = fValue1 / fValue2;
424 DDIV ( dValue1 dValue2 -- dResult ) 0x6f
426 dResult = dValue1 / dValue2;
430 IREM ( iValue1 iValue2 -- iResult ) 0x70
432 CHECK_ZERO_DIVISOR(iValue2);
433 if (iValue1 == 0x80000000 && iValue2 == -1)
436 iResult = iValue1 % iValue2;
439 IREMPOW2 ( i1 #imask -- i2 )
446 LREM ( lValue1 lValue2 -- lResult ) 0x71
448 CHECK_ZERO_DIVISOR(lValue2);
449 if (lValue1 == 0x8000000000000000LL && lValue2 == -1)
452 lResult = lValue1 % lValue2;
455 LREMPOW2 ( l1 #lmask -- l2 )
462 FREM ( fValue1 fValue2 -- fResult ) 0x72
464 fResult = builtin_frem(fValue1, fValue2);
467 DREM ( dValue1 dValue2 -- dResult ) 0x73
469 dResult = builtin_drem(dValue1, dValue2);
472 INEG ( vValue -- vResult ) 0x74
477 LNEG ( lValue -- lResult ) 0x75
482 FNEG ( fValue -- fResult ) 0x76
487 DNEG ( dValue -- dResult ) 0x77
492 ISHL ( vValue1 vValue2 -- vResult ) 0x78
494 vResult = vValue1 << (vValue2 & 31);
497 LSHL ( lValue1 vValue2 -- lResult ) 0x79
499 lResult = lValue1 << (vValue2 & 63);
502 ISHR ( iValue1 iValue2 -- iResult ) 0x7a
504 iResult = iValue1 >> (iValue2 & 31);
507 LSHR ( lValue1 iValue2 -- lResult ) 0x7b
509 lResult = lValue1 >> (iValue2 & 63);
512 IUSHR ( iValue1 vValue2 -- iResult ) 0x7c
514 iResult = ((unsigned) iValue1) >> (vValue2 & 31);
517 LUSHR ( lValue1 vValue2 -- lResult ) 0x7d
519 lResult = (unsigned long long) lValue1 >> (vValue2 & 63);
522 IAND ( vValue1 vValue2 -- vResult ) 0x7e
524 vResult = vValue1 & vValue2;
527 LAND ( lValue1 lValue2 -- lResult ) 0x7f
529 lResult = lValue1 & lValue2;
532 IOR ( vValue1 vValue2 -- vResult ) 0x80
534 vResult = vValue1 | vValue2;
537 LOR ( lValue1 lValue2 -- lResult ) 0x81
539 lResult = lValue1 | lValue2;
542 IXOR ( vValue1 vValue2 -- vResult ) 0x82
544 vResult = vValue1 ^ vValue2;
547 LXOR ( lValue1 lValue2 -- lResult ) 0x83
549 lResult = lValue1 ^ lValue2;
552 IINC ( #vOffset #iConst -- ) 0x84
554 access_local_int(vOffset) += iConst;
557 I2L ( iValue -- lValue ) 0x85
562 I2F ( iValue -- fValue ) 0x86
564 fValue = (float) iValue;
567 I2D ( iValue -- dValue ) 0x87
569 dValue = (double) iValue;
572 L2I ( lValue -- iValue ) 0x88
577 L2F ( lValue -- fValue ) 0x89
579 fValue = (float) lValue;
582 L2D ( lValue -- dValue ) 0x8a
584 dValue = (double) lValue;
587 F2I ( fValue -- iValue ) 0x8b
589 iValue = builtin_f2i(fValue);
592 F2L ( fValue -- lValue ) 0x8c
594 lValue = builtin_f2l(fValue);
597 F2D ( fValue -- dValue ) 0x8d
602 D2I ( dValue -- iValue ) 0x8e
604 iValue = builtin_d2i(dValue);
607 D2L ( dValue -- lValue ) 0x8f
609 lValue = builtin_d2l(dValue);
612 D2F ( dValue -- fValue ) 0x90
617 INT2BYTE ( iValue -- iResult ) 0x91
619 iResult = (iValue << 24) >> 24; /* XXX: try "(s1)iValue" */
623 INT2CHAR ( iValue -- iResult ) 0x92
625 iResult = iValue & 0xFFFF;
628 INT2SHORT ( iValue -- iResult ) 0x93
630 iResult = (iValue << 16) >> 16; /* XXX: try "(s2)iValue" */
633 LCMP ( lValue1 lValue2 -- vResult ) 0x94
635 vResult = lValue1 < lValue2 ? -1 : lValue1 > lValue2 ? 1 : 0;
638 FCMPL ( fValue1 fValue2 -- vResult ) 0x95
640 vResult = builtin_fcmpl(fValue1, fValue2);
643 FCMPG ( fValue1 fValue2 -- vResult ) 0x96
645 vResult = builtin_fcmpg(fValue1, fValue2);
648 DCMPL ( dValue1 dValue2 -- iResult ) 0x97
650 iResult = builtin_dcmpl(dValue1, dValue2);
653 DCMPG ( dValue1 dValue2 -- iResult ) 0x98
655 iResult = builtin_dcmpg(dValue1, dValue2);
658 IFEQ ( #ainstTarget iValue -- ) 0x99
665 IFNE ( #ainstTarget iValue -- ) 0x9a
672 IFLT ( #ainstTarget iValue -- ) 0x9b
678 IFGE ( #ainstTarget iValue -- ) 0x9c
684 IFGT ( #ainstTarget iValue -- ) 0x9d
690 IFLE ( #ainstTarget iValue -- ) 0x9e
696 IF_ICMPEQ ( #ainstTarget iValue1 iValue2 -- ) 0x9f
698 if ( iValue1 == iValue2 )
702 IF_ICMPNE ( #ainstTarget iValue1 iValue2 -- ) 0xa0
704 if ( iValue1 != iValue2 )
708 IF_ICMPLT ( #ainstTarget iValue1 iValue2 -- ) 0xa1
710 if ( iValue1 < iValue2 )
714 IF_ICMPGE ( #ainstTarget iValue1 iValue2 -- ) 0xa2
716 if ( iValue1 >= iValue2 )
720 IF_ICMPGT ( #ainstTarget iValue1 iValue2 -- ) 0xa3
722 if ( iValue1 > iValue2 )
726 IF_ICMPLE ( #ainstTarget iValue1 iValue2 -- ) 0xa4
728 if ( iValue1 <= iValue2 )
732 IF_LCMPEQ ( #ainstTarget lValue1 lValue2 -- ) opt
734 if ( lValue1 == lValue2 )
738 IF_LCMPNE ( #ainstTarget lValue1 lValue2 -- ) opt
740 if ( lValue1 != lValue2 )
744 IF_LCMPLT ( #ainstTarget lValue1 lValue2 -- ) opt
746 if ( lValue1 < lValue2 )
750 IF_LCMPGE ( #ainstTarget lValue1 lValue2 -- ) opt
752 if ( lValue1 >= lValue2 )
756 IF_LCMPGT ( #ainstTarget lValue1 lValue2 -- ) opt
758 if ( lValue1 > lValue2 )
762 IF_LCMPLE ( #ainstTarget lValue1 lValue2 -- ) opt
764 if ( lValue1 <= lValue2 )
768 IF_ACMPEQ ( #ainstTarget aRef1 aRef2 -- ) 0xa5
770 if ( aRef1 == aRef2 )
774 IF_ACMPNE ( #ainstTarget aRef1 aRef2 -- ) 0xa6
776 if ( aRef1 != aRef2 )
780 GOTO ( #ainstTarget -- ) 0xa7
785 JSR ( #ainstTarget -- ainstRA ) 0xa8
787 /* Warning: The generator already adds 1 to the IP
788 because there is an inline parameter. Thus, instead
789 of writing IP + 1, we write...*/
794 RET ( #vOffset -- ) 0xa9
797 saved_ip = access_local_ref(vOffset);
801 TABLESWITCH ( #iLow #iRange #addrSegment #iOffset #ainstDefault iIndex -- ) 0xaa
803 s4 idx = iIndex - iLow;
804 if ( ((u4) idx) >= iRange ) {
805 SET_IP(ainstDefault);
808 SET_IP(((Inst **)(addrSegment+iOffset))[idx]);
812 LOOKUPSWITCH ( #iNpairs #addrSegment #iOffset #ainstDefault iKey -- ) 0xab
814 /* Note: This code should use a binary search, as
815 the table is sorted. Note also, we reversed the order
822 Cell *table = (Cell *) (addrSegment+iOffset);
823 if (iKey == (s4) (table[2 * i])) {
824 SET_IP((Inst *)(table[2 * i + 1])); INST_TAIL;
827 /* falls through if no match */
828 SET_IP(ainstDefault);
832 \ Our stack works like this:
833 \ The stack holds locals, the operand stack and the return address stack.
834 \ When we invoke a method, the paramaters are the top N elements
835 \ on the stack. These become the first N local variables.
836 \ Next we have space for the rest of the local variables.
837 \ Next comes a single position on the stack which holds
838 \ the value of the frame pointer for the calling function.
839 \ Another position holds the instruction pointer of the caller.
840 \ Finally, we have space for the elements of the operand stack.
842 \ fp points to the bottom local; since the stack grows downwards, the
843 \ upper end of the frame is fp+1, not fp. That's why the sp updates
844 \ in the returns look like they are off by one.
850 \ sp -> oldip ; at the start, empty stack
851 \ stack0 ;once there is something on the stack
854 IRETURN ( #vOffsetFP ... vValue -- vResult ) 0xac
857 MAYBE_UNUSED Cell *currentsp = sp;
858 new_ip = (Inst *) access_local_cell(vOffsetFP - SIZEOF_VOID_P);
860 fp = (Cell *) access_local_cell(vOffsetFP);
861 CLEARSTACK(currentsp - 6, sp - 1);
866 LRETURN ( #vOffsetFP ... lValue -- lResult ) 0xad
869 MAYBE_UNUSED Cell *currentsp = sp;
870 new_ip = (Inst *) access_local_cell(vOffsetFP - SIZEOF_VOID_P);
872 fp = (Cell *) access_local_cell(vOffsetFP);
873 CLEARSTACK(currentsp - 7, sp - 2);
878 RETURN ( #vOffsetFP ... -- ) 0xb1
881 MAYBE_UNUSED Cell *currentsp = sp;
882 new_ip = (Inst *) access_local_cell(vOffsetFP - SIZEOF_VOID_P);
884 fp = (Cell *) access_local_cell(vOffsetFP);
885 CLEARSTACK(currentsp - 5, sp - 1);
889 GETSTATIC_CELL ( #addr #afi -- vResult ) opt
891 vResult = *(Cell *)addr;
894 GETSTATIC_INT ( #addr #afi -- iResult ) opt
896 iResult = *(s4 *)addr;
899 GETSTATIC_FLOAT ( #addr #afi -- fResult ) opt
901 fResult = *(float *)addr;
904 GETSTATIC_LONG ( #addr #afi -- lResult ) opt
906 lResult = *((s8 *) addr);
909 PUTSTATIC_CELL ( #addr #afi vValue -- ) opt
911 *((Cell *) addr) = vValue;
914 PUTSTATIC_INT ( #addr #afi iValue -- ) opt
916 *((s4 *) addr) = iValue;
919 PUTSTATIC_FLOAT ( #addr #afi fValue -- ) opt
921 *((float *) addr) = fValue;
924 PUTSTATIC_LONG ( #addr #afi lValue -- ) opt
926 *((s8 *) addr) = lValue;
929 GETFIELD_CELL ( #vOffset #afi aRef -- vResult ) opt
931 CHECK_NULL_PTR(aRef);
932 vResult = *((Cell *) (((u1 *)aRef) + vOffset));
935 GETFIELD_INT ( #vOffset #afi aRef -- iResult ) opt
937 CHECK_NULL_PTR(aRef);
938 iResult = *((s4 *) (((u1 *)aRef) + vOffset));
941 GETFIELD_FLOAT ( #vOffset #afi aRef -- fResult ) opt
943 CHECK_NULL_PTR(aRef);
944 fResult = *((float *) (((u1 *) aRef) + vOffset));
947 GETFIELD_LONG ( #vOffset #afi aRef -- lResult ) opt
949 CHECK_NULL_PTR(aRef);
950 lResult = *((s8 *) (((u1 *)aRef) + vOffset));
954 PUTFIELD_CELL ( #vOffset #afi aRef vValue -- ) opt
956 CHECK_NULL_PTR(aRef);
957 *((Cell *) (((u1 *)aRef) + vOffset)) = vValue;
960 PUTFIELD_INT ( #vOffset #afi aRef iValue -- ) opt
962 CHECK_NULL_PTR(aRef);
963 *((s4 *) (((u1 *)aRef) + vOffset)) = iValue;
966 PUTFIELD_FLOAT ( #vOffset #afi aRef fValue -- ) opt
968 CHECK_NULL_PTR(aRef);
969 *((float *) (((u1 *)aRef) + vOffset)) = fValue;
972 PUTFIELD_LONG ( #vOffset #afi aRef lValue -- ) opt
974 CHECK_NULL_PTR(aRef);
975 *((s8 *) (((u1 *)aRef) + vOffset)) = lValue;
978 \ !! called methods have the number of locals at offset -1.
979 \ methods are always called indirectly through the codeptr in the stub
980 \ (see createcompilerstub and TRANSLATE).
982 INVOKEVIRTUAL ( #vOffset #iNargs #am ... -- ... acelloldfp ainstoldip ) 0xd8
984 java_objectheader *aRef = (java_objectheader *)(sp[iNargs - 1]);
988 CHECK_NULL_PTR(aRef);
989 v = (char *)(aRef->vftbl);
990 stub = *(Inst ***)(v+vOffset);
994 fp = sp - 1 + iNargs;
995 sp = fp - FRAMESIZE(stub) + 1;
999 INVOKESTATIC ( #aaTarget #iNargs #am ... -- ... acelloldfp ainstoldip ) 0xb8
1000 /* an indirect pointer to target is passed to avoid references to uncompiled code */
1002 Inst *target = *aaTarget;
1005 fp = sp - 1 + iNargs; /* !! scale nargs at translation time */
1006 sp = fp - FRAMESIZE(aaTarget) + 1;
1010 INVOKESPECIAL ( #aaTarget #iNargs #am ... -- ... acelloldfp ainstoldip ) 0xb7
1011 /* an indirect pointer to target is passed to avoid references to uncompiled code */
1013 java_objectheader *aRef = (java_objectheader *)(sp[iNargs - 1]);
1014 Inst *target = *aaTarget;
1015 CHECK_NULL_PTR(aRef);
1018 fp = sp - 1 + iNargs; /* !! scale nargs at translation time */
1019 sp = fp - FRAMESIZE(aaTarget) + 1;
1023 INVOKEINTERFACE ( #iInterfaceOffset #vOffset #iNargs #am ... -- ... acelloldfp ainstoldip ) 0xd8
1025 java_objectheader *aRef;
1030 aRef = (java_objectheader *)sp[iNargs - 1];
1031 CHECK_NULL_PTR(aRef);
1032 v = (char *)(aRef->vftbl);
1033 t = *(char **)(v + iInterfaceOffset);
1034 stub = *(Inst ***)(t+vOffset);
1038 fp = sp - 1 + iNargs;
1039 sp = fp - FRAMESIZE(stub) + 1;
1043 \ the BUILTIN functions like NEW get their parameters on the stack
1044 \ instead of through immediate arguments.
1046 \ !! do we need to synchronize the stack here?
1047 \ !! if so, is global_sp right?
1049 NEW ( ... aClass -- ... aRef ) 0xbb
1052 aRef = builtin_new((classinfo *) aClass);
1055 *exceptionptr = stacktrace_inline_fillInStackTrace(NULL, (u1 *) fp, (u1 *) IP, (u1 *) IP);
1064 NEWARRAY_BOOLEAN ( ... iSize -- ... aArray )
1067 aArray = (java_arrayheader *) builtin_newarray_boolean(iSize);
1068 if (aArray == NULL) {
1070 *exceptionptr = stacktrace_inline_fillInStackTrace(NULL, (u1 *) fp, (u1 *) IP, (u1 *) IP);
1077 NEWARRAY_BYTE ( ... iSize -- ... aArray )
1080 aArray = (java_arrayheader *) builtin_newarray_byte(iSize);
1081 if (aArray == NULL) {
1083 *exceptionptr = stacktrace_inline_fillInStackTrace(NULL, (u1 *) fp, (u1 *) IP, (u1 *) IP);
1090 NEWARRAY_CHAR ( ... iSize -- ... aArray )
1093 aArray = (java_arrayheader *) builtin_newarray_char(iSize);
1094 if (aArray == NULL) {
1096 *exceptionptr = stacktrace_inline_fillInStackTrace(NULL, (u1 *) fp, (u1 *) IP, (u1 *) IP);
1103 NEWARRAY_SHORT ( ... iSize -- ... aArray )
1106 aArray = (java_arrayheader *) builtin_newarray_short(iSize);
1107 if (aArray == NULL) {
1109 *exceptionptr = stacktrace_inline_fillInStackTrace(NULL, (u1 *) fp, (u1 *) IP, (u1 *) IP);
1116 NEWARRAY_INT ( ... iSize -- ... aArray )
1119 aArray = (java_arrayheader *) builtin_newarray_int(iSize);
1120 if (aArray == NULL) {
1122 *exceptionptr = stacktrace_inline_fillInStackTrace(NULL, (u1 *) fp, (u1 *) IP, (u1 *) IP);
1129 NEWARRAY_LONG ( ... iSize -- ... aArray )
1132 aArray = (java_arrayheader *) builtin_newarray_long(iSize);
1133 if (aArray == NULL) {
1135 *exceptionptr = stacktrace_inline_fillInStackTrace(NULL, (u1 *) fp, (u1 *) IP, (u1 *) IP);
1142 NEWARRAY_FLOAT ( ... iSize -- ... aArray )
1145 aArray = (java_arrayheader *) builtin_newarray_float(iSize);
1146 if (aArray == NULL) {
1148 *exceptionptr = stacktrace_inline_fillInStackTrace(NULL, (u1 *) fp, (u1 *) IP, (u1 *) IP);
1155 NEWARRAY_DOUBLE ( ... iSize -- ... aArray )
1158 aArray = (java_arrayheader *) builtin_newarray_double(iSize);
1159 if (aArray == NULL) {
1161 *exceptionptr = stacktrace_inline_fillInStackTrace(NULL, (u1 *) fp, (u1 *) IP, (u1 *) IP);
1168 NEWARRAY ( ... iSize aClass -- ... aArray )
1171 aArray = (java_arrayheader *) builtin_newarray(iSize, aClass);
1172 if (aArray == NULL) {
1174 *exceptionptr = stacktrace_inline_fillInStackTrace(NULL, (u1 *) fp, (u1 *) IP, (u1 *) IP);
1181 ARRAYLENGTH ( aArray -- iResult )
1183 CHECK_NULL_PTR(aArray);
1184 iResult = length_array(aArray);
1187 ATHROW ( ... aRef -- ... aRef1 )
1189 Cell *new_sp, *new_fp;
1191 CHECK_NULL_PTR(aRef);
1195 aRef = *exceptionptr;
1196 *exceptionptr = NULL;
1198 new_ip = intrp_asm_handle_exception(IP, aRef, fp, &new_sp, &new_fp);
1199 if (new_ip == NULL) {
1200 /* !! sp = new_sp; ? */
1202 SUPER_END; /* ATHROW may end a basic block */
1211 CHECKCAST ( #aClass #acr aRef -- aRef ) 0xc0
1213 if (!builtin_checkcast(aRef, (classinfo *) aClass))
1214 THROW_CLASSCASTEXCEPTION(aRef);
1217 ARRAYCHECKCAST ( #aClass #acr aRef -- aRef ) 0xc0
1219 if (!builtin_arraycheckcast(aRef, aClass))
1220 THROW_CLASSCASTEXCEPTION(aRef);
1223 PATCHER_ARRAYCHECKCAST ( #avftbl #acr ... -- ) 0xc0
1227 stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
1228 result = intrp_patcher_builtin_arraycheckcast((u1 *) (IP - 3));
1229 stacktrace_remove_stackframeinfo(&sfi);
1233 STORE_ORDER_BARRIER();
1234 IP[-3] = INST_ADDR(ARRAYCHECKCAST);
1236 patchersuper_rewrite(IP);
1238 INSTANCEOF ( #aClass #acr aRef -- iResult )
1240 iResult = builtin_instanceof(aRef, aClass);
1243 ARRAYINSTANCEOF ( aRef aClass -- iResult )
1245 iResult = builtin_arrayinstanceof(aRef, aClass);
1248 MONITORENTER ( aRef -- )
1250 #if defined(ENABLE_THREADS)
1251 /* CHECK_NULL_PTR(aRef); is now done explicitly inside lock_monitor_enter */
1253 if (!lock_monitor_enter(aRef))
1259 MONITOREXIT ( aRef -- )
1261 #if defined(ENABLE_THREADS)
1263 if (!lock_monitor_exit(aRef))
1269 CHECKNULL ( aRef -- aRef )
1271 CHECK_NULL_PTR(aRef);
1274 MULTIANEWARRAY ( #aClass #iSize #acr ... -- aRef )
1279 dims = MNEW(long, iSize);
1281 for (i = 0; i < iSize; i++) {
1282 dims[i] = sp[iSize - i - 1];
1285 aRef = (java_objectheader *) builtin_multianewarray(iSize, aClass, dims);
1287 MFREE(dims, long, iSize);
1291 *exceptionptr = stacktrace_inline_fillInStackTrace(NULL, (u1 *) fp, (u1 *) IP, (u1 *) IP);
1299 IFNULL ( #ainstTarget aRef -- ) 0xc6
1301 if ( aRef == NULL ) {
1302 SET_IP(ainstTarget);
1306 IFNONNULL ( #ainstTarget aRef -- ) 0xc7
1308 if ( aRef != NULL ) {
1309 SET_IP(ainstTarget);
1313 \ patchers for resolving fields
1315 PATCHER_GETSTATIC_INT ( #aRef #auf ... -- )
1319 stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
1320 result = intrp_patcher_get_putstatic((u1 *) (IP - 3));
1321 stacktrace_remove_stackframeinfo(&sfi);
1325 STORE_ORDER_BARRIER();
1326 IP[-3] = INST_ADDR(GETSTATIC_INT);
1328 patchersuper_rewrite(IP);
1330 PATCHER_GETSTATIC_FLOAT ( #aRef #auf ... -- )
1334 stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
1335 result = intrp_patcher_get_putstatic((u1 *)(IP-3));
1336 stacktrace_remove_stackframeinfo(&sfi);
1340 STORE_ORDER_BARRIER();
1341 IP[-3] = INST_ADDR(GETSTATIC_FLOAT);
1343 patchersuper_rewrite(IP);
1345 PATCHER_GETSTATIC_LONG ( #aRef #auf ... -- )
1349 stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
1350 result = intrp_patcher_get_putstatic((u1 *) (IP - 3));
1351 stacktrace_remove_stackframeinfo(&sfi);
1355 STORE_ORDER_BARRIER();
1356 IP[-3] = INST_ADDR(GETSTATIC_LONG);
1358 patchersuper_rewrite(IP);
1360 PATCHER_GETSTATIC_CELL ( #aRef #auf ... -- )
1364 stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
1365 result = intrp_patcher_get_putstatic((u1 *) (IP - 3));
1366 stacktrace_remove_stackframeinfo(&sfi);
1370 STORE_ORDER_BARRIER();
1371 IP[-3] = INST_ADDR(GETSTATIC_CELL);
1373 patchersuper_rewrite(IP);
1375 \ patchers for statically initializing classes
1377 PATCHER_GETSTATIC_CLINIT_INT ( #aRef #afi ... -- )
1381 stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
1382 result = intrp_patcher_get_putstatic_clinit((u1 *) (IP - 3));
1383 stacktrace_remove_stackframeinfo(&sfi);
1387 STORE_ORDER_BARRIER();
1388 IP[-3] = INST_ADDR(GETSTATIC_INT);
1390 patchersuper_rewrite(IP);
1392 PATCHER_GETSTATIC_CLINIT_FLOAT ( #aRef #afi ... -- )
1396 stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
1397 result = intrp_patcher_get_putstatic_clinit((u1 *)(IP-3));
1398 stacktrace_remove_stackframeinfo(&sfi);
1402 STORE_ORDER_BARRIER();
1403 IP[-3] = INST_ADDR(GETSTATIC_FLOAT);
1405 patchersuper_rewrite(IP);
1407 PATCHER_GETSTATIC_CLINIT_LONG ( #aRef #afi ... -- )
1411 stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
1412 result = intrp_patcher_get_putstatic_clinit((u1 *) (IP - 3));
1413 stacktrace_remove_stackframeinfo(&sfi);
1417 STORE_ORDER_BARRIER();
1418 IP[-3] = INST_ADDR(GETSTATIC_LONG);
1420 patchersuper_rewrite(IP);
1422 PATCHER_GETSTATIC_CLINIT_CELL ( #aRef #afi ... -- )
1426 stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
1427 result = intrp_patcher_get_putstatic_clinit((u1 *) (IP - 3));
1428 stacktrace_remove_stackframeinfo(&sfi);
1432 STORE_ORDER_BARRIER();
1433 IP[-3] = INST_ADDR(GETSTATIC_CELL);
1435 patchersuper_rewrite(IP);
1437 \ patchers for resolving fields
1439 PATCHER_PUTSTATIC_INT ( #aRef #auf ... -- )
1443 stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
1444 result = intrp_patcher_get_putstatic((u1 *) (IP - 3));
1445 stacktrace_remove_stackframeinfo(&sfi);
1449 STORE_ORDER_BARRIER();
1450 IP[-3] = INST_ADDR(PUTSTATIC_INT);
1452 patchersuper_rewrite(IP);
1454 PATCHER_PUTSTATIC_FLOAT ( #aRef #auf ... -- )
1458 stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
1459 result = intrp_patcher_get_putstatic((u1 *)(IP-3));
1460 stacktrace_remove_stackframeinfo(&sfi);
1464 STORE_ORDER_BARRIER();
1465 IP[-3] = INST_ADDR(PUTSTATIC_FLOAT);
1467 patchersuper_rewrite(IP);
1469 PATCHER_PUTSTATIC_LONG ( #aRef #auf ... -- )
1473 stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
1474 result = intrp_patcher_get_putstatic((u1 *) (IP - 3));
1475 stacktrace_remove_stackframeinfo(&sfi);
1479 STORE_ORDER_BARRIER();
1480 IP[-3] = INST_ADDR(PUTSTATIC_LONG);
1482 patchersuper_rewrite(IP);
1484 PATCHER_PUTSTATIC_CELL ( #aRef #auf ... -- )
1488 stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
1489 result = intrp_patcher_get_putstatic((u1 *) (IP - 3));
1490 stacktrace_remove_stackframeinfo(&sfi);
1494 STORE_ORDER_BARRIER();
1495 IP[-3] = INST_ADDR(PUTSTATIC_CELL);
1497 patchersuper_rewrite(IP);
1499 \ patchers for statically initializing classes
1501 PATCHER_PUTSTATIC_CLINIT_INT ( #aRef #afi ... -- )
1505 stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
1506 result = intrp_patcher_get_putstatic_clinit((u1 *) (IP - 3));
1507 stacktrace_remove_stackframeinfo(&sfi);
1511 STORE_ORDER_BARRIER();
1512 IP[-3] = INST_ADDR(PUTSTATIC_INT);
1514 patchersuper_rewrite(IP);
1516 PATCHER_PUTSTATIC_CLINIT_FLOAT ( #aRef #afi ... -- )
1520 stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
1521 result = intrp_patcher_get_putstatic_clinit((u1 *)(IP-3));
1522 stacktrace_remove_stackframeinfo(&sfi);
1526 STORE_ORDER_BARRIER();
1527 IP[-3] = INST_ADDR(PUTSTATIC_FLOAT);
1529 patchersuper_rewrite(IP);
1531 PATCHER_PUTSTATIC_CLINIT_LONG ( #aRef #afi ... -- )
1535 stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
1536 result = intrp_patcher_get_putstatic_clinit((u1 *) (IP - 3));
1537 stacktrace_remove_stackframeinfo(&sfi);
1541 STORE_ORDER_BARRIER();
1542 IP[-3] = INST_ADDR(PUTSTATIC_LONG);
1544 patchersuper_rewrite(IP);
1546 PATCHER_PUTSTATIC_CLINIT_CELL ( #aRef #afi ... -- )
1550 stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
1551 result = intrp_patcher_get_putstatic_clinit((u1 *) (IP - 3));
1552 stacktrace_remove_stackframeinfo(&sfi);
1556 STORE_ORDER_BARRIER();
1557 IP[-3] = INST_ADDR(PUTSTATIC_CELL);
1559 patchersuper_rewrite(IP);
1561 \ patchers for resolving fields
1563 PATCHER_GETFIELD_INT ( #vOffset #auf ... -- )
1567 stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
1568 result = intrp_patcher_get_putfield((u1 *) (IP - 3));
1569 stacktrace_remove_stackframeinfo(&sfi);
1573 STORE_ORDER_BARRIER();
1574 IP[-3] = INST_ADDR(GETFIELD_INT);
1576 patchersuper_rewrite(IP);
1578 PATCHER_GETFIELD_FLOAT ( #vOffset #auf ... -- )
1582 stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
1583 result = intrp_patcher_get_putfield((u1 *)(IP-3));
1584 stacktrace_remove_stackframeinfo(&sfi);
1588 STORE_ORDER_BARRIER();
1589 IP[-3] = INST_ADDR(GETFIELD_FLOAT);
1591 patchersuper_rewrite(IP);
1593 PATCHER_GETFIELD_LONG ( #vOffset #auf ... -- )
1597 stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
1598 result = intrp_patcher_get_putfield((u1 *) (IP - 3));
1599 stacktrace_remove_stackframeinfo(&sfi);
1603 STORE_ORDER_BARRIER();
1604 IP[-3] = INST_ADDR(GETFIELD_LONG);
1606 patchersuper_rewrite(IP);
1608 PATCHER_GETFIELD_CELL ( #vOffset #auf ... -- )
1612 stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
1613 result = intrp_patcher_get_putfield((u1 *) (IP - 3));
1614 stacktrace_remove_stackframeinfo(&sfi);
1618 STORE_ORDER_BARRIER();
1619 IP[-3] = INST_ADDR(GETFIELD_CELL);
1621 patchersuper_rewrite(IP);
1623 PATCHER_PUTFIELD_INT ( #vOffset #auf ... -- )
1627 stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
1628 result = intrp_patcher_get_putfield((u1 *) (IP - 3));
1629 stacktrace_remove_stackframeinfo(&sfi);
1633 STORE_ORDER_BARRIER();
1634 IP[-3] = INST_ADDR(PUTFIELD_INT);
1636 patchersuper_rewrite(IP);
1638 PATCHER_PUTFIELD_FLOAT ( #vOffset #auf ... -- )
1642 stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
1643 result = intrp_patcher_get_putfield((u1 *)(IP-3));
1644 stacktrace_remove_stackframeinfo(&sfi);
1648 STORE_ORDER_BARRIER();
1649 IP[-3] = INST_ADDR(PUTFIELD_FLOAT);
1651 patchersuper_rewrite(IP);
1653 PATCHER_PUTFIELD_LONG ( #vOffset #auf ... -- )
1657 stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
1658 result = intrp_patcher_get_putfield((u1 *) (IP - 3));
1659 stacktrace_remove_stackframeinfo(&sfi);
1663 STORE_ORDER_BARRIER();
1664 IP[-3] = INST_ADDR(PUTFIELD_LONG);
1666 patchersuper_rewrite(IP);
1668 PATCHER_PUTFIELD_CELL ( #vOffset #auf ... -- )
1672 stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
1673 result = intrp_patcher_get_putfield((u1 *) (IP - 3));
1674 stacktrace_remove_stackframeinfo(&sfi);
1678 STORE_ORDER_BARRIER();
1679 IP[-3] = INST_ADDR(PUTFIELD_CELL);
1681 patchersuper_rewrite(IP);
1683 \ other patchers for lazy resolving
1685 PATCHER_MULTIANEWARRAY ( #aClass #iSize #acr ... -- )
1689 stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
1690 result = intrp_patcher_builtin_multianewarray((u1 *) (IP - 4));
1691 stacktrace_remove_stackframeinfo(&sfi);
1695 STORE_ORDER_BARRIER();
1696 IP[-4] = INST_ADDR(MULTIANEWARRAY);
1698 patchersuper_rewrite(IP);
1700 PATCHER_INVOKESTATIC ( #aaTarget #iNargs #aum ... -- ) 0xd8
1704 stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
1705 result = intrp_patcher_invokestatic_special((u1 *) (IP - 4));
1706 stacktrace_remove_stackframeinfo(&sfi);
1710 STORE_ORDER_BARRIER();
1711 IP[-4] = INST_ADDR(INVOKESTATIC);
1713 patchersuper_rewrite(IP);
1715 PATCHER_INVOKESPECIAL ( #aaTarget #iNargs #aum ... -- ) 0xd8
1719 stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
1720 result = intrp_patcher_invokestatic_special((u1 *) (IP - 4));
1721 stacktrace_remove_stackframeinfo(&sfi);
1725 STORE_ORDER_BARRIER();
1726 IP[-4] = INST_ADDR(INVOKESPECIAL);
1728 patchersuper_rewrite(IP);
1730 PATCHER_INVOKEVIRTUAL ( #vOffset #iNargs #aum ... -- ) 0xd8
1734 stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
1735 result = intrp_patcher_invokevirtual((u1 *) (IP - 4));
1736 stacktrace_remove_stackframeinfo(&sfi);
1740 STORE_ORDER_BARRIER();
1741 IP[-4] = INST_ADDR(INVOKEVIRTUAL);
1743 patchersuper_rewrite(IP);
1745 PATCHER_INVOKEINTERFACE ( #iInterfaceoffset #vOffset #iNargs #aum ... -- ) 0xd8
1749 stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
1750 result = intrp_patcher_invokeinterface((u1 *) (IP - 5));
1751 stacktrace_remove_stackframeinfo(&sfi);
1755 STORE_ORDER_BARRIER();
1756 IP[-5] = INST_ADDR(INVOKEINTERFACE);
1758 patchersuper_rewrite(IP);
1760 PATCHER_CHECKCAST ( #aClass #acr ... -- ) 0xc
1764 stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
1765 result = intrp_patcher_checkcast_instanceof((u1 *) (IP - 3));
1766 stacktrace_remove_stackframeinfo(&sfi);
1770 STORE_ORDER_BARRIER();
1771 IP[-3] = INST_ADDR(CHECKCAST);
1773 patchersuper_rewrite(IP);
1775 PATCHER_INSTANCEOF ( #aClass #acr ... -- ) 0xc1
1779 stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
1780 result = intrp_patcher_checkcast_instanceof((u1 *) (IP - 3));
1781 stacktrace_remove_stackframeinfo(&sfi);
1785 STORE_ORDER_BARRIER();
1786 IP[-3] = INST_ADDR(INSTANCEOF);
1788 patchersuper_rewrite(IP);
1790 \ This is stub code for methods that we have not yet translated.
1791 \ Initially, the code for each method is set to this stub. The
1792 \ first time the method is called, the code in the stub runs, which
1793 \ translates the bytecode, and replaces the stub with the threaded code.
1795 TRANSLATE ( #am ... -- )
1802 vm_Cell2acell(sp[1],acelloldfp);
1803 vm_Cell2ainst(sp[0],ainstoldip);
1805 stacktrace_create_extern_stackframeinfo(&sfi, NULL, (u1 *) acelloldfp, (u1 *) ainstoldip, (u1 *) ainstoldip);
1806 codeptr = (Inst *) jit_compile(am);
1807 stacktrace_remove_stackframeinfo(&sfi);
1808 if (codeptr == NULL) {
1810 SET_IP(ainstoldip); /* set up ip and fp for throw */
1818 NATIVECALL ( #am #af #addrcif ... acelloldfp ainstoldip -- )
1819 sp = nativecall(af, am, sp, ainstoldip, acelloldfp, addrcif);
1826 TRACENATIVECALL ( #am #af #addrcif ... acelloldfp ainstoldip -- )
1827 sp = nativecall(af, am, sp, ainstoldip, acelloldfp, addrcif);
1834 #if !defined(NDEBUG)
1835 builtin_verbosecall_exit((s8) v, f, f, am);
1841 PATCHER_NATIVECALL ( #am #af #addrcif ... -- )
1842 #if !defined(WITH_STATIC_CLASSPATH)
1846 stacktrace_create_stackframeinfo(&sfi, NULL, (u1 *) fp, (u1 *) IP);
1847 result = intrp_patcher_resolve_native((u1 *) (IP - 4));
1848 stacktrace_remove_stackframeinfo(&sfi);
1852 STORE_ORDER_BARRIER();
1853 IP[-4] = opt_verbosecall ? INST_ADDR(TRACENATIVECALL) : INST_ADDR(NATIVECALL);
1855 patchersuper_rewrite(IP);
1860 TRACECALL ( #am -- )
1861 #if !defined(NDEBUG)
1862 #if SIZEOF_VOID_P == 4
1864 s8 args[TRACE_ARGS_NUM];
1867 typedesc *params = am->parseddesc->paramtypes;
1868 for (i=0; i < TRACE_ARGS_NUM; ++i, ++params) {
1869 if (IS_2_WORD_TYPE(params->type)) {
1870 vm_twoCell2l(access_local_cell(ofs), access_local_cell(ofs - SIZEOF_VOID_P), args[i]);
1871 ofs -= 2*SIZEOF_VOID_P;
1874 args[i] = access_local_cell(ofs);
1875 ofs -= SIZEOF_VOID_P;
1878 builtin_verbosecall_enter(args[0], args[1], args[2], args[3],
1879 #if TRACE_ARGS_NUM > 4
1882 #if TRACE_ARGS_NUM == 8
1887 #else /* SIZEOF_VOID_P */
1888 builtin_verbosecall_enter(
1889 access_local_cell(0 * -SIZEOF_VOID_P),
1890 access_local_cell(1 * -SIZEOF_VOID_P),
1891 access_local_cell(2 * -SIZEOF_VOID_P),
1892 access_local_cell(3 * -SIZEOF_VOID_P),
1893 #if TRACE_ARGS_NUM > 4
1894 access_local_cell(4 * -SIZEOF_VOID_P),
1895 access_local_cell(5 * -SIZEOF_VOID_P),
1897 #if TRACE_ARGS_NUM == 8
1898 access_local_cell(6 * -SIZEOF_VOID_P),
1899 access_local_cell(7 * -SIZEOF_VOID_P),
1902 #endif /* SIZEOF_VOID_P */
1903 #endif /* !defined(NDEBUG) */
1905 TRACERETURN ( #am v -- v )
1908 #if !defined(NDEBUG)
1909 builtin_verbosecall_exit((s8) v, f, f, am);
1912 TRACELRETURN ( #am l -- l )
1915 #if !defined(NDEBUG)
1916 builtin_verbosecall_exit(l, ds.d, ds.d, am);
1922 vm_uncount_block(IP); /* undo the count part of SUPER_END,
1923 because there is no fallthrough */
1926 _ALOAD_GETFIELD_CELL_ = ALOAD GETFIELD_CELL
1927 _DUP_ICONST_ = DUP ICONST
1928 _ALOAD_ALOAD_ = ALOAD ALOAD
1929 _ICONST_ICONST_ = ICONST ICONST
1930 _DUP_ICONST_ICONST_ = DUP ICONST ICONST
1931 _ICONST_CASTORE_ = ICONST CASTORE
1932 _ICONST_ICONST_CASTORE_ = ICONST ICONST CASTORE
1933 _DUP_ICONST_ICONST_CASTORE_ = DUP ICONST ICONST CASTORE
1934 _CASTORE_DUP_ = CASTORE DUP
1935 _CASTORE_DUP_ICONST_ = CASTORE DUP ICONST
1936 _DUP_ICONST_ICONST_CASTORE_DUP_ = DUP ICONST ICONST CASTORE DUP
1937 _ICONST_CASTORE_DUP_ = ICONST CASTORE DUP
1938 _ICONST_CASTORE_DUP_ICONST_ = ICONST CASTORE DUP ICONST
1939 _ICONST_ICONST_CASTORE_DUP_ = ICONST ICONST CASTORE DUP
1940 _ICONST_ICONST_CASTORE_DUP_ICONST_ = ICONST ICONST CASTORE DUP ICONST
1941 _CASTORE_DUP_ICONST_ICONST_ = CASTORE DUP ICONST ICONST
1942 _CASTORE_DUP_ICONST_ICONST_CASTORE_ = CASTORE DUP ICONST ICONST CASTORE
1943 _ICONST_CASTORE_DUP_ICONST_ICONST_ = ICONST CASTORE DUP ICONST ICONST
1944 _ASTORE_ALOAD_ = ASTORE ALOAD
1945 _ALOAD_GETFIELD_INT_ = ALOAD GETFIELD_INT
1946 _ALOAD_ILOAD_ = ALOAD ILOAD
1947 _ALOAD_ACONST_ = ALOAD ACONST
1948 _ICONST_ACONST_ = ICONST ACONST
1949 _AASTORE_DUP_ = AASTORE DUP
1950 _AASTORE_DUP_ICONST_ = AASTORE DUP ICONST
1951 _ALOAD_ICONST_ = ALOAD ICONST
1952 _ILOAD_ICONST_ = ILOAD ICONST
1953 _ILOAD_ILOAD_ = ILOAD ILOAD
1954 _DUP_ICONST_ACONST_ = DUP ICONST ACONST
1955 _GETFIELD_CELL_ALOAD_ = GETFIELD_CELL ALOAD
1956 _AASTORE_DUP_ICONST_ACONST_ = AASTORE DUP ICONST ACONST
1957 _ACONST_AASTORE_ = ACONST AASTORE
1958 _ICONST_ACONST_AASTORE_ = ICONST ACONST AASTORE
1959 _DUP_ICONST_ACONST_AASTORE_ = DUP ICONST ACONST AASTORE
1960 _ALOAD_GETFIELD_CELL_ALOAD_ = ALOAD GETFIELD_CELL ALOAD
1961 _ACONST_AASTORE_DUP_ = ACONST AASTORE DUP
1962 _ACONST_AASTORE_DUP_ICONST_ = ACONST AASTORE DUP ICONST
1963 _DUP_ICONST_ACONST_AASTORE_DUP_ = DUP ICONST ACONST AASTORE DUP
1964 _ICONST_ACONST_AASTORE_DUP_ = ICONST ACONST AASTORE DUP
1965 _ICONST_ACONST_AASTORE_DUP_ICONST_ = ICONST ACONST AASTORE DUP ICONST
1966 _AASTORE_DUP_ICONST_ACONST_AASTORE_ = AASTORE DUP ICONST ACONST AASTORE
1967 _DUP_ACONST_ = DUP ACONST
1968 _ACONST_AASTORE_DUP_ICONST_ACONST_ = ACONST AASTORE DUP ICONST ACONST
1969 _PUTFIELD_CELL_ALOAD_ = PUTFIELD_CELL ALOAD
1970 _ILOAD_ALOAD_ = ILOAD ALOAD
1971 _ICONST_ALOAD_ = ICONST ALOAD
1972 _DUP_ALOAD_ = DUP ALOAD
1973 _ICONST_ISTORE_ = ICONST ISTORE
1974 _ASTORE_ALOAD_ALOAD_ = ASTORE ALOAD ALOAD
1975 _ALOAD_PUTFIELD_CELL_ = ALOAD PUTFIELD_CELL
1976 _PUTFIELD_INT_ALOAD_ = PUTFIELD_INT ALOAD
1977 _ALOAD_ALOAD_PUTFIELD_CELL_ = ALOAD ALOAD PUTFIELD_CELL
1978 _ICONST_IADD_ = ICONST IADD
1979 _ISTORE_GOTO_ = ISTORE GOTO
1980 _ACONST_ACONST_ = ACONST ACONST
1981 _POP_ALOAD_ = POP ALOAD
1982 _ACONST_ICONST_ = ACONST ICONST
1983 _ALOAD_ALOAD_ALOAD_ = ALOAD ALOAD ALOAD
1984 _ALOAD_ALOAD_GETFIELD_CELL_ = ALOAD ALOAD GETFIELD_CELL
1985 _ISTORE_ALOAD_ = ISTORE ALOAD
1986 _GETFIELD_CELL_ILOAD_ = GETFIELD_CELL ILOAD
1987 _IINC_ILOAD_ = IINC ILOAD
1988 _ISTORE_ILOAD_ = ISTORE ILOAD
1989 _ALOAD_GETFIELD_CELL_ILOAD_ = ALOAD GETFIELD_CELL ILOAD
1990 _ILOAD_ICONST_IADD_ = ILOAD ICONST IADD
1991 _CHECKCAST_ASTORE_ = CHECKCAST ASTORE
1992 _ASTORE_ACONST_ = ASTORE ACONST
1993 _GETFIELD_INT_ALOAD_ = GETFIELD_INT ALOAD
1994 _ACONST_ALOAD_ = ACONST ALOAD
1995 _ICONST_ISTORE_GOTO_ = ICONST ISTORE GOTO
1996 _CHECKCAST_ASTORE_ALOAD_ = CHECKCAST ASTORE ALOAD
1997 _ASTORE_GOTO_ = ASTORE GOTO
1998 _ALOAD_PUTFIELD_CELL_ALOAD_ = ALOAD PUTFIELD_CELL ALOAD
1999 _ALOAD_ALOAD_PUTFIELD_CELL_ALOAD_ = ALOAD ALOAD PUTFIELD_CELL ALOAD
2000 _ICONST_PUTFIELD_INT_ = ICONST PUTFIELD_INT
2001 _ALOAD_IFNULL_ = ALOAD IFNULL
2002 _ALOAD_IFNONNULL_ = ALOAD IFNONNULL
2003 _ALOAD_ICONST_PUTFIELD_INT_ = ALOAD ICONST PUTFIELD_INT
2004 _ALOAD_GETFIELD_INT_ALOAD_ = ALOAD GETFIELD_INT ALOAD
2005 _ALOAD_ILOAD_ILOAD_ = ALOAD ILOAD ILOAD
2006 _DUP_ICONST_ALOAD_ = DUP ICONST ALOAD
2007 _IADD_ILOAD_ = IADD ILOAD
2008 _GETFIELD_CELL_ICONST_ = GETFIELD_CELL ICONST
2009 _ILOAD_PUTFIELD_INT_ = ILOAD PUTFIELD_INT
2010 _GETFIELD_INT_ALOAD_GETFIELD_INT_ = GETFIELD_INT ALOAD GETFIELD_INT
2011 _GETFIELD_CELL_GETFIELD_CELL_ = GETFIELD_CELL GETFIELD_CELL
2012 _ALOAD_ACONST_ACONST_ = ALOAD ACONST ACONST
2013 _ALOAD_ARRAYLENGTH_ = ALOAD ARRAYLENGTH
2014 _GETFIELD_CELL_IFNULL_ = GETFIELD_CELL IFNULL
2015 _ICONST_ISUB_ = ICONST ISUB
2016 _ALOAD_ILOAD_PUTFIELD_INT_ = ALOAD ILOAD PUTFIELD_INT
2017 _ALOAD_GETFIELD_CELL_GETFIELD_CELL_ = ALOAD GETFIELD_CELL GETFIELD_CELL
2018 _PUTFIELD_CELL_ALOAD_ALOAD_ = PUTFIELD_CELL ALOAD ALOAD
2019 _ILOAD_AALOAD_ = ILOAD AALOAD
2020 _ALOAD_MONITOREXIT_ = ALOAD MONITOREXIT
2021 _ALOAD_CHECKCAST_ = ALOAD CHECKCAST
2022 _ALOAD_GETFIELD_CELL_ICONST_ = ALOAD GETFIELD_CELL ICONST
2023 _ICONST_ILOAD_ = ICONST ILOAD
2024 _ACONST_ICONST_ICONST_ = ACONST ICONST ICONST
2025 _ALOAD_GETFIELD_CELL_IFNULL_ = ALOAD GETFIELD_CELL IFNULL