1 // interpret-run.cc - Code to interpret bytecode
3 /* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 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 /* This file is meant only to be included in interpret.cc, it should not be
12 * compiled directly. */
14 using namespace java::lang::reflect
;
16 // FRAME_DESC registers this particular invocation as the top-most
17 // interpreter frame. This lets the stack tracing code (for
18 // Throwable) print information about the method being interpreted
19 // rather than about the interpreter itself. FRAME_DESC has a
20 // destructor so it cleans up automatically when the interpreter
22 java::lang::Thread
*thread
= java::lang::Thread::currentThread();
23 _Jv_InterpFrame
frame_desc (meth
, thread
);
25 _Jv_word stack
[meth
->max_stack
];
28 _Jv_word locals
[meth
->max_locals
];
31 frame_desc
.locals
= locals
;
32 char locals_type
[meth
->max_locals
];
33 memset (locals_type
, 'x', meth
->max_locals
);
34 frame_desc
.locals_type
= locals_type
;
37 #define INSN_LABEL(op) &&insn_##op
39 static const void *const insn_target
[] =
42 INSN_LABEL(aconst_null
),
43 INSN_LABEL(iconst_m1
),
100 INSN_LABEL(istore_0
),
101 INSN_LABEL(istore_1
),
102 INSN_LABEL(istore_2
),
103 INSN_LABEL(istore_3
),
104 INSN_LABEL(lstore_0
),
105 INSN_LABEL(lstore_1
),
106 INSN_LABEL(lstore_2
),
107 INSN_LABEL(lstore_3
),
108 INSN_LABEL(fstore_0
),
109 INSN_LABEL(fstore_1
),
110 INSN_LABEL(fstore_2
),
111 INSN_LABEL(fstore_3
),
112 INSN_LABEL(dstore_0
),
113 INSN_LABEL(dstore_1
),
114 INSN_LABEL(dstore_2
),
115 INSN_LABEL(dstore_3
),
116 INSN_LABEL(astore_0
),
117 INSN_LABEL(astore_1
),
118 INSN_LABEL(astore_2
),
119 INSN_LABEL(astore_3
),
200 INSN_LABEL(if_icmpeq
),
201 INSN_LABEL(if_icmpne
),
202 INSN_LABEL(if_icmplt
),
203 INSN_LABEL(if_icmpge
),
204 INSN_LABEL(if_icmpgt
),
205 INSN_LABEL(if_icmple
),
206 INSN_LABEL(if_acmpeq
),
207 INSN_LABEL(if_acmpne
),
211 INSN_LABEL(tableswitch
),
212 INSN_LABEL(lookupswitch
),
219 INSN_LABEL(getstatic
),
220 INSN_LABEL(putstatic
),
221 INSN_LABEL(getfield
),
222 INSN_LABEL(putfield
),
223 INSN_LABEL(invokevirtual
),
224 INSN_LABEL(invokespecial
),
225 INSN_LABEL(invokestatic
),
226 INSN_LABEL(invokeinterface
),
227 INSN_LABEL(breakpoint
),
229 INSN_LABEL(newarray
),
230 INSN_LABEL(anewarray
),
231 INSN_LABEL(arraylength
),
233 INSN_LABEL(checkcast
),
234 INSN_LABEL(instanceof
),
235 INSN_LABEL(monitorenter
),
236 INSN_LABEL(monitorexit
),
237 #ifdef DIRECT_THREADED
242 INSN_LABEL(multianewarray
),
244 INSN_LABEL(ifnonnull
),
247 #ifdef DIRECT_THREADED
248 INSN_LABEL (ldc_class
)
256 #ifdef DIRECT_THREADED
263 if (JVMTI_REQUESTED_EVENT (SingleStep)) \
265 JNIEnv *env = _Jv_GetCurrentJNIEnv (); \
266 jmethodID method = meth->self; \
267 jlocation loc = meth->insn_index (pc); \
268 _Jv_JVMTI_PostEvent (JVMTI_EVENT_SINGLE_STEP, thread, \
271 goto *((pc++)->insn); \
276 #define NEXT_INSN goto *((pc++)->insn)
279 #define INTVAL() ((pc++)->int_val)
280 #define AVAL() ((pc++)->datum)
282 #define GET1S() INTVAL ()
283 #define GET2S() INTVAL ()
284 #define GET1U() INTVAL ()
285 #define GET2U() INTVAL ()
286 #define AVAL1U() AVAL ()
287 #define AVAL2U() AVAL ()
288 #define AVAL2UP() AVAL ()
289 #define SKIP_GOTO ++pc
290 #define GOTO_VAL() (insn_slot *) pc->datum
291 #define PCVAL(unionval) unionval.p
292 #define AMPAMP(label) &&label
294 // Compile if we must. NOTE: Double-check locking.
295 if (meth
->prepared
== NULL
)
297 _Jv_MutexLock (&compile_mutex
);
298 if (meth
->prepared
== NULL
)
299 meth
->compile (insn_target
);
300 _Jv_MutexUnlock (&compile_mutex
);
303 // If we're only compiling, stop here
307 pc
= (insn_slot
*) meth
->prepared
;
315 if (JVMTI_REQUESTED_EVENT (SingleStep)) \
317 JNIEnv *env = _Jv_GetCurrentJNIEnv (); \
318 jmethodID method = meth->self; \
319 jlocation loc = meth->insn_index (pc); \
320 _Jv_JVMTI_PostEvent (JVMTI_EVENT_SINGLE_STEP, thread, \
323 goto *(insn_target[*pc++])
325 #define NEXT_INSN goto *(insn_target[*pc++])
328 #define GET1S() get1s (pc++)
329 #define GET2S() (pc += 2, get2s (pc- 2))
330 #define GET1U() get1u (pc++)
331 #define GET2U() (pc += 2, get2u (pc - 2))
332 // Note that these could be more efficient when not handling 'ldc
335 ({ int index = get1u (pc++); \
336 _Jv_Linker::resolve_pool_entry (meth->defining_class, index).o; })
338 ({ int index = get2u (pc); pc += 2; \
339 _Jv_Linker::resolve_pool_entry (meth->defining_class, index).o; })
340 // Note that we don't need to resolve the pool entry here as class
341 // constants are never wide.
342 #define AVAL2UP() ({ int index = get2u (pc); pc += 2; &pool_data[index]; })
343 #define SKIP_GOTO pc += 2
344 #define GOTO_VAL() pc - 1 + get2s (pc)
345 #define PCVAL(unionval) unionval.i
346 #define AMPAMP(label) NULL
348 pc
= meth
->bytecode ();
350 #endif /* DIRECT_THREADED */
352 #define TAKE_GOTO pc = GOTO_VAL ()
354 /* Go straight at it! the ffi raw format matches the internal
355 stack representation exactly. At least, that's the idea.
357 memcpy ((void*) locals
, (void*) args
, meth
->args_raw_size
);
360 // Get the object pointer for this method, after checking that it is
362 _Jv_Method
*method
= meth
->get_method ();
364 if ((method
->accflags
& java::lang::reflect::Modifier::STATIC
) == 0)
365 frame_desc
.obj_ptr
= locals
[0].o
;
368 _Jv_word
*pool_data
= meth
->defining_class
->constants
.data
;
370 /* These three are temporaries for common code used by several
373 _Jv_ResolvedMethod
* rmeth
;
378 // We keep nop around. It is used if we're interpreting the
379 // bytecodes and not doing direct threading.
383 /* The first few instructions here are ordered according to their
384 frequency, in the hope that this will improve code locality a
387 insn_aload_0
: // 0x2a
395 insn_iload_1
: // 0x1b
399 insn_invokevirtual
: // 0xb6
402 int index
= GET2U ();
404 /* _Jv_Linker::resolve_pool_entry returns immediately if the
405 * value already is resolved. If we want to clutter up the
406 * code here to gain a little performance, then we can check
407 * the corresponding bit JV_CONSTANT_ResolvedFlag in the tag
408 * directly. For now, I don't think it is worth it. */
410 rmeth
= (_Jv_Linker::resolve_pool_entry (meth
->defining_class
,
413 sp
-= rmeth
->stack_item_count
;
415 if (rmeth
->method
->accflags
& Modifier::FINAL
)
417 // We can't rely on NULLCHECK working if the method is final.
419 throw_null_pointer_exception ();
421 // Final methods might not appear in the vtable.
422 fun
= (void (*)()) rmeth
->method
->ncode
;
427 jobject rcv
= sp
[0].o
;
428 _Jv_VTable
*table
= *(_Jv_VTable
**) rcv
;
429 fun
= (void (*)()) table
->get_method (rmeth
->method
->index
);
432 #ifdef DIRECT_THREADED
433 // Rewrite instruction so that we use a faster pre-resolved
435 pc
[-2].insn
= &&invokevirtual_resolved
;
436 pc
[-1].datum
= rmeth
;
437 #endif /* DIRECT_THREADED */
441 #ifdef DIRECT_THREADED
442 invokevirtual_resolved
:
445 rmeth
= (_Jv_ResolvedMethod
*) AVAL ();
446 sp
-= rmeth
->stack_item_count
;
448 if (rmeth
->method
->accflags
& Modifier::FINAL
)
450 // We can't rely on NULLCHECK working if the method is final.
452 throw_null_pointer_exception ();
454 // Final methods might not appear in the vtable.
455 fun
= (void (*)()) rmeth
->method
->ncode
;
459 jobject rcv
= sp
[0].o
;
460 _Jv_VTable
*table
= *(_Jv_VTable
**) rcv
;
461 fun
= (void (*)()) table
->get_method (rmeth
->method
->index
);
465 #endif /* DIRECT_THREADED */
469 /* here goes the magic again... */
470 ffi_cif
*cif
= &rmeth
->cif
;
471 ffi_raw
*raw
= (ffi_raw
*) sp
;
475 #if FFI_NATIVE_RAW_API
476 /* We assume that this is only implemented if it's correct */
477 /* to use it here. On a 64 bit machine, it never is. */
478 ffi_raw_call (cif
, fun
, (void*)&rvalue
, raw
);
480 ffi_java_raw_call (cif
, fun
, (void*)&rvalue
, raw
);
483 int rtype
= cif
->rtype
->type
;
485 /* the likelyhood of object, int, or void return is very high,
486 * so those are checked before the switch */
487 if (rtype
== FFI_TYPE_POINTER
)
489 PUSHA (rvalue
.object_value
);
491 else if (rtype
== FFI_TYPE_SINT32
)
493 PUSHI (rvalue
.int_value
);
495 else if (rtype
== FFI_TYPE_VOID
)
504 PUSHI ((jbyte
)(rvalue
.int_value
& 0xff));
507 case FFI_TYPE_SINT16
:
508 PUSHI ((jshort
)(rvalue
.int_value
& 0xffff));
511 case FFI_TYPE_UINT16
:
512 PUSHI (rvalue
.int_value
& 0xffff);
516 PUSHF (rvalue
.float_value
);
519 case FFI_TYPE_DOUBLE
:
520 PUSHD (rvalue
.double_value
);
523 case FFI_TYPE_SINT64
:
524 PUSHL (rvalue
.long_value
);
528 throw_internal_error ("unknown return type in invokeXXX");
595 // For direct threaded, bipush and sipush are the same.
596 #ifndef DIRECT_THREADED
599 #endif /* DIRECT_THREADED */
605 // For direct threaded, ldc and ldc_w are the same.
606 #ifndef DIRECT_THREADED
607 PUSHA ((jobject
) AVAL1U ());
609 #endif /* DIRECT_THREADED */
611 PUSHA ((jobject
) AVAL2U ());
614 #ifdef DIRECT_THREADED
615 // For direct threaded we have a separate 'ldc class' operation.
619 // We could rewrite the instruction at this point.
620 int index
= INTVAL ();
621 jobject k
= (_Jv_Linker::resolve_pool_entry (meth
->defining_class
,
626 #endif /* DIRECT_THREADED */
630 void *where
= AVAL2UP ();
631 memcpy (sp
, where
, 2*sizeof (_Jv_word
));
727 jintArray arr
= (jintArray
) POPA();
728 NULLARRAYCHECK (arr
);
729 ARRAYBOUNDSCHECK (arr
, index
);
730 PUSHI( elements(arr
)[index
] );
737 jlongArray arr
= (jlongArray
) POPA();
738 NULLARRAYCHECK (arr
);
739 ARRAYBOUNDSCHECK (arr
, index
);
740 PUSHL( elements(arr
)[index
] );
747 jfloatArray arr
= (jfloatArray
) POPA();
748 NULLARRAYCHECK (arr
);
749 ARRAYBOUNDSCHECK (arr
, index
);
750 PUSHF( elements(arr
)[index
] );
757 jdoubleArray arr
= (jdoubleArray
) POPA();
758 NULLARRAYCHECK (arr
);
759 ARRAYBOUNDSCHECK (arr
, index
);
760 PUSHD( elements(arr
)[index
] );
767 jobjectArray arr
= (jobjectArray
) POPA();
768 NULLARRAYCHECK (arr
);
769 ARRAYBOUNDSCHECK (arr
, index
);
770 PUSHA( elements(arr
)[index
] );
777 jbyteArray arr
= (jbyteArray
) POPA();
778 NULLARRAYCHECK (arr
);
779 ARRAYBOUNDSCHECK (arr
, index
);
780 PUSHI( elements(arr
)[index
] );
787 jcharArray arr
= (jcharArray
) POPA();
788 NULLARRAYCHECK (arr
);
789 ARRAYBOUNDSCHECK (arr
, index
);
790 PUSHI( elements(arr
)[index
] );
797 jshortArray arr
= (jshortArray
) POPA();
798 NULLARRAYCHECK (arr
);
799 ARRAYBOUNDSCHECK (arr
, index
);
800 PUSHI( elements(arr
)[index
] );
908 jintArray arr
= (jintArray
) POPA();
909 NULLARRAYCHECK (arr
);
910 ARRAYBOUNDSCHECK (arr
, index
);
911 elements(arr
)[index
] = value
;
917 jlong value
= POPL();
919 jlongArray arr
= (jlongArray
) POPA();
920 NULLARRAYCHECK (arr
);
921 ARRAYBOUNDSCHECK (arr
, index
);
922 elements(arr
)[index
] = value
;
928 jfloat value
= POPF();
930 jfloatArray arr
= (jfloatArray
) POPA();
931 NULLARRAYCHECK (arr
);
932 ARRAYBOUNDSCHECK (arr
, index
);
933 elements(arr
)[index
] = value
;
939 jdouble value
= POPD();
941 jdoubleArray arr
= (jdoubleArray
) POPA();
942 NULLARRAYCHECK (arr
);
943 ARRAYBOUNDSCHECK (arr
, index
);
944 elements(arr
)[index
] = value
;
950 jobject value
= POPA();
952 jobjectArray arr
= (jobjectArray
) POPA();
953 NULLARRAYCHECK (arr
);
954 ARRAYBOUNDSCHECK (arr
, index
);
955 _Jv_CheckArrayStore (arr
, value
);
956 elements(arr
)[index
] = value
;
962 jbyte value
= (jbyte
) POPI();
964 jbyteArray arr
= (jbyteArray
) POPA();
965 NULLARRAYCHECK (arr
);
966 ARRAYBOUNDSCHECK (arr
, index
);
967 elements(arr
)[index
] = value
;
973 jchar value
= (jchar
) POPI();
975 jcharArray arr
= (jcharArray
) POPA();
976 NULLARRAYCHECK (arr
);
977 ARRAYBOUNDSCHECK (arr
, index
);
978 elements(arr
)[index
] = value
;
984 jshort value
= (jshort
) POPI();
986 jshortArray arr
= (jshortArray
) POPA();
987 NULLARRAYCHECK (arr
);
988 ARRAYBOUNDSCHECK (arr
, index
);
989 elements(arr
)[index
] = value
;
1007 dupx (sp
, 1, 1); sp
+=1;
1011 dupx (sp
, 1, 2); sp
+=1;
1021 dupx (sp
, 2, 1); sp
+=2;
1025 dupx (sp
, 2, 2); sp
+=2;
1030 jobject tmp1
= POPA();
1031 jobject tmp2
= POPA();
1088 jint value2
= POPI();
1089 jint value1
= POPI();
1090 jint res
= _Jv_divI (value1
, value2
);
1098 jlong value2
= POPL();
1099 jlong value1
= POPL();
1100 jlong res
= _Jv_divJ (value1
, value2
);
1107 jfloat value2
= POPF();
1108 jfloat value1
= POPF();
1109 jfloat res
= value1
/ value2
;
1116 jdouble value2
= POPD();
1117 jdouble value1
= POPD();
1118 jdouble res
= value1
/ value2
;
1126 jint value2
= POPI();
1127 jint value1
= POPI();
1128 jint res
= _Jv_remI (value1
, value2
);
1136 jlong value2
= POPL();
1137 jlong value1
= POPL();
1138 jlong res
= _Jv_remJ (value1
, value2
);
1145 jfloat value2
= POPF();
1146 jfloat value1
= POPF();
1147 jfloat res
= __ieee754_fmod (value1
, value2
);
1154 jdouble value2
= POPD();
1155 jdouble value1
= POPD();
1156 jdouble res
= __ieee754_fmod (value1
, value2
);
1163 jint value
= POPI();
1170 jlong value
= POPL();
1177 jfloat value
= POPF();
1184 jdouble value
= POPD();
1191 jint shift
= (POPI() & 0x1f);
1192 jint value
= POPI();
1193 PUSHI (value
<< shift
);
1199 jint shift
= (POPI() & 0x3f);
1200 jlong value
= POPL();
1201 PUSHL (value
<< shift
);
1207 jint shift
= (POPI() & 0x1f);
1208 jint value
= POPI();
1209 PUSHI (value
>> shift
);
1215 jint shift
= (POPI() & 0x3f);
1216 jlong value
= POPL();
1217 PUSHL (value
>> shift
);
1223 jint shift
= (POPI() & 0x1f);
1224 _Jv_uint value
= (_Jv_uint
) POPI();
1225 PUSHI ((jint
) (value
>> shift
));
1231 jint shift
= (POPI() & 0x3f);
1232 _Jv_ulong value
= (_Jv_ulong
) POPL();
1233 PUSHL ((jlong
) (value
>> shift
));
1263 jint index
= GET1U ();
1264 jint amount
= GET1S ();
1265 locals
[index
].i
+= amount
;
1270 {jlong value
= POPI(); PUSHL (value
);}
1274 {jfloat value
= POPI(); PUSHF (value
);}
1278 {jdouble value
= POPI(); PUSHD (value
);}
1282 {jint value
= POPL(); PUSHI (value
);}
1286 {jfloat value
= POPL(); PUSHF (value
);}
1290 {jdouble value
= POPL(); PUSHD (value
);}
1295 using namespace java::lang
;
1296 jint value
= convert (POPF (), Integer::MIN_VALUE
, Integer::MAX_VALUE
);
1303 using namespace java::lang
;
1304 jlong value
= convert (POPF (), Long::MIN_VALUE
, Long::MAX_VALUE
);
1310 { jdouble value
= POPF (); PUSHD(value
); }
1315 using namespace java::lang
;
1316 jint value
= convert (POPD (), Integer::MIN_VALUE
, Integer::MAX_VALUE
);
1323 using namespace java::lang
;
1324 jlong value
= convert (POPD (), Long::MIN_VALUE
, Long::MAX_VALUE
);
1330 { jfloat value
= POPD (); PUSHF(value
); }
1334 { jbyte value
= POPI (); PUSHI(value
); }
1338 { jchar value
= POPI (); PUSHI(value
); }
1342 { jshort value
= POPI (); PUSHI(value
); }
1347 jlong value2
= POPL ();
1348 jlong value1
= POPL ();
1349 if (value1
> value2
)
1351 else if (value1
== value2
)
1367 jfloat value2
= POPF ();
1368 jfloat value1
= POPF ();
1369 if (value1
> value2
)
1371 else if (value1
== value2
)
1373 else if (value1
< value2
)
1389 jdouble value2
= POPD ();
1390 jdouble value1
= POPD ();
1391 if (value1
> value2
)
1393 else if (value1
== value2
)
1395 else if (value1
< value2
)
1458 jint value2
= POPI();
1459 jint value1
= POPI();
1460 if (value1
== value2
)
1469 jint value2
= POPI();
1470 jint value1
= POPI();
1471 if (value1
!= value2
)
1480 jint value2
= POPI();
1481 jint value1
= POPI();
1482 if (value1
< value2
)
1491 jint value2
= POPI();
1492 jint value1
= POPI();
1493 if (value1
>= value2
)
1502 jint value2
= POPI();
1503 jint value1
= POPI();
1504 if (value1
> value2
)
1513 jint value2
= POPI();
1514 jint value1
= POPI();
1515 if (value1
<= value2
)
1524 jobject value2
= POPA();
1525 jobject value1
= POPA();
1526 if (value1
== value2
)
1535 jobject value2
= POPA();
1536 jobject value1
= POPA();
1537 if (value1
!= value2
)
1545 #ifndef DIRECT_THREADED
1546 // For direct threaded, goto and goto_w are the same.
1547 pc
= pc
- 1 + get4 (pc
);
1549 #endif /* DIRECT_THREADED */
1555 #ifndef DIRECT_THREADED
1556 // For direct threaded, jsr and jsr_w are the same.
1558 pc_t next
= pc
- 1 + get4 (pc
);
1560 PUSHA ((jobject
) pc
);
1564 #endif /* DIRECT_THREADED */
1567 pc_t next
= GOTO_VAL();
1569 PUSHA ((jobject
) pc
);
1576 jint index
= GET1U ();
1577 pc
= (pc_t
) PEEKA (index
);
1583 #ifdef DIRECT_THREADED
1584 void *def
= (pc
++)->datum
;
1588 jint low
= INTVAL ();
1589 jint high
= INTVAL ();
1591 if (index
< low
|| index
> high
)
1592 pc
= (insn_slot
*) def
;
1594 pc
= (insn_slot
*) ((pc
+ index
- low
)->datum
);
1596 pc_t base_pc
= pc
- 1;
1597 int index
= POPI ();
1599 pc_t base
= (pc_t
) meth
->bytecode ();
1600 while ((pc
- base
) % 4 != 0)
1603 jint def
= get4 (pc
);
1604 jint low
= get4 (pc
+ 4);
1605 jint high
= get4 (pc
+ 8);
1606 if (index
< low
|| index
> high
)
1609 pc
= base_pc
+ get4 (pc
+ 4 * (index
- low
+ 3));
1610 #endif /* DIRECT_THREADED */
1616 #ifdef DIRECT_THREADED
1617 void *def
= (pc
++)->insn
;
1621 jint npairs
= INTVAL ();
1623 int max
= npairs
- 1;
1626 // Simple binary search...
1629 int half
= (min
+ max
) / 2;
1630 int match
= pc
[2 * half
].int_val
;
1635 pc
= (insn_slot
*) pc
[2 * half
+ 1].datum
;
1638 else if (index
< match
)
1639 // We can use HALF - 1 here because we check again on
1643 // We can use HALF + 1 here because we check again on
1647 if (index
== pc
[2 * min
].int_val
)
1648 pc
= (insn_slot
*) pc
[2 * min
+ 1].datum
;
1650 pc
= (insn_slot
*) def
;
1652 unsigned char *base_pc
= pc
-1;
1655 unsigned char* base
= meth
->bytecode ();
1656 while ((pc
-base
) % 4 != 0)
1659 jint def
= get4 (pc
);
1660 jint npairs
= get4 (pc
+4);
1665 // Simple binary search...
1668 int half
= (min
+max
)/2;
1669 int match
= get4 (pc
+ 4*(2 + 2*half
));
1673 else if (index
< match
)
1674 // We can use HALF - 1 here because we check again on
1678 // We can use HALF + 1 here because we check again on
1683 if (index
== get4 (pc
+ 4*(2 + 2*min
)))
1684 pc
= base_pc
+ get4 (pc
+ 4*(2 + 2*min
+ 1));
1687 #endif /* DIRECT_THREADED */
1692 *(jobject
*) retp
= POPA ();
1696 *(jlong
*) retp
= POPL ();
1700 *(jfloat
*) retp
= POPF ();
1704 *(jdouble
*) retp
= POPD ();
1708 *(jint
*) retp
= POPI ();
1716 jint fieldref_index
= GET2U ();
1717 SAVE_PC(); // Constant pool resolution could throw.
1718 _Jv_Linker::resolve_pool_entry (meth
->defining_class
, fieldref_index
);
1719 _Jv_Field
*field
= pool_data
[fieldref_index
].field
;
1721 if ((field
->flags
& Modifier::STATIC
) == 0)
1722 throw_incompatible_class_change_error
1723 (JvNewStringLatin1 ("field no longer static"));
1725 jclass type
= field
->type
;
1727 // We rewrite the instruction once we discover what it refers
1729 void *newinsn
= NULL
;
1730 if (type
->isPrimitive ())
1732 switch (type
->size_in_bytes
)
1735 PUSHI (*field
->u
.byte_addr
);
1736 newinsn
= AMPAMP (getstatic_resolved_1
);
1740 if (type
== JvPrimClass (char))
1742 PUSHI (*field
->u
.char_addr
);
1743 newinsn
= AMPAMP (getstatic_resolved_char
);
1747 PUSHI (*field
->u
.short_addr
);
1748 newinsn
= AMPAMP (getstatic_resolved_short
);
1753 PUSHI(*field
->u
.int_addr
);
1754 newinsn
= AMPAMP (getstatic_resolved_4
);
1758 PUSHL(*field
->u
.long_addr
);
1759 newinsn
= AMPAMP (getstatic_resolved_8
);
1765 PUSHA(*field
->u
.object_addr
);
1766 newinsn
= AMPAMP (getstatic_resolved_obj
);
1769 #ifdef DIRECT_THREADED
1770 pc
[-2].insn
= newinsn
;
1771 pc
[-1].datum
= field
->u
.addr
;
1772 #endif /* DIRECT_THREADED */
1776 #ifdef DIRECT_THREADED
1777 getstatic_resolved_1
:
1778 PUSHI (*(jbyte
*) AVAL ());
1781 getstatic_resolved_char
:
1782 PUSHI (*(jchar
*) AVAL ());
1785 getstatic_resolved_short
:
1786 PUSHI (*(jshort
*) AVAL ());
1789 getstatic_resolved_4
:
1790 PUSHI (*(jint
*) AVAL ());
1793 getstatic_resolved_8
:
1794 PUSHL (*(jlong
*) AVAL ());
1797 getstatic_resolved_obj
:
1798 PUSHA (*(jobject
*) AVAL ());
1800 #endif /* DIRECT_THREADED */
1805 jint fieldref_index
= GET2U ();
1806 _Jv_Linker::resolve_pool_entry (meth
->defining_class
, fieldref_index
);
1807 _Jv_Field
*field
= pool_data
[fieldref_index
].field
;
1809 if ((field
->flags
& Modifier::STATIC
) != 0)
1810 throw_incompatible_class_change_error
1811 (JvNewStringLatin1 ("field is static"));
1813 jclass type
= field
->type
;
1814 jint field_offset
= field
->u
.boffset
;
1816 jobject obj
= POPA();
1819 void *newinsn
= NULL
;
1820 _Jv_value
*val
= (_Jv_value
*) ((char *)obj
+ field_offset
);
1821 if (type
->isPrimitive ())
1823 switch (type
->size_in_bytes
)
1826 PUSHI (val
->byte_value
);
1827 newinsn
= AMPAMP (getfield_resolved_1
);
1831 if (type
== JvPrimClass (char))
1833 PUSHI (val
->char_value
);
1834 newinsn
= AMPAMP (getfield_resolved_char
);
1838 PUSHI (val
->short_value
);
1839 newinsn
= AMPAMP (getfield_resolved_short
);
1844 PUSHI (val
->int_value
);
1845 newinsn
= AMPAMP (getfield_resolved_4
);
1849 PUSHL (val
->long_value
);
1850 newinsn
= AMPAMP (getfield_resolved_8
);
1856 PUSHA (val
->object_value
);
1857 newinsn
= AMPAMP (getfield_resolved_obj
);
1860 #ifdef DIRECT_THREADED
1861 pc
[-2].insn
= newinsn
;
1862 pc
[-1].int_val
= field_offset
;
1863 #endif /* DIRECT_THREADED */
1867 #ifdef DIRECT_THREADED
1868 getfield_resolved_1
:
1870 char *obj
= (char *) POPA ();
1872 PUSHI (*(jbyte
*) (obj
+ INTVAL ()));
1876 getfield_resolved_char
:
1878 char *obj
= (char *) POPA ();
1880 PUSHI (*(jchar
*) (obj
+ INTVAL ()));
1884 getfield_resolved_short
:
1886 char *obj
= (char *) POPA ();
1888 PUSHI (*(jshort
*) (obj
+ INTVAL ()));
1892 getfield_resolved_4
:
1894 char *obj
= (char *) POPA ();
1896 PUSHI (*(jint
*) (obj
+ INTVAL ()));
1900 getfield_resolved_8
:
1902 char *obj
= (char *) POPA ();
1904 PUSHL (*(jlong
*) (obj
+ INTVAL ()));
1908 getfield_resolved_obj
:
1910 char *obj
= (char *) POPA ();
1912 PUSHA (*(jobject
*) (obj
+ INTVAL ()));
1915 #endif /* DIRECT_THREADED */
1920 jint fieldref_index
= GET2U ();
1921 _Jv_Linker::resolve_pool_entry (meth
->defining_class
, fieldref_index
);
1922 _Jv_Field
*field
= pool_data
[fieldref_index
].field
;
1924 jclass type
= field
->type
;
1926 // ResolvePoolEntry cannot check this
1927 if ((field
->flags
& Modifier::STATIC
) == 0)
1928 throw_incompatible_class_change_error
1929 (JvNewStringLatin1 ("field no longer static"));
1931 void *newinsn
= NULL
;
1932 if (type
->isPrimitive ())
1934 switch (type
->size_in_bytes
)
1938 jint value
= POPI();
1939 *field
->u
.byte_addr
= value
;
1940 newinsn
= AMPAMP (putstatic_resolved_1
);
1946 jint value
= POPI();
1947 *field
->u
.char_addr
= value
;
1948 newinsn
= AMPAMP (putstatic_resolved_2
);
1954 jint value
= POPI();
1955 *field
->u
.int_addr
= value
;
1956 newinsn
= AMPAMP (putstatic_resolved_4
);
1962 jlong value
= POPL();
1963 *field
->u
.long_addr
= value
;
1964 newinsn
= AMPAMP (putstatic_resolved_8
);
1971 jobject value
= POPA();
1972 *field
->u
.object_addr
= value
;
1973 newinsn
= AMPAMP (putstatic_resolved_obj
);
1976 #ifdef DIRECT_THREADED
1977 pc
[-2].insn
= newinsn
;
1978 pc
[-1].datum
= field
->u
.addr
;
1979 #endif /* DIRECT_THREADED */
1983 #ifdef DIRECT_THREADED
1984 putstatic_resolved_1
:
1985 *(jbyte
*) AVAL () = POPI ();
1988 putstatic_resolved_2
:
1989 *(jchar
*) AVAL () = POPI ();
1992 putstatic_resolved_4
:
1993 *(jint
*) AVAL () = POPI ();
1996 putstatic_resolved_8
:
1997 *(jlong
*) AVAL () = POPL ();
2000 putstatic_resolved_obj
:
2001 *(jobject
*) AVAL () = POPA ();
2003 #endif /* DIRECT_THREADED */
2008 jint fieldref_index
= GET2U ();
2009 _Jv_Linker::resolve_pool_entry (meth
->defining_class
, fieldref_index
);
2010 _Jv_Field
*field
= pool_data
[fieldref_index
].field
;
2012 jclass type
= field
->type
;
2014 if ((field
->flags
& Modifier::STATIC
) != 0)
2015 throw_incompatible_class_change_error
2016 (JvNewStringLatin1 ("field is static"));
2018 jint field_offset
= field
->u
.boffset
;
2020 void *newinsn
= NULL
;
2021 if (type
->isPrimitive ())
2023 switch (type
->size_in_bytes
)
2027 jint value
= POPI();
2028 jobject obj
= POPA();
2030 *(jbyte
*) ((char*)obj
+ field_offset
) = value
;
2031 newinsn
= AMPAMP (putfield_resolved_1
);
2037 jint value
= POPI();
2038 jobject obj
= POPA();
2040 *(jchar
*) ((char*)obj
+ field_offset
) = value
;
2041 newinsn
= AMPAMP (putfield_resolved_2
);
2047 jint value
= POPI();
2048 jobject obj
= POPA();
2050 *(jint
*) ((char*)obj
+ field_offset
) = value
;
2051 newinsn
= AMPAMP (putfield_resolved_4
);
2057 jlong value
= POPL();
2058 jobject obj
= POPA();
2060 *(jlong
*) ((char*)obj
+ field_offset
) = value
;
2061 newinsn
= AMPAMP (putfield_resolved_8
);
2068 jobject value
= POPA();
2069 jobject obj
= POPA();
2071 *(jobject
*) ((char*)obj
+ field_offset
) = value
;
2072 newinsn
= AMPAMP (putfield_resolved_obj
);
2075 #ifdef DIRECT_THREADED
2076 pc
[-2].insn
= newinsn
;
2077 pc
[-1].int_val
= field_offset
;
2078 #endif /* DIRECT_THREADED */
2082 #ifdef DIRECT_THREADED
2083 putfield_resolved_1
:
2086 char *obj
= (char *) POPA ();
2088 *(jbyte
*) (obj
+ INTVAL ()) = val
;
2092 putfield_resolved_2
:
2095 char *obj
= (char *) POPA ();
2097 *(jchar
*) (obj
+ INTVAL ()) = val
;
2101 putfield_resolved_4
:
2104 char *obj
= (char *) POPA ();
2106 *(jint
*) (obj
+ INTVAL ()) = val
;
2110 putfield_resolved_8
:
2112 jlong val
= POPL ();
2113 char *obj
= (char *) POPA ();
2115 *(jlong
*) (obj
+ INTVAL ()) = val
;
2119 putfield_resolved_obj
:
2121 jobject val
= POPA ();
2122 char *obj
= (char *) POPA ();
2124 *(jobject
*) (obj
+ INTVAL ()) = val
;
2127 #endif /* DIRECT_THREADED */
2132 int index
= GET2U ();
2134 rmeth
= (_Jv_Linker::resolve_pool_entry (meth
->defining_class
,
2137 sp
-= rmeth
->stack_item_count
;
2139 // We don't use NULLCHECK here because we can't rely on that
2140 // working for <init>. So instead we do an explicit test.
2144 throw_null_pointer_exception ();
2147 fun
= (void (*)()) rmeth
->method
->ncode
;
2149 #ifdef DIRECT_THREADED
2150 // Rewrite instruction so that we use a faster pre-resolved
2152 pc
[-2].insn
= &&invokespecial_resolved
;
2153 pc
[-1].datum
= rmeth
;
2154 #endif /* DIRECT_THREADED */
2156 goto perform_invoke
;
2158 #ifdef DIRECT_THREADED
2159 invokespecial_resolved
:
2162 rmeth
= (_Jv_ResolvedMethod
*) AVAL ();
2163 sp
-= rmeth
->stack_item_count
;
2164 // We don't use NULLCHECK here because we can't rely on that
2165 // working for <init>. So instead we do an explicit test.
2168 throw_null_pointer_exception ();
2170 fun
= (void (*)()) rmeth
->method
->ncode
;
2172 goto perform_invoke
;
2173 #endif /* DIRECT_THREADED */
2178 int index
= GET2U ();
2180 rmeth
= (_Jv_Linker::resolve_pool_entry (meth
->defining_class
,
2183 sp
-= rmeth
->stack_item_count
;
2185 fun
= (void (*)()) rmeth
->method
->ncode
;
2187 #ifdef DIRECT_THREADED
2188 // Rewrite instruction so that we use a faster pre-resolved
2190 pc
[-2].insn
= &&invokestatic_resolved
;
2191 pc
[-1].datum
= rmeth
;
2192 #endif /* DIRECT_THREADED */
2194 goto perform_invoke
;
2196 #ifdef DIRECT_THREADED
2197 invokestatic_resolved
:
2200 rmeth
= (_Jv_ResolvedMethod
*) AVAL ();
2201 sp
-= rmeth
->stack_item_count
;
2202 fun
= (void (*)()) rmeth
->method
->ncode
;
2204 goto perform_invoke
;
2205 #endif /* DIRECT_THREADED */
2207 insn_invokeinterface
:
2210 int index
= GET2U ();
2212 rmeth
= (_Jv_Linker::resolve_pool_entry (meth
->defining_class
,
2215 sp
-= rmeth
->stack_item_count
;
2217 jobject rcv
= sp
[0].o
;
2222 _Jv_LookupInterfaceMethod (rcv
->getClass (),
2223 rmeth
->method
->name
,
2224 rmeth
->method
->signature
);
2226 #ifdef DIRECT_THREADED
2227 // Rewrite instruction so that we use a faster pre-resolved
2229 pc
[-2].insn
= &&invokeinterface_resolved
;
2230 pc
[-1].datum
= rmeth
;
2232 // Skip dummy bytes.
2234 #endif /* DIRECT_THREADED */
2236 goto perform_invoke
;
2238 #ifdef DIRECT_THREADED
2239 invokeinterface_resolved
:
2242 rmeth
= (_Jv_ResolvedMethod
*) AVAL ();
2243 sp
-= rmeth
->stack_item_count
;
2244 jobject rcv
= sp
[0].o
;
2247 _Jv_LookupInterfaceMethod (rcv
->getClass (),
2248 rmeth
->method
->name
,
2249 rmeth
->method
->signature
);
2251 goto perform_invoke
;
2252 #endif /* DIRECT_THREADED */
2257 int index
= GET2U ();
2258 jclass klass
= (_Jv_Linker::resolve_pool_entry (meth
->defining_class
,
2260 /* VM spec, section 3.11.5 */
2261 if ((klass
->getModifiers() & Modifier::ABSTRACT
)
2262 || klass
->isInterface())
2263 throw new java::lang::InstantiationException
;
2264 jobject res
= _Jv_AllocObject (klass
);
2267 #ifdef DIRECT_THREADED
2268 pc
[-2].insn
= &&new_resolved
;
2269 pc
[-1].datum
= klass
;
2270 #endif /* DIRECT_THREADED */
2274 #ifdef DIRECT_THREADED
2277 jclass klass
= (jclass
) AVAL ();
2278 jobject res
= _Jv_AllocObject (klass
);
2282 #endif /* DIRECT_THREADED */
2286 int atype
= GET1U ();
2288 jobject result
= _Jv_NewArray (atype
, size
);
2296 int index
= GET2U ();
2297 jclass klass
= (_Jv_Linker::resolve_pool_entry (meth
->defining_class
,
2300 jobject result
= _Jv_NewObjectArray (size
, klass
, 0);
2303 #ifdef DIRECT_THREADED
2304 pc
[-2].insn
= &&anewarray_resolved
;
2305 pc
[-1].datum
= klass
;
2306 #endif /* DIRECT_THREADED */
2310 #ifdef DIRECT_THREADED
2313 jclass klass
= (jclass
) AVAL ();
2315 jobject result
= _Jv_NewObjectArray (size
, klass
, 0);
2319 #endif /* DIRECT_THREADED */
2323 __JArray
*arr
= (__JArray
*)POPA();
2324 NULLARRAYCHECK (arr
);
2325 PUSHI (arr
->length
);
2331 jobject value
= POPA();
2332 throw static_cast<jthrowable
>(value
);
2339 jobject value
= POPA();
2340 jint index
= GET2U ();
2341 jclass to
= (_Jv_Linker::resolve_pool_entry (meth
->defining_class
,
2344 value
= (jobject
) _Jv_CheckCast (to
, value
);
2348 #ifdef DIRECT_THREADED
2349 pc
[-2].insn
= &&checkcast_resolved
;
2351 #endif /* DIRECT_THREADED */
2355 #ifdef DIRECT_THREADED
2359 jobject value
= POPA ();
2360 jclass to
= (jclass
) AVAL ();
2361 value
= (jobject
) _Jv_CheckCast (to
, value
);
2365 #endif /* DIRECT_THREADED */
2370 jobject value
= POPA();
2371 jint index
= GET2U ();
2372 jclass to
= (_Jv_Linker::resolve_pool_entry (meth
->defining_class
,
2374 PUSHI (to
->isInstance (value
));
2376 #ifdef DIRECT_THREADED
2377 pc
[-2].insn
= &&instanceof_resolved
;
2379 #endif /* DIRECT_THREADED */
2383 #ifdef DIRECT_THREADED
2384 instanceof_resolved
:
2386 jobject value
= POPA ();
2387 jclass to
= (jclass
) AVAL ();
2388 PUSHI (to
->isInstance (value
));
2391 #endif /* DIRECT_THREADED */
2395 jobject value
= POPA();
2397 _Jv_MonitorEnter (value
);
2403 jobject value
= POPA();
2405 _Jv_MonitorExit (value
);
2411 jobject val
= POPA();
2421 jobject val
= POPA();
2429 insn_multianewarray
:
2432 int kind_index
= GET2U ();
2436 = (_Jv_Linker::resolve_pool_entry (meth
->defining_class
,
2438 jint
*sizes
= (jint
*) __builtin_alloca (sizeof (jint
)*dim
);
2440 for (int i
= dim
- 1; i
>= 0; i
--)
2445 jobject res
= _Jv_NewMultiArray (type
,dim
, sizes
);
2451 #ifndef DIRECT_THREADED
2454 jint the_mod_op
= get1u (pc
++);
2455 jint wide
= get2u (pc
); pc
+= 2;
2500 pc
= (unsigned char*) PEEKA (wide
);
2505 jint amount
= get2s (pc
); pc
+= 2;
2506 jint value
= PEEKI (wide
);
2507 POKEI (wide
, value
+amount
);
2512 throw_internal_error ("illegal bytecode modified by wide");
2516 #endif /* DIRECT_THREADED */
2520 JvAssert (JVMTI_REQUESTED_EVENT (Breakpoint
));
2522 // Send JVMTI notification
2523 using namespace ::java::lang
;
2524 jmethodID method
= meth
->self
;
2525 jlocation location
= meth
->insn_index (pc
- 1);
2526 Thread
*thread
= Thread::currentThread ();
2527 JNIEnv
*jni_env
= _Jv_GetCurrentJNIEnv ();
2529 _Jv_JVMTI_PostEvent (JVMTI_EVENT_BREAKPOINT
, thread
, jni_env
,
2532 // Continue execution
2533 using namespace gnu::gcj::jvmti
;
2535 = BreakpointManager::getBreakpoint (reinterpret_cast<jlong
> (method
),
2537 JvAssert (bp
!= NULL
);
2539 pc_t opc
= reinterpret_cast<pc_t
> (bp
->getInsn ());
2541 #ifdef DIRECT_THREADED
2544 goto *(insn_target
[*opc
]);
2548 catch (java::lang::Throwable
*ex
)
2551 // This needs to be done before the pc is changed.
2552 jlong throw_loc
= meth
->insn_index (pc
);
2554 // Check if the exception is handled and, if so, set the pc to the start
2555 // of the appropriate catch block.
2556 if (meth
->check_handler (&pc
, meth
, ex
))
2559 sp
++->o
= ex
; // Push exception.
2561 if (JVMTI_REQUESTED_EVENT (Exception
))
2563 using namespace gnu::gcj::jvmti
;
2564 jlong throw_meth
= reinterpret_cast<jlong
> (meth
->get_method ());
2565 jlong catch_loc
= meth
->insn_index (pc
);
2566 ExceptionEvent::postExceptionEvent (thread
, throw_meth
,
2567 throw_loc
, ex
, throw_meth
,
2574 if (JVMTI_REQUESTED_EVENT (Exception
))
2576 using namespace gnu::gcj::jvmti
;
2577 jlong throw_meth
= reinterpret_cast<jlong
> (meth
->get_method ());
2578 ExceptionEvent::postExceptionEvent (thread
, throw_meth
, throw_loc
,
2582 // No handler, so re-throw.