1 // interpret.cc - Code for the interpreter
3 /* Copyright (C) 1999, 2000, 2001 , 2002 Free Software Foundation
5 This file is part of libgcj.
7 This software is copyrighted work licensed under the terms of the
8 Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
11 /* Author: Kresten Krab Thorup <krab@gnu.org> */
15 #pragma implementation "java-interp.h"
18 #include <java-cpool.h>
19 #include <java-interp.h>
20 // #include <java/lang/fdlibm.h>
21 #include <java/lang/System.h>
22 #include <java/lang/String.h>
23 #include <java/lang/Integer.h>
24 #include <java/lang/StringBuffer.h>
25 #include <java/lang/Class.h>
26 #include <java/lang/reflect/Modifier.h>
27 #include <java/lang/ClassCastException.h>
28 #include <java/lang/VirtualMachineError.h>
29 #include <java/lang/InternalError.h>
30 #include <java/lang/NullPointerException.h>
31 #include <java/lang/ArithmeticException.h>
32 #include <java/lang/IncompatibleClassChangeError.h>
33 #include <java-insns.h>
34 #include <java-signal.h>
42 static void throw_internal_error (char *msg
)
43 __attribute__ ((__noreturn__
));
44 static void throw_incompatible_class_change_error (jstring msg
)
45 __attribute__ ((__noreturn__
));
47 static void throw_null_pointer_exception ()
48 __attribute__ ((__noreturn__
));
51 extern "C" double __ieee754_fmod (double,double);
53 static inline void dupx (_Jv_word
*sp
, int n
, int x
)
55 // first "slide" n+x elements n to the right
57 for (int i
= 0; i
< n
+x
; i
++)
59 sp
[(top
-i
)] = sp
[(top
-i
)-n
];
62 // next, copy the n top elements, n+x down
63 for (int i
= 0; i
< n
; i
++)
65 sp
[top
-(n
+x
)-i
] = sp
[top
-i
];
71 #define PUSHA(V) (sp++)->o = (V)
72 #define PUSHI(V) (sp++)->i = (V)
73 #define PUSHF(V) (sp++)->f = (V)
74 #if SIZEOF_VOID_P == 8
75 # define PUSHL(V) (sp->l = (V), sp += 2)
76 # define PUSHD(V) (sp->d = (V), sp += 2)
78 # define PUSHL(V) do { _Jv_word2 w2; w2.l=(V); \
79 (sp++)->ia[0] = w2.ia[0]; \
80 (sp++)->ia[0] = w2.ia[1]; } while (0)
81 # define PUSHD(V) do { _Jv_word2 w2; w2.d=(V); \
82 (sp++)->ia[0] = w2.ia[0]; \
83 (sp++)->ia[0] = w2.ia[1]; } while (0)
86 #define POPA() ((--sp)->o)
87 #define POPI() ((jint) (--sp)->i) // cast since it may be promoted
88 #define POPF() ((jfloat) (--sp)->f)
89 #if SIZEOF_VOID_P == 8
90 # define POPL() (sp -= 2, (jlong) sp->l)
91 # define POPD() (sp -= 2, (jdouble) sp->d)
93 # define POPL() ({ _Jv_word2 w2; \
94 w2.ia[1] = (--sp)->ia[0]; \
95 w2.ia[0] = (--sp)->ia[0]; w2.l; })
96 # define POPD() ({ _Jv_word2 w2; \
97 w2.ia[1] = (--sp)->ia[0]; \
98 w2.ia[0] = (--sp)->ia[0]; w2.d; })
101 #define LOADA(I) (sp++)->o = locals[I].o
102 #define LOADI(I) (sp++)->i = locals[I].i
103 #define LOADF(I) (sp++)->f = locals[I].f
104 #if SIZEOF_VOID_P == 8
105 # define LOADL(I) (sp->l = locals[I].l, sp += 2)
106 # define LOADD(I) (sp->d = locals[I].d, sp += 2)
108 # define LOADL(I) do { jint __idx = (I); \
109 (sp++)->ia[0] = locals[__idx].ia[0]; \
110 (sp++)->ia[0] = locals[__idx+1].ia[0]; \
112 # define LOADD(I) LOADL(I)
115 #define STOREA(I) locals[I].o = (--sp)->o
116 #define STOREI(I) locals[I].i = (--sp)->i
117 #define STOREF(I) locals[I].f = (--sp)->f
118 #if SIZEOF_VOID_P == 8
119 # define STOREL(I) (sp -= 2, locals[I].l = sp->l)
120 # define STORED(I) (sp -= 2, locals[I].d = sp->d)
122 # define STOREL(I) do { jint __idx = (I); \
123 locals[__idx+1].ia[0] = (--sp)->ia[0]; \
124 locals[__idx].ia[0] = (--sp)->ia[0]; \
126 # define STORED(I) STOREL(I)
129 #define PEEKI(I) (locals+(I))->i
130 #define PEEKA(I) (locals+(I))->o
132 #define POKEI(I,V) ((locals+(I))->i = (V))
135 #define BINOPI(OP) { \
136 jint value2 = POPI(); \
137 jint value1 = POPI(); \
138 PUSHI(value1 OP value2); \
141 #define BINOPF(OP) { \
142 jfloat value2 = POPF(); \
143 jfloat value1 = POPF(); \
144 PUSHF(value1 OP value2); \
147 #define BINOPL(OP) { \
148 jlong value2 = POPL(); \
149 jlong value1 = POPL(); \
150 PUSHL(value1 OP value2); \
153 #define BINOPD(OP) { \
154 jdouble value2 = POPD(); \
155 jdouble value1 = POPD(); \
156 PUSHD(value1 OP value2); \
159 static inline jint
get1s(unsigned char* loc
) {
160 return *(signed char*)loc
;
163 static inline jint
get1u(unsigned char* loc
) {
167 static inline jint
get2s(unsigned char* loc
) {
168 return (((jint
)*(signed char*)loc
) << 8) | ((jint
)*(loc
+1));
171 static inline jint
get2u(unsigned char* loc
) {
172 return (((jint
)(*loc
)) << 8) | ((jint
)*(loc
+1));
175 static jint
get4(unsigned char* loc
) {
176 return (((jint
)(loc
[0])) << 24)
177 | (((jint
)(loc
[1])) << 16)
178 | (((jint
)(loc
[2])) << 8)
179 | (((jint
)(loc
[3])) << 0);
185 #define NULLARRAYCHECK(X) do { SAVE_PC; } while (0)
187 #define NULLCHECK(X) \
188 do { if ((X)==NULL) throw_null_pointer_exception (); } while (0)
189 #define NULLARRAYCHECK(X) \
190 do { if ((X)==NULL) { SAVE_PC; throw_null_pointer_exception (); } } while (0)
193 #define ARRAYBOUNDSCHECK(array, index) \
196 if (((unsigned) index) >= (unsigned) (array->length)) \
197 _Jv_ThrowBadArrayIndex (index); \
201 // this method starts the actual running of the method. It is inlined
202 // in three different variants in the static methods run_normal,
203 // run_sync_object and run_sync_class (see below). Those static methods
204 // are installed directly in the stub for this method (by
205 // _Jv_InterpMethod::ncode, in resolve.cc).
208 _Jv_InterpMethod::run (ffi_cif
* cif
,
211 _Jv_InterpMethodInvocation
*inv
)
214 inv
->pc
= bytecode ();
215 inv
->sp
= inv
->stack_base ();
216 _Jv_word
*locals
= inv
->local_base ();
218 /* Go straight at it! the ffi raw format matches the internal
219 stack representation exactly. At least, that's the idea.
221 memcpy ((void*) locals
, (void*) args
, args_raw_size
);
231 catch (java::lang::Throwable
*ex2
)
236 if (ex
== 0) // no exception...
238 /* define sp locally, so the POP? macros will pick it up */
239 _Jv_word
*sp
= inv
->sp
;
240 int rtype
= cif
->rtype
->type
;
242 if (rtype
== FFI_TYPE_POINTER
)
245 *(jobject
*) retp
= r
;
248 else if (rtype
== FFI_TYPE_SINT32
)
254 else if (rtype
== FFI_TYPE_VOID
)
267 case FFI_TYPE_DOUBLE
:
275 case FFI_TYPE_UINT16
:
276 case FFI_TYPE_UINT32
:
278 case FFI_TYPE_SINT16
:
285 case FFI_TYPE_SINT64
:
293 throw_internal_error ("unknown return type");
297 /** handle an exception */
298 if ( find_exception (ex
, inv
) )
304 #define SAVE_PC inv->pc = pc
306 bool _Jv_InterpMethod::find_exception (jobject ex
,
307 _Jv_InterpMethodInvocation
*inv
)
309 // We subtract one because the PC was incremented before it was
311 int logical_pc
= inv
->pc
- 1 - bytecode ();
312 _Jv_InterpException
*exc
= exceptions ();
313 jclass exc_class
= ex
->getClass ();
315 for (int i
= 0; i
< exc_count
; i
++)
317 if (exc
[i
].start_pc
<= logical_pc
&& logical_pc
< exc
[i
].end_pc
)
321 if (exc
[i
].handler_type
!= 0)
322 handler
= (_Jv_ResolvePoolEntry (defining_class
,
323 exc
[i
].handler_type
)).clazz
;
327 if (handler
==NULL
|| handler
->isAssignableFrom (exc_class
))
329 inv
->pc
= bytecode () + exc
[i
].handler_pc
;
330 inv
->sp
= inv
->stack_base (); // reset stack
331 (inv
->sp
++)->o
= ex
; // push exception
339 void _Jv_InterpMethod::run_normal (ffi_cif
* cif
,
344 _Jv_InterpMethod
* _this
= (_Jv_InterpMethod
*)__this
;
346 // we do the alloca of the method invocation here, to allow the method
347 // "run" ro be inlined. Otherwise gcc will ignore the inline directive.
348 int storage_size
= _this
->max_stack
+_this
->max_locals
;
349 _Jv_InterpMethodInvocation
* inv
= (_Jv_InterpMethodInvocation
*)
350 __builtin_alloca (sizeof (_Jv_InterpMethodInvocation
)
351 + storage_size
* sizeof (_Jv_word
));
353 jobject ex
= _this
->run (cif
, ret
, args
, inv
);
354 if (ex
!= 0) throw static_cast<jthrowable
>(ex
);
357 void _Jv_InterpMethod::run_synch_object (ffi_cif
* cif
,
362 _Jv_InterpMethod
* _this
= (_Jv_InterpMethod
*)__this
;
363 jobject rcv
= (jobject
)args
[0].ptr
;
365 int storage_size
= _this
->max_stack
+_this
->max_locals
;
366 _Jv_InterpMethodInvocation
* inv
= (_Jv_InterpMethodInvocation
*)
367 __builtin_alloca (sizeof (_Jv_InterpMethodInvocation
)
368 + storage_size
* sizeof (_Jv_word
));
370 _Jv_MonitorEnter (rcv
);
371 jobject ex
= _this
->run (cif
, ret
, args
, inv
);
372 _Jv_MonitorExit (rcv
);
374 if (ex
!= 0) throw static_cast<jthrowable
>(ex
);
377 void _Jv_InterpMethod::run_synch_class (ffi_cif
* cif
,
382 _Jv_InterpMethod
* _this
= (_Jv_InterpMethod
*)__this
;
383 jclass sync
= _this
->defining_class
;
385 int storage_size
= _this
->max_stack
+_this
->max_locals
;
386 _Jv_InterpMethodInvocation
* inv
= (_Jv_InterpMethodInvocation
*)
387 __builtin_alloca (sizeof (_Jv_InterpMethodInvocation
)
388 + storage_size
* sizeof (_Jv_word
));
390 _Jv_MonitorEnter (sync
);
391 jobject ex
= _this
->run (cif
, ret
, args
, inv
);
392 _Jv_MonitorExit (sync
);
394 if (ex
!= 0) throw static_cast<jthrowable
>(ex
);
398 This proceeds execution, as designated in "inv". If an exception
399 happens, then it is simply thrown, and handled in Java. Thus, the pc
400 needs to be stored in the inv->pc at all times, so we can figure
401 out which handler (if any) to invoke.
403 One design issue, which I have not completely considered, is if it
404 should be possible to have interpreted classes linked in! Seldom used
405 (or non-critical) classes could reasonably be interpreted.
409 void _Jv_InterpMethod::continue1 (_Jv_InterpMethodInvocation
*inv
)
411 using namespace java::lang::reflect
;
413 _Jv_word
*sp
= inv
->sp
;
414 unsigned char *pc
= inv
->pc
;
415 _Jv_word
*locals
= inv
->local_base ();
417 _Jv_word
*pool_data
= defining_class
->constants
.data
;
419 /* these two are used in the invokeXXX instructions */
421 _Jv_ResolvedMethod
* rmeth
;
423 #define INSN_LABEL(op) &&insn_##op
424 #define GOTO_INSN(op) goto *(insn_target[op])
426 static const void *const insn_target
[] =
429 INSN_LABEL(aconst_null
),
430 INSN_LABEL(iconst_m1
),
431 INSN_LABEL(iconst_0
),
432 INSN_LABEL(iconst_1
),
433 INSN_LABEL(iconst_2
),
434 INSN_LABEL(iconst_3
),
435 INSN_LABEL(iconst_4
),
436 INSN_LABEL(iconst_5
),
437 INSN_LABEL(lconst_0
),
438 INSN_LABEL(lconst_1
),
439 INSN_LABEL(fconst_0
),
440 INSN_LABEL(fconst_1
),
441 INSN_LABEL(fconst_2
),
442 INSN_LABEL(dconst_0
),
443 INSN_LABEL(dconst_1
),
487 INSN_LABEL(istore_0
),
488 INSN_LABEL(istore_1
),
489 INSN_LABEL(istore_2
),
490 INSN_LABEL(istore_3
),
491 INSN_LABEL(lstore_0
),
492 INSN_LABEL(lstore_1
),
493 INSN_LABEL(lstore_2
),
494 INSN_LABEL(lstore_3
),
495 INSN_LABEL(fstore_0
),
496 INSN_LABEL(fstore_1
),
497 INSN_LABEL(fstore_2
),
498 INSN_LABEL(fstore_3
),
499 INSN_LABEL(dstore_0
),
500 INSN_LABEL(dstore_1
),
501 INSN_LABEL(dstore_2
),
502 INSN_LABEL(dstore_3
),
503 INSN_LABEL(astore_0
),
504 INSN_LABEL(astore_1
),
505 INSN_LABEL(astore_2
),
506 INSN_LABEL(astore_3
),
587 INSN_LABEL(if_icmpeq
),
588 INSN_LABEL(if_icmpne
),
589 INSN_LABEL(if_icmplt
),
590 INSN_LABEL(if_icmpge
),
591 INSN_LABEL(if_icmpgt
),
592 INSN_LABEL(if_icmple
),
593 INSN_LABEL(if_acmpeq
),
594 INSN_LABEL(if_acmpne
),
598 INSN_LABEL(tableswitch
),
599 INSN_LABEL(lookupswitch
),
606 INSN_LABEL(getstatic
),
607 INSN_LABEL(putstatic
),
608 INSN_LABEL(getfield
),
609 INSN_LABEL(putfield
),
610 INSN_LABEL(invokevirtual
),
611 INSN_LABEL(invokespecial
),
612 INSN_LABEL(invokestatic
),
613 INSN_LABEL(invokeinterface
),
614 0, /* op_xxxunusedxxx1, */
616 INSN_LABEL(newarray
),
617 INSN_LABEL(anewarray
),
618 INSN_LABEL(arraylength
),
620 INSN_LABEL(checkcast
),
621 INSN_LABEL(instanceof
),
622 INSN_LABEL(monitorenter
),
623 INSN_LABEL(monitorexit
),
625 INSN_LABEL(multianewarray
),
627 INSN_LABEL(ifnonnull
),
632 /* If the macro INLINE_SWITCH is not defined, then the main loop
633 operates as one big (normal) switch statement. If it is defined,
634 then the case selection is performed `inline' in the end of the
635 code for each case. The latter saves a native branch instruction
636 for each java-instruction, but expands the code size somewhat.
638 NOTE: On i386 defining INLINE_SWITCH improves over all
639 performance approximately seven percent, but it may be different
640 for other machines. At some point, this may be made into a proper
641 configuration parameter. */
643 #define INLINE_SWITCH
647 #define NEXT_INSN do { GOTO_INSN(*pc++); } while (0)
653 #define NEXT_INSN goto next_insn
660 /* The first few instructions here are ordered according to their
661 frequency, in the hope that this will improve code locality a
664 insn_aload_0
: // 0x2a
669 LOADI (get1u (pc
++));
672 insn_iload_1
: // 0x1b
676 insn_invokevirtual
: // 0xb6
679 int index
= get2u (pc
); pc
+= 2;
681 /* _Jv_ResolvePoolEntry returns immediately if the value already
682 * is resolved. If we want to clutter up the code here to gain
683 * a little performance, then we can check the corresponding bit
684 * JV_CONSTANT_ResolvedFlag in the tag directly. For now, I
685 * don't think it is worth it. */
687 rmeth
= (_Jv_ResolvePoolEntry (defining_class
, index
)).rmethod
;
689 sp
-= rmeth
->stack_item_count
;
690 // We don't use NULLCHECK here because we can't rely on that
691 // working if the method is final. So instead we do an
694 throw new java::lang::NullPointerException
;
696 if (rmeth
->vtable_index
== -1)
698 // final methods do not appear in the vtable,
699 // if it does not appear in the superclass.
700 fun
= (void (*)()) rmeth
->method
->ncode
;
704 jobject rcv
= sp
[0].o
;
705 _Jv_VTable
*table
= *(_Jv_VTable
**)rcv
;
706 fun
= (void (*)()) table
->get_method(rmeth
->vtable_index
);
713 /* here goes the magic again... */
714 ffi_cif
*cif
= &rmeth
->cif
;
715 ffi_raw
*raw
= (ffi_raw
*) sp
;
719 #if FFI_NATIVE_RAW_API
720 /* We assume that this is only implemented if it's correct */
721 /* to use it here. On a 64 bit machine, it never is. */
722 ffi_raw_call (cif
, fun
, (void*)&rvalue
, raw
);
724 ffi_java_raw_call (cif
, fun
, (void*)&rvalue
, raw
);
727 int rtype
= cif
->rtype
->type
;
729 /* the likelyhood of object, int, or void return is very high,
730 * so those are checked before the switch */
731 if (rtype
== FFI_TYPE_POINTER
)
733 PUSHA (*(jobject
*)&rvalue
);
735 else if (rtype
== FFI_TYPE_SINT32
)
737 PUSHI (*(jint
*)&rvalue
);
739 else if (rtype
== FFI_TYPE_VOID
)
747 jbyte value
= (*(jint
*)&rvalue
) & 0xff;
752 case FFI_TYPE_SINT16
:
754 jshort value
= (*(jint
*)&rvalue
) & 0xffff;
759 case FFI_TYPE_UINT16
:
761 jint value
= (*(jint
*)&rvalue
) & 0xffff;
767 PUSHF (*(jfloat
*)&rvalue
);
770 case FFI_TYPE_DOUBLE
:
774 case FFI_TYPE_SINT64
:
775 PUSHL (*(jlong
*)&rvalue
);
779 throw_internal_error ("unknown return type in invokeXXX");
854 PUSHI (get2s(pc
)); pc
+= 2;
859 int index
= get1u (pc
++);
860 PUSHA(pool_data
[index
].o
);
866 int index
= get2u (pc
); pc
+= 2;
867 PUSHA(pool_data
[index
].o
);
873 int index
= get2u (pc
); pc
+= 2;
874 memcpy (sp
, &pool_data
[index
], 2*sizeof (_Jv_word
));
880 LOADL (get1u (pc
++));
884 LOADF (get1u (pc
++));
888 LOADD (get1u (pc
++));
892 LOADA (get1u (pc
++));
970 jintArray arr
= (jintArray
) POPA();
971 NULLARRAYCHECK (arr
);
972 ARRAYBOUNDSCHECK (arr
, index
);
973 PUSHI( elements(arr
)[index
] );
980 jlongArray arr
= (jlongArray
) POPA();
981 NULLARRAYCHECK (arr
);
982 ARRAYBOUNDSCHECK (arr
, index
);
983 PUSHL( elements(arr
)[index
] );
990 jfloatArray arr
= (jfloatArray
) POPA();
991 NULLARRAYCHECK (arr
);
992 ARRAYBOUNDSCHECK (arr
, index
);
993 PUSHF( elements(arr
)[index
] );
1000 jdoubleArray arr
= (jdoubleArray
) POPA();
1001 NULLARRAYCHECK (arr
);
1002 ARRAYBOUNDSCHECK (arr
, index
);
1003 PUSHD( elements(arr
)[index
] );
1009 jint index
= POPI();
1010 jobjectArray arr
= (jobjectArray
) POPA();
1011 NULLARRAYCHECK (arr
);
1012 ARRAYBOUNDSCHECK (arr
, index
);
1013 PUSHA( elements(arr
)[index
] );
1019 jint index
= POPI();
1020 jbyteArray arr
= (jbyteArray
) POPA();
1021 NULLARRAYCHECK (arr
);
1022 ARRAYBOUNDSCHECK (arr
, index
);
1023 PUSHI( elements(arr
)[index
] );
1029 jint index
= POPI();
1030 jcharArray arr
= (jcharArray
) POPA();
1031 NULLARRAYCHECK (arr
);
1032 ARRAYBOUNDSCHECK (arr
, index
);
1033 PUSHI( elements(arr
)[index
] );
1039 jint index
= POPI();
1040 jshortArray arr
= (jshortArray
) POPA();
1041 NULLARRAYCHECK (arr
);
1042 ARRAYBOUNDSCHECK (arr
, index
);
1043 PUSHI( elements(arr
)[index
] );
1048 STOREI (get1u (pc
++));
1052 STOREL (get1u (pc
++));
1056 STOREF (get1u (pc
++));
1060 STORED (get1u (pc
++));
1064 STOREA (get1u (pc
++));
1149 jint value
= POPI();
1150 jint index
= POPI();
1151 jintArray arr
= (jintArray
) POPA();
1152 NULLARRAYCHECK (arr
);
1153 ARRAYBOUNDSCHECK (arr
, index
);
1154 elements(arr
)[index
] = value
;
1160 jlong value
= POPL();
1161 jint index
= POPI();
1162 jlongArray arr
= (jlongArray
) POPA();
1163 NULLARRAYCHECK (arr
);
1164 ARRAYBOUNDSCHECK (arr
, index
);
1165 elements(arr
)[index
] = value
;
1171 jfloat value
= POPF();
1172 jint index
= POPI();
1173 jfloatArray arr
= (jfloatArray
) POPA();
1174 NULLARRAYCHECK (arr
);
1175 ARRAYBOUNDSCHECK (arr
, index
);
1176 elements(arr
)[index
] = value
;
1182 jdouble value
= POPD();
1183 jint index
= POPI();
1184 jdoubleArray arr
= (jdoubleArray
) POPA();
1185 NULLARRAYCHECK (arr
);
1186 ARRAYBOUNDSCHECK (arr
, index
);
1187 elements(arr
)[index
] = value
;
1193 jobject value
= POPA();
1194 jint index
= POPI();
1195 jobjectArray arr
= (jobjectArray
) POPA();
1196 NULLARRAYCHECK (arr
);
1197 ARRAYBOUNDSCHECK (arr
, index
);
1198 _Jv_CheckArrayStore (arr
, value
);
1199 elements(arr
)[index
] = value
;
1205 jbyte value
= (jbyte
) POPI();
1206 jint index
= POPI();
1207 jbyteArray arr
= (jbyteArray
) POPA();
1208 NULLARRAYCHECK (arr
);
1209 ARRAYBOUNDSCHECK (arr
, index
);
1210 elements(arr
)[index
] = value
;
1216 jchar value
= (jchar
) POPI();
1217 jint index
= POPI();
1218 jcharArray arr
= (jcharArray
) POPA();
1219 NULLARRAYCHECK (arr
);
1220 ARRAYBOUNDSCHECK (arr
, index
);
1221 elements(arr
)[index
] = value
;
1227 jshort value
= (jshort
) POPI();
1228 jint index
= POPI();
1229 jshortArray arr
= (jshortArray
) POPA();
1230 NULLARRAYCHECK (arr
);
1231 ARRAYBOUNDSCHECK (arr
, index
);
1232 elements(arr
)[index
] = value
;
1250 dupx (sp
, 1, 1); sp
+=1;
1254 dupx (sp
, 1, 2); sp
+=1;
1264 dupx (sp
, 2, 1); sp
+=2;
1268 dupx (sp
, 2, 2); sp
+=2;
1273 jobject tmp1
= POPA();
1274 jobject tmp2
= POPA();
1331 jint value2
= POPI();
1332 jint value1
= POPI();
1333 jint res
= _Jv_divI (value1
, value2
);
1341 jlong value2
= POPL();
1342 jlong value1
= POPL();
1343 jlong res
= _Jv_divJ (value1
, value2
);
1350 jfloat value2
= POPF();
1351 jfloat value1
= POPF();
1352 jfloat res
= value1
/ value2
;
1359 jdouble value2
= POPD();
1360 jdouble value1
= POPD();
1361 jdouble res
= value1
/ value2
;
1369 jint value2
= POPI();
1370 jint value1
= POPI();
1371 jint res
= _Jv_remI (value1
, value2
);
1379 jlong value2
= POPL();
1380 jlong value1
= POPL();
1381 jlong res
= _Jv_remJ (value1
, value2
);
1388 jfloat value2
= POPF();
1389 jfloat value1
= POPF();
1390 jfloat res
= __ieee754_fmod (value1
, value2
);
1397 jdouble value2
= POPD();
1398 jdouble value1
= POPD();
1399 jdouble res
= __ieee754_fmod (value1
, value2
);
1406 jint value
= POPI();
1413 jlong value
= POPL();
1420 jfloat value
= POPF();
1427 jdouble value
= POPD();
1434 jint shift
= (POPI() & 0x1f);
1435 jint value
= POPI();
1436 PUSHI (value
<< shift
);
1442 jint shift
= (POPI() & 0x3f);
1443 jlong value
= POPL();
1444 PUSHL (value
<< shift
);
1450 jint shift
= (POPI() & 0x1f);
1451 jint value
= POPI();
1452 PUSHI (value
>> shift
);
1458 jint shift
= (POPI() & 0x3f);
1459 jlong value
= POPL();
1460 PUSHL (value
>> shift
);
1466 jint shift
= (POPI() & 0x1f);
1467 unsigned long value
= POPI();
1468 PUSHI ((jint
) (value
>> shift
));
1474 jint shift
= (POPI() & 0x3f);
1475 UINT64 value
= (UINT64
) POPL();
1476 PUSHL ((value
>> shift
));
1506 jint index
= get1u (pc
++);
1507 jint amount
= get1s (pc
++);
1508 locals
[index
].i
+= amount
;
1513 {jlong value
= POPI(); PUSHL (value
);}
1517 {jfloat value
= POPI(); PUSHF (value
);}
1521 {jdouble value
= POPI(); PUSHD (value
);}
1525 {jint value
= POPL(); PUSHI (value
);}
1529 {jfloat value
= POPL(); PUSHF (value
);}
1533 {jdouble value
= POPL(); PUSHD (value
);}
1537 { jint value
= (jint
)POPF (); PUSHI(value
); }
1541 { jlong value
= (jlong
)POPF (); PUSHL(value
); }
1545 { jdouble value
= POPF (); PUSHD(value
); }
1549 { jint value
= (jint
)POPD (); PUSHI(value
); }
1553 { jlong value
= (jlong
)POPD (); PUSHL(value
); }
1557 { jfloat value
= POPD (); PUSHF(value
); }
1561 { jbyte value
= POPI (); PUSHI(value
); }
1565 { jchar value
= POPI (); PUSHI(value
); }
1569 { jshort value
= POPI (); PUSHI(value
); }
1574 jlong value2
= POPL ();
1575 jlong value1
= POPL ();
1576 if (value1
> value2
)
1578 else if (value1
== value2
)
1588 jfloat value2
= POPF ();
1589 jfloat value1
= POPF ();
1590 if (value1
> value2
)
1592 else if (value1
== value2
)
1594 else if (value1
< value2
)
1596 else if ((*(pc
-1)) == op_fcmpg
)
1606 jdouble value2
= POPD ();
1607 jdouble value1
= POPD ();
1608 if (value1
> value2
)
1610 else if (value1
== value2
)
1612 else if (value1
< value2
)
1614 else if ((*(pc
-1)) == op_dcmpg
)
1623 jint offset
= get2s (pc
);
1633 jint offset
= get2s (pc
);
1643 jint offset
= get2s (pc
);
1653 jint offset
= get2s (pc
);
1663 jint offset
= get2s (pc
);
1673 jint offset
= get2s (pc
);
1683 jint offset
= get2s (pc
);
1684 jint value2
= POPI();
1685 jint value1
= POPI();
1686 if (value1
== value2
)
1695 jint offset
= get2s (pc
);
1696 jint value2
= POPI();
1697 jint value1
= POPI();
1698 if (value1
!= value2
)
1707 jint offset
= get2s (pc
);
1708 jint value2
= POPI();
1709 jint value1
= POPI();
1710 if (value1
< value2
)
1719 jint offset
= get2s (pc
);
1720 jint value2
= POPI();
1721 jint value1
= POPI();
1722 if (value1
>= value2
)
1731 jint offset
= get2s (pc
);
1732 jint value2
= POPI();
1733 jint value1
= POPI();
1734 if (value1
> value2
)
1743 jint offset
= get2s (pc
);
1744 jint value2
= POPI();
1745 jint value1
= POPI();
1746 if (value1
<= value2
)
1755 jint offset
= get2s (pc
);
1756 jobject value2
= POPA();
1757 jobject value1
= POPA();
1758 if (value1
== value2
)
1767 jint offset
= get2s (pc
);
1768 jobject value2
= POPA();
1769 jobject value1
= POPA();
1770 if (value1
!= value2
)
1779 jint offset
= get2s (pc
);
1786 unsigned char *base_pc
= pc
-1;
1787 jint offset
= get2s (pc
); pc
+= 2;
1788 PUSHA ((jobject
)pc
);
1789 pc
= base_pc
+offset
;
1795 jint index
= get1u (pc
);
1796 pc
= (unsigned char*) PEEKA (index
);
1802 unsigned char *base_pc
= pc
-1;
1805 unsigned char* base
= bytecode ();
1806 while ((pc
-base
) % 4 != 0)
1809 jint def
= get4 (pc
);
1810 jint low
= get4 (pc
+4);
1811 jint high
= get4 (pc
+8);
1813 if (index
< low
|| index
> high
)
1816 pc
= base_pc
+ get4 (pc
+4*(index
-low
+3));
1822 unsigned char *base_pc
= pc
-1;
1825 unsigned char* base
= bytecode ();
1826 while ((pc
-base
) % 4 != 0)
1829 jint def
= get4 (pc
);
1830 jint npairs
= get4 (pc
+4);
1835 // simple binary search...
1838 int half
= (min
+max
)/2;
1839 int match
= get4 (pc
+ 4*(2 + 2*half
));
1844 else if (index
< match
)
1851 if (index
== get4 (pc
+ 4*(2 + 2*min
)))
1852 pc
= base_pc
+ get4 (pc
+ 4*(2 + 2*min
+ 1));
1858 /* on return, just save the sp and return to caller */
1871 jint fieldref_index
= get2u (pc
); pc
+= 2;
1872 _Jv_ResolvePoolEntry (defining_class
, fieldref_index
);
1873 _Jv_Field
*field
= pool_data
[fieldref_index
].field
;
1875 if ((field
->flags
& Modifier::STATIC
) == 0)
1876 throw_incompatible_class_change_error
1877 (JvNewStringLatin1 ("field no longer static"));
1879 jclass type
= field
->type
;
1881 if (type
->isPrimitive ())
1883 switch (type
->size_in_bytes
)
1886 PUSHI (*(jbyte
*) (field
->u
.addr
));
1890 if (type
== JvPrimClass (char))
1891 PUSHI(*(jchar
*) (field
->u
.addr
));
1893 PUSHI(*(jshort
*) (field
->u
.addr
));
1897 PUSHI(*(jint
*) (field
->u
.addr
));
1901 PUSHL(*(jlong
*) (field
->u
.addr
));
1907 PUSHA(*(jobject
*) (field
->u
.addr
));
1915 jint fieldref_index
= get2u (pc
); pc
+= 2;
1916 _Jv_ResolvePoolEntry (defining_class
, fieldref_index
);
1917 _Jv_Field
*field
= pool_data
[fieldref_index
].field
;
1919 if ((field
->flags
& Modifier::STATIC
) != 0)
1920 throw_incompatible_class_change_error
1921 (JvNewStringLatin1 ("field is static"));
1923 jclass type
= field
->type
;
1924 jint field_offset
= field
->u
.boffset
;
1925 if (field_offset
> 0xffff)
1926 throw new java::lang::VirtualMachineError
;
1928 jobject obj
= POPA();
1931 if (type
->isPrimitive ())
1933 switch (type
->size_in_bytes
)
1936 PUSHI (*(jbyte
*) ((char*)obj
+ field_offset
));
1940 if (type
== JvPrimClass (char))
1941 PUSHI (*(jchar
*) ((char*)obj
+ field_offset
));
1943 PUSHI (*(jshort
*) ((char*)obj
+ field_offset
));
1947 PUSHI (*(jint
*) ((char*)obj
+ field_offset
));
1951 PUSHL(*(jlong
*) ((char*)obj
+ field_offset
));
1957 PUSHA(*(jobject
*) ((char*)obj
+ field_offset
));
1965 jint fieldref_index
= get2u (pc
); pc
+= 2;
1966 _Jv_ResolvePoolEntry (defining_class
, fieldref_index
);
1967 _Jv_Field
*field
= pool_data
[fieldref_index
].field
;
1969 jclass type
= field
->type
;
1971 // ResolvePoolEntry cannot check this
1972 if ((field
->flags
& Modifier::STATIC
) == 0)
1973 throw_incompatible_class_change_error
1974 (JvNewStringLatin1 ("field no longer static"));
1976 if (type
->isPrimitive ())
1978 switch (type
->size_in_bytes
)
1982 jint value
= POPI();
1983 *(jbyte
*) (field
->u
.addr
) = value
;
1989 jint value
= POPI();
1990 *(jchar
*) (field
->u
.addr
) = value
;
1996 jint value
= POPI();
1997 *(jint
*) (field
->u
.addr
) = value
;
2003 jlong value
= POPL();
2004 *(jlong
*) (field
->u
.addr
) = value
;
2011 jobject value
= POPA();
2012 *(jobject
*) (field
->u
.addr
) = value
;
2021 jint fieldref_index
= get2u (pc
); pc
+= 2;
2022 _Jv_ResolvePoolEntry (defining_class
, fieldref_index
);
2023 _Jv_Field
*field
= pool_data
[fieldref_index
].field
;
2025 jclass type
= field
->type
;
2027 if ((field
->flags
& Modifier::STATIC
) != 0)
2028 throw_incompatible_class_change_error
2029 (JvNewStringLatin1 ("field is static"));
2031 jint field_offset
= field
->u
.boffset
;
2032 if (field_offset
> 0xffff)
2033 throw new java::lang::VirtualMachineError
;
2035 if (type
->isPrimitive ())
2037 switch (type
->size_in_bytes
)
2041 jint value
= POPI();
2042 jobject obj
= POPA();
2044 *(jbyte
*) ((char*)obj
+ field_offset
) = value
;
2050 jint value
= POPI();
2051 jobject obj
= POPA();
2053 *(jchar
*) ((char*)obj
+ field_offset
) = value
;
2059 jint value
= POPI();
2060 jobject obj
= POPA();
2062 *(jint
*) ((char*)obj
+ field_offset
) = value
;
2068 jlong value
= POPL();
2069 jobject obj
= POPA();
2071 *(jlong
*) ((char*)obj
+ field_offset
) = value
;
2078 jobject value
= POPA();
2079 jobject obj
= POPA();
2081 *(jobject
*) ((char*)obj
+ field_offset
) = value
;
2089 int index
= get2u (pc
); pc
+= 2;
2091 rmeth
= (_Jv_ResolvePoolEntry (defining_class
, index
)).rmethod
;
2093 sp
-= rmeth
->stack_item_count
;
2095 NULLCHECK (sp
[0].o
);
2097 fun
= (void (*)()) rmeth
->method
->ncode
;
2099 goto perform_invoke
;
2104 int index
= get2u (pc
); pc
+= 2;
2106 rmeth
= (_Jv_ResolvePoolEntry (defining_class
, index
)).rmethod
;
2108 sp
-= rmeth
->stack_item_count
;
2110 _Jv_InitClass (rmeth
->klass
);
2111 fun
= (void (*)()) rmeth
->method
->ncode
;
2113 goto perform_invoke
;
2115 insn_invokeinterface
:
2118 int index
= get2u (pc
); pc
+= 2;
2120 // invokeinterface has two unused bytes...
2123 rmeth
= (_Jv_ResolvePoolEntry (defining_class
, index
)).rmethod
;
2125 sp
-= rmeth
->stack_item_count
;
2127 jobject rcv
= sp
[0].o
;
2132 _Jv_LookupInterfaceMethod (rcv
->getClass (),
2133 rmeth
->method
->name
,
2134 rmeth
->method
->signature
);
2136 goto perform_invoke
;
2142 int index
= get2u (pc
); pc
+= 2;
2143 jclass klass
= (_Jv_ResolvePoolEntry (defining_class
, index
)).clazz
;
2144 _Jv_InitClass (klass
);
2145 jobject res
= _Jv_AllocObject (klass
, klass
->size_in_bytes
);
2153 int atype
= get1u (pc
++);
2155 jobject result
= _Jv_NewArray (atype
, size
);
2163 int index
= get2u (pc
); pc
+= 2;
2164 jclass klass
= (_Jv_ResolvePoolEntry (defining_class
, index
)).clazz
;
2166 _Jv_InitClass (klass
);
2167 jobject result
= _Jv_NewObjectArray (size
, klass
, 0);
2174 __JArray
*arr
= (__JArray
*)POPA();
2175 NULLARRAYCHECK (arr
);
2176 PUSHI (arr
->length
);
2183 jobject value
= POPA();
2184 throw static_cast<jthrowable
>(value
);
2191 jobject value
= POPA();
2192 jint index
= get2u (pc
); pc
+= 2;
2193 jclass to
= (_Jv_ResolvePoolEntry (defining_class
, index
)).clazz
;
2195 if (value
!= NULL
&& ! to
->isInstance (value
))
2197 throw new java::lang::ClassCastException (to
->getName());
2207 jobject value
= POPA();
2208 jint index
= get2u (pc
); pc
+= 2;
2209 jclass to
= (_Jv_ResolvePoolEntry (defining_class
, index
)).clazz
;
2210 PUSHI (to
->isInstance (value
));
2217 jobject value
= POPA();
2219 _Jv_MonitorEnter (value
);
2226 jobject value
= POPA();
2228 _Jv_MonitorExit (value
);
2234 unsigned char* base_pc
= pc
-1;
2235 jint offset
= get2s (pc
); pc
+= 2;
2236 jobject val
= POPA();
2238 pc
= base_pc
+offset
;
2244 unsigned char* base_pc
= pc
-1;
2245 jint offset
= get2s (pc
); pc
+= 2;
2246 jobject val
= POPA();
2248 pc
= base_pc
+offset
;
2255 jint the_mod_op
= get1u (pc
++);
2256 jint wide
= get2u (pc
); pc
+= 2;
2297 pc
= (unsigned char*) PEEKA (wide
);
2302 jint amount
= get2s (pc
); pc
+= 2;
2303 jint value
= PEEKI (wide
);
2304 POKEI (wide
, value
+amount
);
2309 throw_internal_error ("illegal bytecode modified by wide");
2314 insn_multianewarray
:
2317 int kind_index
= get2u (pc
); pc
+= 2;
2318 int dim
= get1u (pc
); pc
+= 1;
2321 = (_Jv_ResolvePoolEntry (defining_class
, kind_index
)).clazz
;
2322 _Jv_InitClass (type
);
2323 jint
*sizes
= (jint
*) __builtin_alloca (sizeof (jint
)*dim
);
2325 for (int i
= dim
- 1; i
>= 0; i
--)
2330 jobject res
= _Jv_NewMultiArray (type
,dim
, sizes
);
2338 unsigned char* base_pc
= pc
-1;
2339 int offset
= get4 (pc
); pc
+= 4;
2340 pc
= base_pc
+offset
;
2346 unsigned char* base_pc
= pc
-1;
2347 int offset
= get4 (pc
); pc
+= 4;
2349 pc
= base_pc
+offset
;
2356 throw_internal_error (char *msg
)
2358 throw new java::lang::InternalError (JvNewStringLatin1 (msg
));
2362 throw_incompatible_class_change_error (jstring msg
)
2364 throw new java::lang::IncompatibleClassChangeError (msg
);
2368 static java::lang::NullPointerException
*null_pointer_exc
;
2370 throw_null_pointer_exception ()
2372 if (null_pointer_exc
== NULL
)
2373 null_pointer_exc
= new java::lang::NullPointerException
;
2375 throw null_pointer_exc
;
2379 #endif // INTERPRETER