Check in tree-dce enh to trunk
[official-gcc.git] / libjava / interpret-run.cc
blobf858c971e0bb7427f593b6170f96813c1642abe5
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
9 details. */
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 pc_t pc = NULL;
18 // FRAME_DESC registers this particular invocation as the top-most
19 // interpreter frame. This lets the stack tracing code (for
20 // Throwable) print information about the method being interpreted
21 // rather than about the interpreter itself. FRAME_DESC has a
22 // destructor so it cleans up automatically when the interpreter
23 // returns.
24 java::lang::Thread *thread = java::lang::Thread::currentThread();
26 #ifdef DEBUG
27 _Jv_InterpFrame frame_desc (meth, thread, NULL, &pc);
28 #else
29 _Jv_InterpFrame frame_desc (meth, thread);
30 #endif
32 _Jv_word stack[meth->max_stack];
33 _Jv_word *sp = stack;
35 _Jv_word locals[meth->max_locals];
37 #ifdef DEBUG
38 // This is the information needed to get and set local variables with
39 // proper type checking.
40 frame_desc.locals = locals;
41 char locals_type[meth->max_locals];
42 frame_desc.locals_type = locals_type;
44 // Set all slots as invalid until they are written to.
45 memset (locals_type, 'x', meth->max_locals);
47 // We need to set the local variable types for the method arguments since
48 // they are valid at invocation.
50 _Jv_Method *method = meth->get_method ();
51 int type_ctr = 0;
53 // If the method is non-static, we need to set the type for the "this" pointer.
54 if ((method->accflags & java::lang::reflect::Modifier::STATIC) == 0)
56 if (args)
58 // Set the "this" pointer for this frame.
59 _Jv_word *this_ptr = reinterpret_cast<_Jv_word *> (args);
60 frame_desc.obj_ptr = this_ptr[0].o;
63 frame_desc.locals_type[0] = 'o';
64 type_ctr++;
67 // Now parse the method signature to set the types of the other arguments.
68 int sig_len = method->signature->len ();
69 char *signature = method->signature->chars ();
70 for (int i = 1; signature[i] != ')' && i <= sig_len; i++)
72 if (signature[i] == 'Z' || signature[i] == 'B' || signature[i] == 'C'
73 || signature[i] == 'S' || signature[i] == 'I')
75 frame_desc.locals_type[type_ctr] = 'i';
76 type_ctr++;
77 continue;
79 else if (signature[i] == 'F')
81 frame_desc.locals_type[type_ctr] = 'f';
82 type_ctr++;
83 continue;
85 else if (signature[i] == 'J')
87 frame_desc.locals_type[type_ctr] = 'l';
88 frame_desc.locals_type[type_ctr+1] = 'x';
89 type_ctr += 2;
90 continue;
92 else if (signature[i] == 'D')
94 frame_desc.locals_type[type_ctr] = 'd';
95 frame_desc.locals_type[type_ctr+1] = 'x';
96 type_ctr += 2;
97 continue;
99 else if (signature[i] == 'L')
101 frame_desc.locals_type[type_ctr] = 'o';
102 type_ctr++;
103 while (signature[i] != ';')
104 i++;
105 continue;
107 else if (signature[i] == '[')
109 frame_desc.locals_type[type_ctr] = 'o';
110 type_ctr++;
112 // Ignore multi-dimensional arrays.
113 while (signature[i] == '[')
114 i++;
116 // Check for an object array
117 if (signature[i] == 'L')
119 while (signature[i] != ';')
120 i++;
122 continue;
125 #endif /* DEBUG */
127 #define INSN_LABEL(op) &&insn_##op
129 static const void *const insn_target[] =
131 INSN_LABEL(nop),
132 INSN_LABEL(aconst_null),
133 INSN_LABEL(iconst_m1),
134 INSN_LABEL(iconst_0),
135 INSN_LABEL(iconst_1),
136 INSN_LABEL(iconst_2),
137 INSN_LABEL(iconst_3),
138 INSN_LABEL(iconst_4),
139 INSN_LABEL(iconst_5),
140 INSN_LABEL(lconst_0),
141 INSN_LABEL(lconst_1),
142 INSN_LABEL(fconst_0),
143 INSN_LABEL(fconst_1),
144 INSN_LABEL(fconst_2),
145 INSN_LABEL(dconst_0),
146 INSN_LABEL(dconst_1),
147 INSN_LABEL(bipush),
148 INSN_LABEL(sipush),
149 INSN_LABEL(ldc),
150 INSN_LABEL(ldc_w),
151 INSN_LABEL(ldc2_w),
152 INSN_LABEL(iload),
153 INSN_LABEL(lload),
154 INSN_LABEL(fload),
155 INSN_LABEL(dload),
156 INSN_LABEL(aload),
157 INSN_LABEL(iload_0),
158 INSN_LABEL(iload_1),
159 INSN_LABEL(iload_2),
160 INSN_LABEL(iload_3),
161 INSN_LABEL(lload_0),
162 INSN_LABEL(lload_1),
163 INSN_LABEL(lload_2),
164 INSN_LABEL(lload_3),
165 INSN_LABEL(fload_0),
166 INSN_LABEL(fload_1),
167 INSN_LABEL(fload_2),
168 INSN_LABEL(fload_3),
169 INSN_LABEL(dload_0),
170 INSN_LABEL(dload_1),
171 INSN_LABEL(dload_2),
172 INSN_LABEL(dload_3),
173 INSN_LABEL(aload_0),
174 INSN_LABEL(aload_1),
175 INSN_LABEL(aload_2),
176 INSN_LABEL(aload_3),
177 INSN_LABEL(iaload),
178 INSN_LABEL(laload),
179 INSN_LABEL(faload),
180 INSN_LABEL(daload),
181 INSN_LABEL(aaload),
182 INSN_LABEL(baload),
183 INSN_LABEL(caload),
184 INSN_LABEL(saload),
185 INSN_LABEL(istore),
186 INSN_LABEL(lstore),
187 INSN_LABEL(fstore),
188 INSN_LABEL(dstore),
189 INSN_LABEL(astore),
190 INSN_LABEL(istore_0),
191 INSN_LABEL(istore_1),
192 INSN_LABEL(istore_2),
193 INSN_LABEL(istore_3),
194 INSN_LABEL(lstore_0),
195 INSN_LABEL(lstore_1),
196 INSN_LABEL(lstore_2),
197 INSN_LABEL(lstore_3),
198 INSN_LABEL(fstore_0),
199 INSN_LABEL(fstore_1),
200 INSN_LABEL(fstore_2),
201 INSN_LABEL(fstore_3),
202 INSN_LABEL(dstore_0),
203 INSN_LABEL(dstore_1),
204 INSN_LABEL(dstore_2),
205 INSN_LABEL(dstore_3),
206 INSN_LABEL(astore_0),
207 INSN_LABEL(astore_1),
208 INSN_LABEL(astore_2),
209 INSN_LABEL(astore_3),
210 INSN_LABEL(iastore),
211 INSN_LABEL(lastore),
212 INSN_LABEL(fastore),
213 INSN_LABEL(dastore),
214 INSN_LABEL(aastore),
215 INSN_LABEL(bastore),
216 INSN_LABEL(castore),
217 INSN_LABEL(sastore),
218 INSN_LABEL(pop),
219 INSN_LABEL(pop2),
220 INSN_LABEL(dup),
221 INSN_LABEL(dup_x1),
222 INSN_LABEL(dup_x2),
223 INSN_LABEL(dup2),
224 INSN_LABEL(dup2_x1),
225 INSN_LABEL(dup2_x2),
226 INSN_LABEL(swap),
227 INSN_LABEL(iadd),
228 INSN_LABEL(ladd),
229 INSN_LABEL(fadd),
230 INSN_LABEL(dadd),
231 INSN_LABEL(isub),
232 INSN_LABEL(lsub),
233 INSN_LABEL(fsub),
234 INSN_LABEL(dsub),
235 INSN_LABEL(imul),
236 INSN_LABEL(lmul),
237 INSN_LABEL(fmul),
238 INSN_LABEL(dmul),
239 INSN_LABEL(idiv),
240 INSN_LABEL(ldiv),
241 INSN_LABEL(fdiv),
242 INSN_LABEL(ddiv),
243 INSN_LABEL(irem),
244 INSN_LABEL(lrem),
245 INSN_LABEL(frem),
246 INSN_LABEL(drem),
247 INSN_LABEL(ineg),
248 INSN_LABEL(lneg),
249 INSN_LABEL(fneg),
250 INSN_LABEL(dneg),
251 INSN_LABEL(ishl),
252 INSN_LABEL(lshl),
253 INSN_LABEL(ishr),
254 INSN_LABEL(lshr),
255 INSN_LABEL(iushr),
256 INSN_LABEL(lushr),
257 INSN_LABEL(iand),
258 INSN_LABEL(land),
259 INSN_LABEL(ior),
260 INSN_LABEL(lor),
261 INSN_LABEL(ixor),
262 INSN_LABEL(lxor),
263 INSN_LABEL(iinc),
264 INSN_LABEL(i2l),
265 INSN_LABEL(i2f),
266 INSN_LABEL(i2d),
267 INSN_LABEL(l2i),
268 INSN_LABEL(l2f),
269 INSN_LABEL(l2d),
270 INSN_LABEL(f2i),
271 INSN_LABEL(f2l),
272 INSN_LABEL(f2d),
273 INSN_LABEL(d2i),
274 INSN_LABEL(d2l),
275 INSN_LABEL(d2f),
276 INSN_LABEL(i2b),
277 INSN_LABEL(i2c),
278 INSN_LABEL(i2s),
279 INSN_LABEL(lcmp),
280 INSN_LABEL(fcmpl),
281 INSN_LABEL(fcmpg),
282 INSN_LABEL(dcmpl),
283 INSN_LABEL(dcmpg),
284 INSN_LABEL(ifeq),
285 INSN_LABEL(ifne),
286 INSN_LABEL(iflt),
287 INSN_LABEL(ifge),
288 INSN_LABEL(ifgt),
289 INSN_LABEL(ifle),
290 INSN_LABEL(if_icmpeq),
291 INSN_LABEL(if_icmpne),
292 INSN_LABEL(if_icmplt),
293 INSN_LABEL(if_icmpge),
294 INSN_LABEL(if_icmpgt),
295 INSN_LABEL(if_icmple),
296 INSN_LABEL(if_acmpeq),
297 INSN_LABEL(if_acmpne),
298 INSN_LABEL(goto),
299 INSN_LABEL(jsr),
300 INSN_LABEL(ret),
301 INSN_LABEL(tableswitch),
302 INSN_LABEL(lookupswitch),
303 INSN_LABEL(ireturn),
304 INSN_LABEL(lreturn),
305 INSN_LABEL(freturn),
306 INSN_LABEL(dreturn),
307 INSN_LABEL(areturn),
308 INSN_LABEL(return),
309 INSN_LABEL(getstatic),
310 INSN_LABEL(putstatic),
311 INSN_LABEL(getfield),
312 INSN_LABEL(putfield),
313 INSN_LABEL(invokevirtual),
314 INSN_LABEL(invokespecial),
315 INSN_LABEL(invokestatic),
316 INSN_LABEL(invokeinterface),
317 INSN_LABEL(breakpoint),
318 INSN_LABEL(new),
319 INSN_LABEL(newarray),
320 INSN_LABEL(anewarray),
321 INSN_LABEL(arraylength),
322 INSN_LABEL(athrow),
323 INSN_LABEL(checkcast),
324 INSN_LABEL(instanceof),
325 INSN_LABEL(monitorenter),
326 INSN_LABEL(monitorexit),
327 #ifdef DIRECT_THREADED
328 0, // wide
329 #else
330 INSN_LABEL(wide),
331 #endif
332 INSN_LABEL(multianewarray),
333 INSN_LABEL(ifnull),
334 INSN_LABEL(ifnonnull),
335 INSN_LABEL(goto_w),
336 INSN_LABEL(jsr_w),
337 #ifdef DIRECT_THREADED
338 INSN_LABEL (ldc_class)
339 #else
341 #endif
344 #ifdef DIRECT_THREADED
346 #ifdef DEBUG
347 #undef NEXT_INSN
348 #define NEXT_INSN \
349 do \
351 pc_t insn = pc++; \
352 if (JVMTI_REQUESTED_EVENT (SingleStep)) \
354 JNIEnv *env = _Jv_GetCurrentJNIEnv (); \
355 jmethodID method = meth->self; \
356 jlocation loc = meth->insn_index (insn); \
357 _Jv_JVMTI_PostEvent (JVMTI_EVENT_SINGLE_STEP, thread, \
358 env, method, loc); \
360 goto *(insn->insn); \
362 while (0)
364 #undef REWRITE_INSN
365 #define REWRITE_INSN(INSN,SLOT,VALUE) \
366 do { \
367 if (pc[-2].insn == breakpoint_insn->insn) \
369 using namespace ::gnu::gcj::jvmti; \
370 jlocation location = meth->insn_index (pc - 2); \
371 _Jv_RewriteBreakpointInsn (meth->self, location, (pc_t) INSN); \
373 else \
374 pc[-2].insn = INSN; \
376 pc[-1].SLOT = VALUE; \
378 while (0)
380 #undef INTERP_REPORT_EXCEPTION
381 #define INTERP_REPORT_EXCEPTION(Jthrowable) REPORT_EXCEPTION (Jthrowable)
382 #else // !DEBUG
383 #undef NEXT_INSN
384 #define NEXT_INSN goto *((pc++)->insn)
385 #define REWRITE_INSN(INSN,SLOT,VALUE) \
386 do { \
387 pc[-2].insn = INSN; \
388 pc[-1].SLOT = VALUE; \
390 while (0)
392 #undef INTERP_REPORT_EXCEPTION
393 #define INTERP_REPORT_EXCEPTION(Jthrowable) /* not needed when not debugging */
394 #endif // !DEBUG
396 #define INTVAL() ((pc++)->int_val)
397 #define AVAL() ((pc++)->datum)
399 #define GET1S() INTVAL ()
400 #define GET2S() INTVAL ()
401 #define GET1U() INTVAL ()
402 #define GET2U() INTVAL ()
403 #define AVAL1U() AVAL ()
404 #define AVAL2U() AVAL ()
405 #define AVAL2UP() AVAL ()
406 #define SKIP_GOTO ++pc
407 #define GOTO_VAL() (insn_slot *) pc->datum
408 #define PCVAL(unionval) unionval.p
409 #define AMPAMP(label) &&label
411 // Compile if we must. NOTE: Double-check locking.
412 if (meth->prepared == NULL)
414 _Jv_MutexLock (&compile_mutex);
415 if (meth->prepared == NULL)
416 meth->compile (insn_target);
417 _Jv_MutexUnlock (&compile_mutex);
420 // If we're only compiling, stop here
421 if (args == NULL)
422 return;
424 pc = (insn_slot *) meth->prepared;
426 #else
428 #ifdef DEBUG
429 #define NEXT_INSN \
430 do \
432 if (JVMTI_REQUESTED_EVENT (SingleStep)) \
434 JNIEnv *env = _Jv_GetCurrentJNIEnv (); \
435 jmethodID method = meth->self; \
436 jlocation loc = meth->insn_index (pc); \
437 _Jv_JVMTI_PostEvent (JVMTI_EVENT_SINGLE_STEP, thread, \
438 env, method, loc); \
440 goto *(insn_target[*pc++])
441 #else
442 #define NEXT_INSN goto *(insn_target[*pc++])
443 #endif
445 #define GET1S() get1s (pc++)
446 #define GET2S() (pc += 2, get2s (pc- 2))
447 #define GET1U() get1u (pc++)
448 #define GET2U() (pc += 2, get2u (pc - 2))
449 // Note that these could be more efficient when not handling 'ldc
450 // class'.
451 #define AVAL1U() \
452 ({ int index = get1u (pc++); \
453 _Jv_Linker::resolve_pool_entry (meth->defining_class, index).o; })
454 #define AVAL2U() \
455 ({ int index = get2u (pc); pc += 2; \
456 _Jv_Linker::resolve_pool_entry (meth->defining_class, index).o; })
457 // Note that we don't need to resolve the pool entry here as class
458 // constants are never wide.
459 #define AVAL2UP() ({ int index = get2u (pc); pc += 2; &pool_data[index]; })
460 #define SKIP_GOTO pc += 2
461 #define GOTO_VAL() pc - 1 + get2s (pc)
462 #define PCVAL(unionval) unionval.i
463 #define AMPAMP(label) NULL
465 pc = meth->bytecode ();
467 #endif /* DIRECT_THREADED */
469 #define TAKE_GOTO pc = GOTO_VAL ()
471 /* Go straight at it! the ffi raw format matches the internal
472 stack representation exactly. At least, that's the idea.
474 memcpy ((void*) locals, (void*) args, meth->args_raw_size);
476 _Jv_word *pool_data = meth->defining_class->constants.data;
478 /* These three are temporaries for common code used by several
479 instructions. */
480 void (*fun)();
481 _Jv_ResolvedMethod* rmeth;
482 int tmpval;
486 // We keep nop around. It is used if we're interpreting the
487 // bytecodes and not doing direct threading.
488 insn_nop:
489 NEXT_INSN;
491 /* The first few instructions here are ordered according to their
492 frequency, in the hope that this will improve code locality a
493 little. */
495 insn_aload_0: // 0x2a
496 LOADA (0);
497 NEXT_INSN;
499 insn_iload: // 0x15
500 LOADI (GET1U ());
501 NEXT_INSN;
503 insn_iload_1: // 0x1b
504 LOADI (1);
505 NEXT_INSN;
507 insn_invokevirtual: // 0xb6
509 SAVE_PC();
510 int index = GET2U ();
512 /* _Jv_Linker::resolve_pool_entry returns immediately if the
513 * value already is resolved. If we want to clutter up the
514 * code here to gain a little performance, then we can check
515 * the corresponding bit JV_CONSTANT_ResolvedFlag in the tag
516 * directly. For now, I don't think it is worth it. */
518 rmeth = (_Jv_Linker::resolve_pool_entry (meth->defining_class,
519 index)).rmethod;
521 sp -= rmeth->stack_item_count;
523 if (rmeth->method->accflags & Modifier::FINAL)
525 // We can't rely on NULLCHECK working if the method is final.
526 if (! sp[0].o)
527 throw_null_pointer_exception ();
529 // Final methods might not appear in the vtable.
530 fun = (void (*)()) rmeth->method->ncode;
532 else
534 NULLCHECK (sp[0].o);
535 jobject rcv = sp[0].o;
536 _Jv_VTable *table = *(_Jv_VTable**) rcv;
537 fun = (void (*)()) table->get_method (rmeth->method->index);
540 #ifdef DIRECT_THREADED
541 // Rewrite instruction so that we use a faster pre-resolved
542 // method.
543 REWRITE_INSN (&&invokevirtual_resolved, datum, rmeth);
544 #endif /* DIRECT_THREADED */
546 goto perform_invoke;
548 #ifdef DIRECT_THREADED
549 invokevirtual_resolved:
551 SAVE_PC();
552 rmeth = (_Jv_ResolvedMethod *) AVAL ();
553 sp -= rmeth->stack_item_count;
555 if (rmeth->method->accflags & Modifier::FINAL)
557 // We can't rely on NULLCHECK working if the method is final.
558 if (! sp[0].o)
559 throw_null_pointer_exception ();
561 // Final methods might not appear in the vtable.
562 fun = (void (*)()) rmeth->method->ncode;
564 else
566 NULLCHECK (sp[0].o);
567 jobject rcv = sp[0].o;
568 _Jv_VTable *table = *(_Jv_VTable**) rcv;
569 fun = (void (*)()) table->get_method (rmeth->method->index);
572 goto perform_invoke;
573 #endif /* DIRECT_THREADED */
575 perform_invoke:
577 /* here goes the magic again... */
578 ffi_cif *cif = &rmeth->cif;
579 INTERP_FFI_RAW_TYPE *raw = (INTERP_FFI_RAW_TYPE *) sp;
581 _Jv_value rvalue;
583 #if FFI_NATIVE_RAW_API
584 /* We assume that this is only implemented if it's correct */
585 /* to use it here. On a 64 bit machine, it never is. */
586 ffi_raw_call (cif, fun, (void*)&rvalue, raw);
587 #else
588 ffi_java_raw_call (cif, fun, (void*)&rvalue, raw);
589 #endif
591 int rtype = cif->rtype->type;
593 /* the likelyhood of object, int, or void return is very high,
594 * so those are checked before the switch */
595 if (rtype == FFI_TYPE_POINTER)
597 PUSHA (rvalue.object_value);
599 else if (rtype == FFI_TYPE_SINT32)
601 PUSHI (rvalue.int_value);
603 else if (rtype == FFI_TYPE_VOID)
605 /* skip */
607 else
609 switch (rtype)
611 case FFI_TYPE_SINT8:
612 PUSHI ((jbyte)(rvalue.int_value & 0xff));
613 break;
615 case FFI_TYPE_SINT16:
616 PUSHI ((jshort)(rvalue.int_value & 0xffff));
617 break;
619 case FFI_TYPE_UINT16:
620 PUSHI (rvalue.int_value & 0xffff);
621 break;
623 case FFI_TYPE_FLOAT:
624 PUSHF (rvalue.float_value);
625 break;
627 case FFI_TYPE_DOUBLE:
628 PUSHD (rvalue.double_value);
629 break;
631 case FFI_TYPE_SINT64:
632 PUSHL (rvalue.long_value);
633 break;
635 default:
636 throw_internal_error ("unknown return type in invokeXXX");
640 NEXT_INSN;
642 insn_aconst_null:
643 PUSHA (NULL);
644 NEXT_INSN;
646 insn_iconst_m1:
647 PUSHI (-1);
648 NEXT_INSN;
650 insn_iconst_0:
651 PUSHI (0);
652 NEXT_INSN;
654 insn_iconst_1:
655 PUSHI (1);
656 NEXT_INSN;
658 insn_iconst_2:
659 PUSHI (2);
660 NEXT_INSN;
662 insn_iconst_3:
663 PUSHI (3);
664 NEXT_INSN;
666 insn_iconst_4:
667 PUSHI (4);
668 NEXT_INSN;
670 insn_iconst_5:
671 PUSHI (5);
672 NEXT_INSN;
674 insn_lconst_0:
675 PUSHL (0);
676 NEXT_INSN;
678 insn_lconst_1:
679 PUSHL (1);
680 NEXT_INSN;
682 insn_fconst_0:
683 PUSHF (0);
684 NEXT_INSN;
686 insn_fconst_1:
687 PUSHF (1);
688 NEXT_INSN;
690 insn_fconst_2:
691 PUSHF (2);
692 NEXT_INSN;
694 insn_dconst_0:
695 PUSHD (0);
696 NEXT_INSN;
698 insn_dconst_1:
699 PUSHD (1);
700 NEXT_INSN;
702 insn_bipush:
703 // For direct threaded, bipush and sipush are the same.
704 #ifndef DIRECT_THREADED
705 PUSHI (GET1S ());
706 NEXT_INSN;
707 #endif /* DIRECT_THREADED */
708 insn_sipush:
709 PUSHI (GET2S ());
710 NEXT_INSN;
712 insn_ldc:
713 // For direct threaded, ldc and ldc_w are the same.
714 #ifndef DIRECT_THREADED
715 PUSHA ((jobject) AVAL1U ());
716 NEXT_INSN;
717 #endif /* DIRECT_THREADED */
718 insn_ldc_w:
719 PUSHA ((jobject) AVAL2U ());
720 NEXT_INSN;
722 #ifdef DIRECT_THREADED
723 // For direct threaded we have a separate 'ldc class' operation.
724 insn_ldc_class:
726 SAVE_PC();
727 // We could rewrite the instruction at this point.
728 int index = INTVAL ();
729 jobject k = (_Jv_Linker::resolve_pool_entry (meth->defining_class,
730 index)).o;
731 PUSHA (k);
733 NEXT_INSN;
734 #endif /* DIRECT_THREADED */
736 insn_ldc2_w:
738 void *where = AVAL2UP ();
739 memcpy (sp, where, 2*sizeof (_Jv_word));
740 sp += 2;
742 NEXT_INSN;
744 insn_lload:
745 LOADL (GET1U ());
746 NEXT_INSN;
748 insn_fload:
749 LOADF (GET1U ());
750 NEXT_INSN;
752 insn_dload:
753 LOADD (GET1U ());
754 NEXT_INSN;
756 insn_aload:
757 LOADA (GET1U ());
758 NEXT_INSN;
760 insn_iload_0:
761 LOADI (0);
762 NEXT_INSN;
764 insn_iload_2:
765 LOADI (2);
766 NEXT_INSN;
768 insn_iload_3:
769 LOADI (3);
770 NEXT_INSN;
772 insn_lload_0:
773 LOADL (0);
774 NEXT_INSN;
776 insn_lload_1:
777 LOADL (1);
778 NEXT_INSN;
780 insn_lload_2:
781 LOADL (2);
782 NEXT_INSN;
784 insn_lload_3:
785 LOADL (3);
786 NEXT_INSN;
788 insn_fload_0:
789 LOADF (0);
790 NEXT_INSN;
792 insn_fload_1:
793 LOADF (1);
794 NEXT_INSN;
796 insn_fload_2:
797 LOADF (2);
798 NEXT_INSN;
800 insn_fload_3:
801 LOADF (3);
802 NEXT_INSN;
804 insn_dload_0:
805 LOADD (0);
806 NEXT_INSN;
808 insn_dload_1:
809 LOADD (1);
810 NEXT_INSN;
812 insn_dload_2:
813 LOADD (2);
814 NEXT_INSN;
816 insn_dload_3:
817 LOADD (3);
818 NEXT_INSN;
820 insn_aload_1:
821 LOADA(1);
822 NEXT_INSN;
824 insn_aload_2:
825 LOADA(2);
826 NEXT_INSN;
828 insn_aload_3:
829 LOADA(3);
830 NEXT_INSN;
832 insn_iaload:
834 jint index = POPI();
835 jintArray arr = (jintArray) POPA();
836 NULLARRAYCHECK (arr);
837 ARRAYBOUNDSCHECK (arr, index);
838 PUSHI( elements(arr)[index] );
840 NEXT_INSN;
842 insn_laload:
844 jint index = POPI();
845 jlongArray arr = (jlongArray) POPA();
846 NULLARRAYCHECK (arr);
847 ARRAYBOUNDSCHECK (arr, index);
848 PUSHL( elements(arr)[index] );
850 NEXT_INSN;
852 insn_faload:
854 jint index = POPI();
855 jfloatArray arr = (jfloatArray) POPA();
856 NULLARRAYCHECK (arr);
857 ARRAYBOUNDSCHECK (arr, index);
858 PUSHF( elements(arr)[index] );
860 NEXT_INSN;
862 insn_daload:
864 jint index = POPI();
865 jdoubleArray arr = (jdoubleArray) POPA();
866 NULLARRAYCHECK (arr);
867 ARRAYBOUNDSCHECK (arr, index);
868 PUSHD( elements(arr)[index] );
870 NEXT_INSN;
872 insn_aaload:
874 jint index = POPI();
875 jobjectArray arr = (jobjectArray) POPA();
876 NULLARRAYCHECK (arr);
877 ARRAYBOUNDSCHECK (arr, index);
878 PUSHA( elements(arr)[index] );
880 NEXT_INSN;
882 insn_baload:
884 jint index = POPI();
885 jbyteArray arr = (jbyteArray) POPA();
886 NULLARRAYCHECK (arr);
887 ARRAYBOUNDSCHECK (arr, index);
888 PUSHI( elements(arr)[index] );
890 NEXT_INSN;
892 insn_caload:
894 jint index = POPI();
895 jcharArray arr = (jcharArray) POPA();
896 NULLARRAYCHECK (arr);
897 ARRAYBOUNDSCHECK (arr, index);
898 PUSHI( elements(arr)[index] );
900 NEXT_INSN;
902 insn_saload:
904 jint index = POPI();
905 jshortArray arr = (jshortArray) POPA();
906 NULLARRAYCHECK (arr);
907 ARRAYBOUNDSCHECK (arr, index);
908 PUSHI( elements(arr)[index] );
910 NEXT_INSN;
912 insn_istore:
913 STOREI (GET1U ());
914 NEXT_INSN;
916 insn_lstore:
917 STOREL (GET1U ());
918 NEXT_INSN;
920 insn_fstore:
921 STOREF (GET1U ());
922 NEXT_INSN;
924 insn_dstore:
925 STORED (GET1U ());
926 NEXT_INSN;
928 insn_astore:
929 STOREA (GET1U ());
930 NEXT_INSN;
932 insn_istore_0:
933 STOREI (0);
934 NEXT_INSN;
936 insn_istore_1:
937 STOREI (1);
938 NEXT_INSN;
940 insn_istore_2:
941 STOREI (2);
942 NEXT_INSN;
944 insn_istore_3:
945 STOREI (3);
946 NEXT_INSN;
948 insn_lstore_0:
949 STOREL (0);
950 NEXT_INSN;
952 insn_lstore_1:
953 STOREL (1);
954 NEXT_INSN;
956 insn_lstore_2:
957 STOREL (2);
958 NEXT_INSN;
960 insn_lstore_3:
961 STOREL (3);
962 NEXT_INSN;
964 insn_fstore_0:
965 STOREF (0);
966 NEXT_INSN;
968 insn_fstore_1:
969 STOREF (1);
970 NEXT_INSN;
972 insn_fstore_2:
973 STOREF (2);
974 NEXT_INSN;
976 insn_fstore_3:
977 STOREF (3);
978 NEXT_INSN;
980 insn_dstore_0:
981 STORED (0);
982 NEXT_INSN;
984 insn_dstore_1:
985 STORED (1);
986 NEXT_INSN;
988 insn_dstore_2:
989 STORED (2);
990 NEXT_INSN;
992 insn_dstore_3:
993 STORED (3);
994 NEXT_INSN;
996 insn_astore_0:
997 STOREA(0);
998 NEXT_INSN;
1000 insn_astore_1:
1001 STOREA(1);
1002 NEXT_INSN;
1004 insn_astore_2:
1005 STOREA(2);
1006 NEXT_INSN;
1008 insn_astore_3:
1009 STOREA(3);
1010 NEXT_INSN;
1012 insn_iastore:
1014 jint value = POPI();
1015 jint index = POPI();
1016 jintArray arr = (jintArray) POPA();
1017 NULLARRAYCHECK (arr);
1018 ARRAYBOUNDSCHECK (arr, index);
1019 elements(arr)[index] = value;
1021 NEXT_INSN;
1023 insn_lastore:
1025 jlong value = POPL();
1026 jint index = POPI();
1027 jlongArray arr = (jlongArray) POPA();
1028 NULLARRAYCHECK (arr);
1029 ARRAYBOUNDSCHECK (arr, index);
1030 elements(arr)[index] = value;
1032 NEXT_INSN;
1034 insn_fastore:
1036 jfloat value = POPF();
1037 jint index = POPI();
1038 jfloatArray arr = (jfloatArray) POPA();
1039 NULLARRAYCHECK (arr);
1040 ARRAYBOUNDSCHECK (arr, index);
1041 elements(arr)[index] = value;
1043 NEXT_INSN;
1045 insn_dastore:
1047 jdouble value = POPD();
1048 jint index = POPI();
1049 jdoubleArray arr = (jdoubleArray) POPA();
1050 NULLARRAYCHECK (arr);
1051 ARRAYBOUNDSCHECK (arr, index);
1052 elements(arr)[index] = value;
1054 NEXT_INSN;
1056 insn_aastore:
1058 jobject value = POPA();
1059 jint index = POPI();
1060 jobjectArray arr = (jobjectArray) POPA();
1061 NULLARRAYCHECK (arr);
1062 ARRAYBOUNDSCHECK (arr, index);
1063 _Jv_CheckArrayStore (arr, value);
1064 elements(arr)[index] = value;
1066 NEXT_INSN;
1068 insn_bastore:
1070 jbyte value = (jbyte) POPI();
1071 jint index = POPI();
1072 jbyteArray arr = (jbyteArray) POPA();
1073 NULLARRAYCHECK (arr);
1074 ARRAYBOUNDSCHECK (arr, index);
1075 elements(arr)[index] = value;
1077 NEXT_INSN;
1079 insn_castore:
1081 jchar value = (jchar) POPI();
1082 jint index = POPI();
1083 jcharArray arr = (jcharArray) POPA();
1084 NULLARRAYCHECK (arr);
1085 ARRAYBOUNDSCHECK (arr, index);
1086 elements(arr)[index] = value;
1088 NEXT_INSN;
1090 insn_sastore:
1092 jshort value = (jshort) POPI();
1093 jint index = POPI();
1094 jshortArray arr = (jshortArray) POPA();
1095 NULLARRAYCHECK (arr);
1096 ARRAYBOUNDSCHECK (arr, index);
1097 elements(arr)[index] = value;
1099 NEXT_INSN;
1101 insn_pop:
1102 sp -= 1;
1103 NEXT_INSN;
1105 insn_pop2:
1106 sp -= 2;
1107 NEXT_INSN;
1109 insn_dup:
1110 sp[0] = sp[-1];
1111 sp += 1;
1112 NEXT_INSN;
1114 insn_dup_x1:
1115 dupx (sp, 1, 1); sp+=1;
1116 NEXT_INSN;
1118 insn_dup_x2:
1119 dupx (sp, 1, 2); sp+=1;
1120 NEXT_INSN;
1122 insn_dup2:
1123 sp[0] = sp[-2];
1124 sp[1] = sp[-1];
1125 sp += 2;
1126 NEXT_INSN;
1128 insn_dup2_x1:
1129 dupx (sp, 2, 1); sp+=2;
1130 NEXT_INSN;
1132 insn_dup2_x2:
1133 dupx (sp, 2, 2); sp+=2;
1134 NEXT_INSN;
1136 insn_swap:
1138 jobject tmp1 = POPA();
1139 jobject tmp2 = POPA();
1140 PUSHA (tmp1);
1141 PUSHA (tmp2);
1143 NEXT_INSN;
1145 insn_iadd:
1146 BINOPI(+);
1147 NEXT_INSN;
1149 insn_ladd:
1150 BINOPL(+);
1151 NEXT_INSN;
1153 insn_fadd:
1154 BINOPF(+);
1155 NEXT_INSN;
1157 insn_dadd:
1158 BINOPD(+);
1159 NEXT_INSN;
1161 insn_isub:
1162 BINOPI(-);
1163 NEXT_INSN;
1165 insn_lsub:
1166 BINOPL(-);
1167 NEXT_INSN;
1169 insn_fsub:
1170 BINOPF(-);
1171 NEXT_INSN;
1173 insn_dsub:
1174 BINOPD(-);
1175 NEXT_INSN;
1177 insn_imul:
1178 BINOPI(*);
1179 NEXT_INSN;
1181 insn_lmul:
1182 BINOPL(*);
1183 NEXT_INSN;
1185 insn_fmul:
1186 BINOPF(*);
1187 NEXT_INSN;
1189 insn_dmul:
1190 BINOPD(*);
1191 NEXT_INSN;
1193 insn_idiv:
1195 SAVE_PC();
1196 jint value2 = POPI();
1197 jint value1 = POPI();
1198 jint res = _Jv_divI (value1, value2);
1199 PUSHI (res);
1201 NEXT_INSN;
1203 insn_ldiv:
1205 SAVE_PC();
1206 jlong value2 = POPL();
1207 jlong value1 = POPL();
1208 jlong res = _Jv_divJ (value1, value2);
1209 PUSHL (res);
1211 NEXT_INSN;
1213 insn_fdiv:
1215 jfloat value2 = POPF();
1216 jfloat value1 = POPF();
1217 jfloat res = value1 / value2;
1218 PUSHF (res);
1220 NEXT_INSN;
1222 insn_ddiv:
1224 jdouble value2 = POPD();
1225 jdouble value1 = POPD();
1226 jdouble res = value1 / value2;
1227 PUSHD (res);
1229 NEXT_INSN;
1231 insn_irem:
1233 SAVE_PC();
1234 jint value2 = POPI();
1235 jint value1 = POPI();
1236 jint res = _Jv_remI (value1, value2);
1237 PUSHI (res);
1239 NEXT_INSN;
1241 insn_lrem:
1243 SAVE_PC();
1244 jlong value2 = POPL();
1245 jlong value1 = POPL();
1246 jlong res = _Jv_remJ (value1, value2);
1247 PUSHL (res);
1249 NEXT_INSN;
1251 insn_frem:
1253 jfloat value2 = POPF();
1254 jfloat value1 = POPF();
1255 jfloat res = __ieee754_fmod (value1, value2);
1256 PUSHF (res);
1258 NEXT_INSN;
1260 insn_drem:
1262 jdouble value2 = POPD();
1263 jdouble value1 = POPD();
1264 jdouble res = __ieee754_fmod (value1, value2);
1265 PUSHD (res);
1267 NEXT_INSN;
1269 insn_ineg:
1271 jint value = POPI();
1272 PUSHI (value * -1);
1274 NEXT_INSN;
1276 insn_lneg:
1278 jlong value = POPL();
1279 PUSHL (value * -1);
1281 NEXT_INSN;
1283 insn_fneg:
1285 jfloat value = POPF();
1286 PUSHF (value * -1);
1288 NEXT_INSN;
1290 insn_dneg:
1292 jdouble value = POPD();
1293 PUSHD (value * -1);
1295 NEXT_INSN;
1297 insn_ishl:
1299 jint shift = (POPI() & 0x1f);
1300 jint value = POPI();
1301 PUSHI (value << shift);
1303 NEXT_INSN;
1305 insn_lshl:
1307 jint shift = (POPI() & 0x3f);
1308 jlong value = POPL();
1309 PUSHL (value << shift);
1311 NEXT_INSN;
1313 insn_ishr:
1315 jint shift = (POPI() & 0x1f);
1316 jint value = POPI();
1317 PUSHI (value >> shift);
1319 NEXT_INSN;
1321 insn_lshr:
1323 jint shift = (POPI() & 0x3f);
1324 jlong value = POPL();
1325 PUSHL (value >> shift);
1327 NEXT_INSN;
1329 insn_iushr:
1331 jint shift = (POPI() & 0x1f);
1332 _Jv_uint value = (_Jv_uint) POPI();
1333 PUSHI ((jint) (value >> shift));
1335 NEXT_INSN;
1337 insn_lushr:
1339 jint shift = (POPI() & 0x3f);
1340 _Jv_ulong value = (_Jv_ulong) POPL();
1341 PUSHL ((jlong) (value >> shift));
1343 NEXT_INSN;
1345 insn_iand:
1346 BINOPI (&);
1347 NEXT_INSN;
1349 insn_land:
1350 BINOPL (&);
1351 NEXT_INSN;
1353 insn_ior:
1354 BINOPI (|);
1355 NEXT_INSN;
1357 insn_lor:
1358 BINOPL (|);
1359 NEXT_INSN;
1361 insn_ixor:
1362 BINOPI (^);
1363 NEXT_INSN;
1365 insn_lxor:
1366 BINOPL (^);
1367 NEXT_INSN;
1369 insn_iinc:
1371 jint index = GET1U ();
1372 jint amount = GET1S ();
1373 locals[index].i += amount;
1375 NEXT_INSN;
1377 insn_i2l:
1378 {jlong value = POPI(); PUSHL (value);}
1379 NEXT_INSN;
1381 insn_i2f:
1382 {jfloat value = POPI(); PUSHF (value);}
1383 NEXT_INSN;
1385 insn_i2d:
1386 {jdouble value = POPI(); PUSHD (value);}
1387 NEXT_INSN;
1389 insn_l2i:
1390 {jint value = POPL(); PUSHI (value);}
1391 NEXT_INSN;
1393 insn_l2f:
1394 {jfloat value = POPL(); PUSHF (value);}
1395 NEXT_INSN;
1397 insn_l2d:
1398 {jdouble value = POPL(); PUSHD (value);}
1399 NEXT_INSN;
1401 insn_f2i:
1403 using namespace java::lang;
1404 jint value = convert (POPF (), Integer::MIN_VALUE, Integer::MAX_VALUE);
1405 PUSHI(value);
1407 NEXT_INSN;
1409 insn_f2l:
1411 using namespace java::lang;
1412 jlong value = convert (POPF (), Long::MIN_VALUE, Long::MAX_VALUE);
1413 PUSHL(value);
1415 NEXT_INSN;
1417 insn_f2d:
1418 { jdouble value = POPF (); PUSHD(value); }
1419 NEXT_INSN;
1421 insn_d2i:
1423 using namespace java::lang;
1424 jint value = convert (POPD (), Integer::MIN_VALUE, Integer::MAX_VALUE);
1425 PUSHI(value);
1427 NEXT_INSN;
1429 insn_d2l:
1431 using namespace java::lang;
1432 jlong value = convert (POPD (), Long::MIN_VALUE, Long::MAX_VALUE);
1433 PUSHL(value);
1435 NEXT_INSN;
1437 insn_d2f:
1438 { jfloat value = POPD (); PUSHF(value); }
1439 NEXT_INSN;
1441 insn_i2b:
1442 { jbyte value = POPI (); PUSHI(value); }
1443 NEXT_INSN;
1445 insn_i2c:
1446 { jchar value = POPI (); PUSHI(value); }
1447 NEXT_INSN;
1449 insn_i2s:
1450 { jshort value = POPI (); PUSHI(value); }
1451 NEXT_INSN;
1453 insn_lcmp:
1455 jlong value2 = POPL ();
1456 jlong value1 = POPL ();
1457 if (value1 > value2)
1458 { PUSHI (1); }
1459 else if (value1 == value2)
1460 { PUSHI (0); }
1461 else
1462 { PUSHI (-1); }
1464 NEXT_INSN;
1466 insn_fcmpl:
1467 tmpval = -1;
1468 goto fcmp;
1470 insn_fcmpg:
1471 tmpval = 1;
1473 fcmp:
1475 jfloat value2 = POPF ();
1476 jfloat value1 = POPF ();
1477 if (value1 > value2)
1478 PUSHI (1);
1479 else if (value1 == value2)
1480 PUSHI (0);
1481 else if (value1 < value2)
1482 PUSHI (-1);
1483 else
1484 PUSHI (tmpval);
1486 NEXT_INSN;
1488 insn_dcmpl:
1489 tmpval = -1;
1490 goto dcmp;
1492 insn_dcmpg:
1493 tmpval = 1;
1495 dcmp:
1497 jdouble value2 = POPD ();
1498 jdouble value1 = POPD ();
1499 if (value1 > value2)
1500 PUSHI (1);
1501 else if (value1 == value2)
1502 PUSHI (0);
1503 else if (value1 < value2)
1504 PUSHI (-1);
1505 else
1506 PUSHI (tmpval);
1508 NEXT_INSN;
1510 insn_ifeq:
1512 if (POPI() == 0)
1513 TAKE_GOTO;
1514 else
1515 SKIP_GOTO;
1517 NEXT_INSN;
1519 insn_ifne:
1521 if (POPI() != 0)
1522 TAKE_GOTO;
1523 else
1524 SKIP_GOTO;
1526 NEXT_INSN;
1528 insn_iflt:
1530 if (POPI() < 0)
1531 TAKE_GOTO;
1532 else
1533 SKIP_GOTO;
1535 NEXT_INSN;
1537 insn_ifge:
1539 if (POPI() >= 0)
1540 TAKE_GOTO;
1541 else
1542 SKIP_GOTO;
1544 NEXT_INSN;
1546 insn_ifgt:
1548 if (POPI() > 0)
1549 TAKE_GOTO;
1550 else
1551 SKIP_GOTO;
1553 NEXT_INSN;
1555 insn_ifle:
1557 if (POPI() <= 0)
1558 TAKE_GOTO;
1559 else
1560 SKIP_GOTO;
1562 NEXT_INSN;
1564 insn_if_icmpeq:
1566 jint value2 = POPI();
1567 jint value1 = POPI();
1568 if (value1 == value2)
1569 TAKE_GOTO;
1570 else
1571 SKIP_GOTO;
1573 NEXT_INSN;
1575 insn_if_icmpne:
1577 jint value2 = POPI();
1578 jint value1 = POPI();
1579 if (value1 != value2)
1580 TAKE_GOTO;
1581 else
1582 SKIP_GOTO;
1584 NEXT_INSN;
1586 insn_if_icmplt:
1588 jint value2 = POPI();
1589 jint value1 = POPI();
1590 if (value1 < value2)
1591 TAKE_GOTO;
1592 else
1593 SKIP_GOTO;
1595 NEXT_INSN;
1597 insn_if_icmpge:
1599 jint value2 = POPI();
1600 jint value1 = POPI();
1601 if (value1 >= value2)
1602 TAKE_GOTO;
1603 else
1604 SKIP_GOTO;
1606 NEXT_INSN;
1608 insn_if_icmpgt:
1610 jint value2 = POPI();
1611 jint value1 = POPI();
1612 if (value1 > value2)
1613 TAKE_GOTO;
1614 else
1615 SKIP_GOTO;
1617 NEXT_INSN;
1619 insn_if_icmple:
1621 jint value2 = POPI();
1622 jint value1 = POPI();
1623 if (value1 <= value2)
1624 TAKE_GOTO;
1625 else
1626 SKIP_GOTO;
1628 NEXT_INSN;
1630 insn_if_acmpeq:
1632 jobject value2 = POPA();
1633 jobject value1 = POPA();
1634 if (value1 == value2)
1635 TAKE_GOTO;
1636 else
1637 SKIP_GOTO;
1639 NEXT_INSN;
1641 insn_if_acmpne:
1643 jobject value2 = POPA();
1644 jobject value1 = POPA();
1645 if (value1 != value2)
1646 TAKE_GOTO;
1647 else
1648 SKIP_GOTO;
1650 NEXT_INSN;
1652 insn_goto_w:
1653 #ifndef DIRECT_THREADED
1654 // For direct threaded, goto and goto_w are the same.
1655 pc = pc - 1 + get4 (pc);
1656 NEXT_INSN;
1657 #endif /* DIRECT_THREADED */
1658 insn_goto:
1659 TAKE_GOTO;
1660 NEXT_INSN;
1662 insn_jsr_w:
1663 #ifndef DIRECT_THREADED
1664 // For direct threaded, jsr and jsr_w are the same.
1666 pc_t next = pc - 1 + get4 (pc);
1667 pc += 4;
1668 PUSHA ((jobject) pc);
1669 pc = next;
1671 NEXT_INSN;
1672 #endif /* DIRECT_THREADED */
1673 insn_jsr:
1675 pc_t next = GOTO_VAL();
1676 SKIP_GOTO;
1677 PUSHA ((jobject) pc);
1678 pc = next;
1680 NEXT_INSN;
1682 insn_ret:
1684 jint index = GET1U ();
1685 pc = (pc_t) PEEKA (index);
1687 NEXT_INSN;
1689 insn_tableswitch:
1691 #ifdef DIRECT_THREADED
1692 void *def = (pc++)->datum;
1694 int index = POPI();
1696 jint low = INTVAL ();
1697 jint high = INTVAL ();
1699 if (index < low || index > high)
1700 pc = (insn_slot *) def;
1701 else
1702 pc = (insn_slot *) ((pc + index - low)->datum);
1703 #else
1704 pc_t base_pc = pc - 1;
1705 int index = POPI ();
1707 pc_t base = (pc_t) meth->bytecode ();
1708 while ((pc - base) % 4 != 0)
1709 ++pc;
1711 jint def = get4 (pc);
1712 jint low = get4 (pc + 4);
1713 jint high = get4 (pc + 8);
1714 if (index < low || index > high)
1715 pc = base_pc + def;
1716 else
1717 pc = base_pc + get4 (pc + 4 * (index - low + 3));
1718 #endif /* DIRECT_THREADED */
1720 NEXT_INSN;
1722 insn_lookupswitch:
1724 #ifdef DIRECT_THREADED
1725 void *def = (pc++)->insn;
1727 int index = POPI();
1729 jint npairs = INTVAL ();
1731 int max = npairs - 1;
1732 int min = 0;
1734 // Simple binary search...
1735 while (min < max)
1737 int half = (min + max) / 2;
1738 int match = pc[2 * half].int_val;
1740 if (index == match)
1742 // Found it.
1743 pc = (insn_slot *) pc[2 * half + 1].datum;
1744 NEXT_INSN;
1746 else if (index < match)
1747 // We can use HALF - 1 here because we check again on
1748 // loop exit.
1749 max = half - 1;
1750 else
1751 // We can use HALF + 1 here because we check again on
1752 // loop exit.
1753 min = half + 1;
1755 if (index == pc[2 * min].int_val)
1756 pc = (insn_slot *) pc[2 * min + 1].datum;
1757 else
1758 pc = (insn_slot *) def;
1759 #else
1760 unsigned char *base_pc = pc-1;
1761 int index = POPI();
1763 unsigned char* base = meth->bytecode ();
1764 while ((pc-base) % 4 != 0)
1765 ++pc;
1767 jint def = get4 (pc);
1768 jint npairs = get4 (pc+4);
1770 int max = npairs-1;
1771 int min = 0;
1773 // Simple binary search...
1774 while (min < max)
1776 int half = (min+max)/2;
1777 int match = get4 (pc+ 4*(2 + 2*half));
1779 if (index == match)
1780 min = max = half;
1781 else if (index < match)
1782 // We can use HALF - 1 here because we check again on
1783 // loop exit.
1784 max = half - 1;
1785 else
1786 // We can use HALF + 1 here because we check again on
1787 // loop exit.
1788 min = half + 1;
1791 if (index == get4 (pc+ 4*(2 + 2*min)))
1792 pc = base_pc + get4 (pc+ 4*(2 + 2*min + 1));
1793 else
1794 pc = base_pc + def;
1795 #endif /* DIRECT_THREADED */
1797 NEXT_INSN;
1799 insn_areturn:
1800 *(jobject *) retp = POPA ();
1801 return;
1803 insn_lreturn:
1804 *(jlong *) retp = POPL ();
1805 return;
1807 insn_freturn:
1808 *(jfloat *) retp = POPF ();
1809 return;
1811 insn_dreturn:
1812 *(jdouble *) retp = POPD ();
1813 return;
1815 insn_ireturn:
1816 *(jint *) retp = POPI ();
1817 return;
1819 insn_return:
1820 return;
1822 insn_getstatic:
1824 jint fieldref_index = GET2U ();
1825 SAVE_PC(); // Constant pool resolution could throw.
1826 _Jv_Linker::resolve_pool_entry (meth->defining_class, fieldref_index);
1827 _Jv_Field *field = pool_data[fieldref_index].field;
1829 if ((field->flags & Modifier::STATIC) == 0)
1830 throw_incompatible_class_change_error
1831 (JvNewStringLatin1 ("field no longer static"));
1833 jclass type = field->type;
1835 // We rewrite the instruction once we discover what it refers
1836 // to.
1837 void *newinsn = NULL;
1838 if (type->isPrimitive ())
1840 switch (type->size_in_bytes)
1842 case 1:
1843 PUSHI (*field->u.byte_addr);
1844 newinsn = AMPAMP (getstatic_resolved_1);
1845 break;
1847 case 2:
1848 if (type == JvPrimClass (char))
1850 PUSHI (*field->u.char_addr);
1851 newinsn = AMPAMP (getstatic_resolved_char);
1853 else
1855 PUSHI (*field->u.short_addr);
1856 newinsn = AMPAMP (getstatic_resolved_short);
1858 break;
1860 case 4:
1861 PUSHI(*field->u.int_addr);
1862 newinsn = AMPAMP (getstatic_resolved_4);
1863 break;
1865 case 8:
1866 PUSHL(*field->u.long_addr);
1867 newinsn = AMPAMP (getstatic_resolved_8);
1868 break;
1871 else
1873 PUSHA(*field->u.object_addr);
1874 newinsn = AMPAMP (getstatic_resolved_obj);
1877 #ifdef DIRECT_THREADED
1878 REWRITE_INSN (newinsn, datum, field->u.addr);
1879 #endif /* DIRECT_THREADED */
1881 NEXT_INSN;
1883 #ifdef DIRECT_THREADED
1884 getstatic_resolved_1:
1885 PUSHI (*(jbyte *) AVAL ());
1886 NEXT_INSN;
1888 getstatic_resolved_char:
1889 PUSHI (*(jchar *) AVAL ());
1890 NEXT_INSN;
1892 getstatic_resolved_short:
1893 PUSHI (*(jshort *) AVAL ());
1894 NEXT_INSN;
1896 getstatic_resolved_4:
1897 PUSHI (*(jint *) AVAL ());
1898 NEXT_INSN;
1900 getstatic_resolved_8:
1901 PUSHL (*(jlong *) AVAL ());
1902 NEXT_INSN;
1904 getstatic_resolved_obj:
1905 PUSHA (*(jobject *) AVAL ());
1906 NEXT_INSN;
1907 #endif /* DIRECT_THREADED */
1909 insn_getfield:
1911 SAVE_PC();
1912 jint fieldref_index = GET2U ();
1913 _Jv_Linker::resolve_pool_entry (meth->defining_class, fieldref_index);
1914 _Jv_Field *field = pool_data[fieldref_index].field;
1916 if ((field->flags & Modifier::STATIC) != 0)
1917 throw_incompatible_class_change_error
1918 (JvNewStringLatin1 ("field is static"));
1920 jclass type = field->type;
1921 jint field_offset = field->u.boffset;
1923 jobject obj = POPA();
1924 NULLCHECK(obj);
1926 void *newinsn = NULL;
1927 _Jv_value *val = (_Jv_value *) ((char *)obj + field_offset);
1928 if (type->isPrimitive ())
1930 switch (type->size_in_bytes)
1932 case 1:
1933 PUSHI (val->byte_value);
1934 newinsn = AMPAMP (getfield_resolved_1);
1935 break;
1937 case 2:
1938 if (type == JvPrimClass (char))
1940 PUSHI (val->char_value);
1941 newinsn = AMPAMP (getfield_resolved_char);
1943 else
1945 PUSHI (val->short_value);
1946 newinsn = AMPAMP (getfield_resolved_short);
1948 break;
1950 case 4:
1951 PUSHI (val->int_value);
1952 newinsn = AMPAMP (getfield_resolved_4);
1953 break;
1955 case 8:
1956 PUSHL (val->long_value);
1957 newinsn = AMPAMP (getfield_resolved_8);
1958 break;
1961 else
1963 PUSHA (val->object_value);
1964 newinsn = AMPAMP (getfield_resolved_obj);
1967 #ifdef DIRECT_THREADED
1968 REWRITE_INSN (newinsn, int_val, field_offset);
1969 #endif /* DIRECT_THREADED */
1971 NEXT_INSN;
1973 #ifdef DIRECT_THREADED
1974 getfield_resolved_1:
1976 char *obj = (char *) POPA ();
1977 NULLCHECK (obj);
1978 PUSHI (*(jbyte *) (obj + INTVAL ()));
1980 NEXT_INSN;
1982 getfield_resolved_char:
1984 char *obj = (char *) POPA ();
1985 NULLCHECK (obj);
1986 PUSHI (*(jchar *) (obj + INTVAL ()));
1988 NEXT_INSN;
1990 getfield_resolved_short:
1992 char *obj = (char *) POPA ();
1993 NULLCHECK (obj);
1994 PUSHI (*(jshort *) (obj + INTVAL ()));
1996 NEXT_INSN;
1998 getfield_resolved_4:
2000 char *obj = (char *) POPA ();
2001 NULLCHECK (obj);
2002 PUSHI (*(jint *) (obj + INTVAL ()));
2004 NEXT_INSN;
2006 getfield_resolved_8:
2008 char *obj = (char *) POPA ();
2009 NULLCHECK (obj);
2010 PUSHL (*(jlong *) (obj + INTVAL ()));
2012 NEXT_INSN;
2014 getfield_resolved_obj:
2016 char *obj = (char *) POPA ();
2017 NULLCHECK (obj);
2018 PUSHA (*(jobject *) (obj + INTVAL ()));
2020 NEXT_INSN;
2021 #endif /* DIRECT_THREADED */
2023 insn_putstatic:
2025 SAVE_PC();
2026 jint fieldref_index = GET2U ();
2027 _Jv_Linker::resolve_pool_entry (meth->defining_class, fieldref_index);
2028 _Jv_Field *field = pool_data[fieldref_index].field;
2030 jclass type = field->type;
2032 // ResolvePoolEntry cannot check this
2033 if ((field->flags & Modifier::STATIC) == 0)
2034 throw_incompatible_class_change_error
2035 (JvNewStringLatin1 ("field no longer static"));
2037 void *newinsn = NULL;
2038 if (type->isPrimitive ())
2040 switch (type->size_in_bytes)
2042 case 1:
2044 jint value = POPI();
2045 *field->u.byte_addr = value;
2046 newinsn = AMPAMP (putstatic_resolved_1);
2047 break;
2050 case 2:
2052 jint value = POPI();
2053 *field->u.char_addr = value;
2054 newinsn = AMPAMP (putstatic_resolved_2);
2055 break;
2058 case 4:
2060 jint value = POPI();
2061 *field->u.int_addr = value;
2062 newinsn = AMPAMP (putstatic_resolved_4);
2063 break;
2066 case 8:
2068 jlong value = POPL();
2069 *field->u.long_addr = value;
2070 newinsn = AMPAMP (putstatic_resolved_8);
2071 break;
2075 else
2077 jobject value = POPA();
2078 *field->u.object_addr = value;
2079 newinsn = AMPAMP (putstatic_resolved_obj);
2082 #ifdef DIRECT_THREADED
2083 REWRITE_INSN (newinsn, datum, field->u.addr);
2084 #endif /* DIRECT_THREADED */
2086 NEXT_INSN;
2088 #ifdef DIRECT_THREADED
2089 putstatic_resolved_1:
2090 *(jbyte *) AVAL () = POPI ();
2091 NEXT_INSN;
2093 putstatic_resolved_2:
2094 *(jchar *) AVAL () = POPI ();
2095 NEXT_INSN;
2097 putstatic_resolved_4:
2098 *(jint *) AVAL () = POPI ();
2099 NEXT_INSN;
2101 putstatic_resolved_8:
2102 *(jlong *) AVAL () = POPL ();
2103 NEXT_INSN;
2105 putstatic_resolved_obj:
2106 *(jobject *) AVAL () = POPA ();
2107 NEXT_INSN;
2108 #endif /* DIRECT_THREADED */
2110 insn_putfield:
2112 SAVE_PC();
2113 jint fieldref_index = GET2U ();
2114 _Jv_Linker::resolve_pool_entry (meth->defining_class, fieldref_index);
2115 _Jv_Field *field = pool_data[fieldref_index].field;
2117 jclass type = field->type;
2119 if ((field->flags & Modifier::STATIC) != 0)
2120 throw_incompatible_class_change_error
2121 (JvNewStringLatin1 ("field is static"));
2123 jint field_offset = field->u.boffset;
2125 void *newinsn = NULL;
2126 if (type->isPrimitive ())
2128 switch (type->size_in_bytes)
2130 case 1:
2132 jint value = POPI();
2133 jobject obj = POPA();
2134 NULLCHECK(obj);
2135 *(jbyte*) ((char*)obj + field_offset) = value;
2136 newinsn = AMPAMP (putfield_resolved_1);
2137 break;
2140 case 2:
2142 jint value = POPI();
2143 jobject obj = POPA();
2144 NULLCHECK(obj);
2145 *(jchar*) ((char*)obj + field_offset) = value;
2146 newinsn = AMPAMP (putfield_resolved_2);
2147 break;
2150 case 4:
2152 jint value = POPI();
2153 jobject obj = POPA();
2154 NULLCHECK(obj);
2155 *(jint*) ((char*)obj + field_offset) = value;
2156 newinsn = AMPAMP (putfield_resolved_4);
2157 break;
2160 case 8:
2162 jlong value = POPL();
2163 jobject obj = POPA();
2164 NULLCHECK(obj);
2165 *(jlong*) ((char*)obj + field_offset) = value;
2166 newinsn = AMPAMP (putfield_resolved_8);
2167 break;
2171 else
2173 jobject value = POPA();
2174 jobject obj = POPA();
2175 NULLCHECK(obj);
2176 *(jobject*) ((char*)obj + field_offset) = value;
2177 newinsn = AMPAMP (putfield_resolved_obj);
2180 #ifdef DIRECT_THREADED
2181 REWRITE_INSN (newinsn, int_val, field_offset);
2182 #endif /* DIRECT_THREADED */
2184 NEXT_INSN;
2186 #ifdef DIRECT_THREADED
2187 putfield_resolved_1:
2189 jint val = POPI ();
2190 char *obj = (char *) POPA ();
2191 NULLCHECK (obj);
2192 *(jbyte *) (obj + INTVAL ()) = val;
2194 NEXT_INSN;
2196 putfield_resolved_2:
2198 jint val = POPI ();
2199 char *obj = (char *) POPA ();
2200 NULLCHECK (obj);
2201 *(jchar *) (obj + INTVAL ()) = val;
2203 NEXT_INSN;
2205 putfield_resolved_4:
2207 jint val = POPI ();
2208 char *obj = (char *) POPA ();
2209 NULLCHECK (obj);
2210 *(jint *) (obj + INTVAL ()) = val;
2212 NEXT_INSN;
2214 putfield_resolved_8:
2216 jlong val = POPL ();
2217 char *obj = (char *) POPA ();
2218 NULLCHECK (obj);
2219 *(jlong *) (obj + INTVAL ()) = val;
2221 NEXT_INSN;
2223 putfield_resolved_obj:
2225 jobject val = POPA ();
2226 char *obj = (char *) POPA ();
2227 NULLCHECK (obj);
2228 *(jobject *) (obj + INTVAL ()) = val;
2230 NEXT_INSN;
2231 #endif /* DIRECT_THREADED */
2233 insn_invokespecial:
2235 SAVE_PC();
2236 int index = GET2U ();
2238 rmeth = (_Jv_Linker::resolve_pool_entry (meth->defining_class,
2239 index)).rmethod;
2241 sp -= rmeth->stack_item_count;
2243 // We don't use NULLCHECK here because we can't rely on that
2244 // working for <init>. So instead we do an explicit test.
2245 if (! sp[0].o)
2247 SAVE_PC();
2248 throw_null_pointer_exception ();
2251 fun = (void (*)()) rmeth->method->ncode;
2253 #ifdef DIRECT_THREADED
2254 // Rewrite instruction so that we use a faster pre-resolved
2255 // method.
2256 REWRITE_INSN (&&invokespecial_resolved, datum, rmeth);
2257 #endif /* DIRECT_THREADED */
2259 goto perform_invoke;
2261 #ifdef DIRECT_THREADED
2262 invokespecial_resolved:
2264 SAVE_PC();
2265 rmeth = (_Jv_ResolvedMethod *) AVAL ();
2266 sp -= rmeth->stack_item_count;
2267 // We don't use NULLCHECK here because we can't rely on that
2268 // working for <init>. So instead we do an explicit test.
2269 if (! sp[0].o)
2271 throw_null_pointer_exception ();
2273 fun = (void (*)()) rmeth->method->ncode;
2275 goto perform_invoke;
2276 #endif /* DIRECT_THREADED */
2278 insn_invokestatic:
2280 SAVE_PC();
2281 int index = GET2U ();
2283 rmeth = (_Jv_Linker::resolve_pool_entry (meth->defining_class,
2284 index)).rmethod;
2286 sp -= rmeth->stack_item_count;
2288 fun = (void (*)()) rmeth->method->ncode;
2290 #ifdef DIRECT_THREADED
2291 // Rewrite instruction so that we use a faster pre-resolved
2292 // method.
2293 REWRITE_INSN (&&invokestatic_resolved, datum, rmeth);
2294 #endif /* DIRECT_THREADED */
2296 goto perform_invoke;
2298 #ifdef DIRECT_THREADED
2299 invokestatic_resolved:
2301 SAVE_PC();
2302 rmeth = (_Jv_ResolvedMethod *) AVAL ();
2303 sp -= rmeth->stack_item_count;
2304 fun = (void (*)()) rmeth->method->ncode;
2306 goto perform_invoke;
2307 #endif /* DIRECT_THREADED */
2309 insn_invokeinterface:
2311 SAVE_PC();
2312 int index = GET2U ();
2314 rmeth = (_Jv_Linker::resolve_pool_entry (meth->defining_class,
2315 index)).rmethod;
2317 sp -= rmeth->stack_item_count;
2319 jobject rcv = sp[0].o;
2321 NULLCHECK (rcv);
2323 fun = (void (*)())
2324 _Jv_LookupInterfaceMethod (rcv->getClass (),
2325 rmeth->method->name,
2326 rmeth->method->signature);
2328 #ifdef DIRECT_THREADED
2329 // Rewrite instruction so that we use a faster pre-resolved
2330 // method.
2331 REWRITE_INSN (&&invokeinterface_resolved, datum, rmeth);
2332 #else
2333 // Skip dummy bytes.
2334 pc += 2;
2335 #endif /* DIRECT_THREADED */
2337 goto perform_invoke;
2339 #ifdef DIRECT_THREADED
2340 invokeinterface_resolved:
2342 SAVE_PC();
2343 rmeth = (_Jv_ResolvedMethod *) AVAL ();
2344 sp -= rmeth->stack_item_count;
2345 jobject rcv = sp[0].o;
2346 NULLCHECK (rcv);
2347 fun = (void (*)())
2348 _Jv_LookupInterfaceMethod (rcv->getClass (),
2349 rmeth->method->name,
2350 rmeth->method->signature);
2352 goto perform_invoke;
2353 #endif /* DIRECT_THREADED */
2355 insn_new:
2357 SAVE_PC();
2358 int index = GET2U ();
2359 jclass klass = (_Jv_Linker::resolve_pool_entry (meth->defining_class,
2360 index)).clazz;
2361 /* VM spec, section 3.11.5 */
2362 if ((klass->getModifiers() & Modifier::ABSTRACT)
2363 || klass->isInterface())
2365 jthrowable t = new java::lang::InstantiationException;
2366 INTERP_REPORT_EXCEPTION (t);
2367 throw t;
2369 jobject res = _Jv_AllocObject (klass);
2370 PUSHA (res);
2372 #ifdef DIRECT_THREADED
2373 REWRITE_INSN (&&new_resolved, datum, klass);
2374 #endif /* DIRECT_THREADED */
2376 NEXT_INSN;
2378 #ifdef DIRECT_THREADED
2379 new_resolved:
2381 jclass klass = (jclass) AVAL ();
2382 jobject res = _Jv_AllocObject (klass);
2383 PUSHA (res);
2385 NEXT_INSN;
2386 #endif /* DIRECT_THREADED */
2388 insn_newarray:
2390 int atype = GET1U ();
2391 int size = POPI();
2392 jobject result = _Jv_NewArray (atype, size);
2393 PUSHA (result);
2395 NEXT_INSN;
2397 insn_anewarray:
2399 SAVE_PC();
2400 int index = GET2U ();
2401 jclass klass = (_Jv_Linker::resolve_pool_entry (meth->defining_class,
2402 index)).clazz;
2403 int size = POPI();
2404 jobject result = _Jv_NewObjectArray (size, klass, 0);
2405 PUSHA (result);
2407 #ifdef DIRECT_THREADED
2408 REWRITE_INSN (&&anewarray_resolved, datum, klass);
2409 #endif /* DIRECT_THREADED */
2411 NEXT_INSN;
2413 #ifdef DIRECT_THREADED
2414 anewarray_resolved:
2416 jclass klass = (jclass) AVAL ();
2417 int size = POPI ();
2418 jobject result = _Jv_NewObjectArray (size, klass, 0);
2419 PUSHA (result);
2421 NEXT_INSN;
2422 #endif /* DIRECT_THREADED */
2424 insn_arraylength:
2426 __JArray *arr = (__JArray*)POPA();
2427 NULLARRAYCHECK (arr);
2428 PUSHI (arr->length);
2430 NEXT_INSN;
2432 insn_athrow:
2434 jobject value = POPA();
2435 jthrowable t = static_cast<jthrowable> (value);
2436 INTERP_REPORT_EXCEPTION (t);
2437 throw t;
2439 NEXT_INSN;
2441 insn_checkcast:
2443 SAVE_PC();
2444 jobject value = POPA();
2445 jint index = GET2U ();
2446 jclass to = (_Jv_Linker::resolve_pool_entry (meth->defining_class,
2447 index)).clazz;
2449 value = (jobject) _Jv_CheckCast (to, value);
2451 PUSHA (value);
2453 #ifdef DIRECT_THREADED
2454 REWRITE_INSN (&&checkcast_resolved, datum, to);
2455 #endif /* DIRECT_THREADED */
2457 NEXT_INSN;
2459 #ifdef DIRECT_THREADED
2460 checkcast_resolved:
2462 SAVE_PC();
2463 jobject value = POPA ();
2464 jclass to = (jclass) AVAL ();
2465 value = (jobject) _Jv_CheckCast (to, value);
2466 PUSHA (value);
2468 NEXT_INSN;
2469 #endif /* DIRECT_THREADED */
2471 insn_instanceof:
2473 SAVE_PC();
2474 jobject value = POPA();
2475 jint index = GET2U ();
2476 jclass to = (_Jv_Linker::resolve_pool_entry (meth->defining_class,
2477 index)).clazz;
2478 PUSHI (to->isInstance (value));
2480 #ifdef DIRECT_THREADED
2481 REWRITE_INSN (&&instanceof_resolved, datum, to);
2482 #endif /* DIRECT_THREADED */
2484 NEXT_INSN;
2486 #ifdef DIRECT_THREADED
2487 instanceof_resolved:
2489 jobject value = POPA ();
2490 jclass to = (jclass) AVAL ();
2491 PUSHI (to->isInstance (value));
2493 NEXT_INSN;
2494 #endif /* DIRECT_THREADED */
2496 insn_monitorenter:
2498 jobject value = POPA();
2499 NULLCHECK(value);
2500 _Jv_MonitorEnter (value);
2502 NEXT_INSN;
2504 insn_monitorexit:
2506 jobject value = POPA();
2507 NULLCHECK(value);
2508 _Jv_MonitorExit (value);
2510 NEXT_INSN;
2512 insn_ifnull:
2514 jobject val = POPA();
2515 if (val == NULL)
2516 TAKE_GOTO;
2517 else
2518 SKIP_GOTO;
2520 NEXT_INSN;
2522 insn_ifnonnull:
2524 jobject val = POPA();
2525 if (val != NULL)
2526 TAKE_GOTO;
2527 else
2528 SKIP_GOTO;
2530 NEXT_INSN;
2532 insn_multianewarray:
2534 SAVE_PC();
2535 int kind_index = GET2U ();
2536 int dim = GET1U ();
2538 jclass type
2539 = (_Jv_Linker::resolve_pool_entry (meth->defining_class,
2540 kind_index)).clazz;
2541 jint *sizes = (jint*) __builtin_alloca (sizeof (jint)*dim);
2543 for (int i = dim - 1; i >= 0; i--)
2545 sizes[i] = POPI ();
2548 jobject res = _Jv_NewMultiArray (type,dim, sizes);
2550 PUSHA (res);
2552 NEXT_INSN;
2554 #ifndef DIRECT_THREADED
2555 insn_wide:
2557 jint the_mod_op = get1u (pc++);
2558 jint wide = get2u (pc); pc += 2;
2560 switch (the_mod_op)
2562 case op_istore:
2563 STOREI (wide);
2564 NEXT_INSN;
2566 case op_fstore:
2567 STOREF (wide);
2568 NEXT_INSN;
2570 case op_astore:
2571 STOREA (wide);
2572 NEXT_INSN;
2574 case op_lload:
2575 LOADL (wide);
2576 NEXT_INSN;
2578 case op_dload:
2579 LOADD (wide);
2580 NEXT_INSN;
2582 case op_iload:
2583 LOADI (wide);
2584 NEXT_INSN;
2586 case op_fload:
2587 LOADF (wide);
2588 NEXT_INSN;
2590 case op_aload:
2591 LOADA (wide);
2592 NEXT_INSN;
2594 case op_lstore:
2595 STOREL (wide);
2596 NEXT_INSN;
2598 case op_dstore:
2599 STORED (wide);
2600 NEXT_INSN;
2602 case op_ret:
2603 pc = (unsigned char*) PEEKA (wide);
2604 NEXT_INSN;
2606 case op_iinc:
2608 jint amount = get2s (pc); pc += 2;
2609 jint value = PEEKI (wide);
2610 POKEI (wide, value+amount);
2612 NEXT_INSN;
2614 default:
2615 throw_internal_error ("illegal bytecode modified by wide");
2619 #endif /* DIRECT_THREADED */
2621 insn_breakpoint:
2623 using namespace ::java::lang;
2624 jmethodID method = meth->self;
2625 jlocation location = meth->insn_index (pc - 1);
2627 using namespace gnu::gcj::jvmti;
2628 Breakpoint *bp
2629 = BreakpointManager::getBreakpoint (reinterpret_cast<jlong> (method),
2630 location);
2631 JvAssert (bp != NULL);
2633 // Save the insn here since the breakpoint could be removed
2634 // before the JVMTI notification returns.
2635 pc_t opc = reinterpret_cast<pc_t> (bp->getInsn ());
2637 bp->execute ();
2639 // Continue execution
2640 #ifdef DIRECT_THREADED
2641 goto *(opc->insn);
2642 #else
2643 goto *(insn_target[*opc]);
2644 #endif
2647 catch (java::lang::Throwable *ex)
2649 // Check if the exception is handled and, if so, set the pc to the start
2650 // of the appropriate catch block.
2651 if (meth->check_handler (&pc, meth, ex))
2653 sp = stack;
2654 sp++->o = ex; // Push exception.
2655 #ifdef DEBUG
2656 if (JVMTI_REQUESTED_EVENT (ExceptionCatch))
2658 using namespace gnu::gcj::jvmti;
2659 jlong catch_meth = reinterpret_cast<jlong> (meth->get_method ());
2660 jlong catch_loc = meth->insn_index (pc);
2661 _Jv_JVMTI_PostEvent (JVMTI_EVENT_EXCEPTION_CATCH, thread,
2662 _Jv_GetCurrentJNIEnv (), catch_meth,
2663 catch_loc, ex);
2665 #endif
2666 NEXT_INSN;
2669 // No handler, so re-throw.
2670 throw ex;