jvmti-int.h (JVMTI): Declare member "enabled".
[platform/upstream/gcc.git] / libjava / interpret-run.cc
1 // interpret-run.cc - Code to interpret bytecode
2
3 /* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation
4
5    This file is part of libgcj.
6
7 This software is copyrighted work licensed under the terms of the
8 Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
9 details.  */
10
11 /* This file is meant only to be included in interpret.cc, it should not be
12  * compiled directly.   */
13
14   using namespace java::lang::reflect;
15
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
21   // returns.
22   java::lang::Thread *thread = java::lang::Thread::currentThread();
23   _Jv_InterpFrame frame_desc (meth, thread);
24
25   _Jv_word stack[meth->max_stack];
26   _Jv_word *sp = stack;
27
28   _Jv_word locals[meth->max_locals];
29
30 #define INSN_LABEL(op) &&insn_##op
31
32   static const void *const insn_target[] = 
33   {
34     INSN_LABEL(nop),
35     INSN_LABEL(aconst_null),
36     INSN_LABEL(iconst_m1),
37     INSN_LABEL(iconst_0),
38     INSN_LABEL(iconst_1),
39     INSN_LABEL(iconst_2),
40     INSN_LABEL(iconst_3),
41     INSN_LABEL(iconst_4),
42     INSN_LABEL(iconst_5),
43     INSN_LABEL(lconst_0),
44     INSN_LABEL(lconst_1),
45     INSN_LABEL(fconst_0),
46     INSN_LABEL(fconst_1),
47     INSN_LABEL(fconst_2),
48     INSN_LABEL(dconst_0),
49     INSN_LABEL(dconst_1),
50     INSN_LABEL(bipush),
51     INSN_LABEL(sipush),
52     INSN_LABEL(ldc),
53     INSN_LABEL(ldc_w),
54     INSN_LABEL(ldc2_w),
55     INSN_LABEL(iload),
56     INSN_LABEL(lload),
57     INSN_LABEL(fload),
58     INSN_LABEL(dload),
59     INSN_LABEL(aload),
60     INSN_LABEL(iload_0),
61     INSN_LABEL(iload_1),
62     INSN_LABEL(iload_2),
63     INSN_LABEL(iload_3),
64     INSN_LABEL(lload_0),
65     INSN_LABEL(lload_1),
66     INSN_LABEL(lload_2),
67     INSN_LABEL(lload_3),
68     INSN_LABEL(fload_0),
69     INSN_LABEL(fload_1),
70     INSN_LABEL(fload_2),
71     INSN_LABEL(fload_3),
72     INSN_LABEL(dload_0),
73     INSN_LABEL(dload_1),
74     INSN_LABEL(dload_2),
75     INSN_LABEL(dload_3),
76     INSN_LABEL(aload_0),
77     INSN_LABEL(aload_1),
78     INSN_LABEL(aload_2),
79     INSN_LABEL(aload_3),
80     INSN_LABEL(iaload),
81     INSN_LABEL(laload),
82     INSN_LABEL(faload),
83     INSN_LABEL(daload),
84     INSN_LABEL(aaload),
85     INSN_LABEL(baload),
86     INSN_LABEL(caload),
87     INSN_LABEL(saload),
88     INSN_LABEL(istore),
89     INSN_LABEL(lstore),
90     INSN_LABEL(fstore),
91     INSN_LABEL(dstore),
92     INSN_LABEL(astore),
93     INSN_LABEL(istore_0),
94     INSN_LABEL(istore_1),
95     INSN_LABEL(istore_2),
96     INSN_LABEL(istore_3),
97     INSN_LABEL(lstore_0),
98     INSN_LABEL(lstore_1),
99     INSN_LABEL(lstore_2),
100     INSN_LABEL(lstore_3),
101     INSN_LABEL(fstore_0),
102     INSN_LABEL(fstore_1),
103     INSN_LABEL(fstore_2),
104     INSN_LABEL(fstore_3),
105     INSN_LABEL(dstore_0),
106     INSN_LABEL(dstore_1),
107     INSN_LABEL(dstore_2),
108     INSN_LABEL(dstore_3),
109     INSN_LABEL(astore_0),
110     INSN_LABEL(astore_1),
111     INSN_LABEL(astore_2),
112     INSN_LABEL(astore_3),
113     INSN_LABEL(iastore),
114     INSN_LABEL(lastore),
115     INSN_LABEL(fastore),
116     INSN_LABEL(dastore),
117     INSN_LABEL(aastore),
118     INSN_LABEL(bastore),
119     INSN_LABEL(castore),
120     INSN_LABEL(sastore),
121     INSN_LABEL(pop),
122     INSN_LABEL(pop2),
123     INSN_LABEL(dup),
124     INSN_LABEL(dup_x1),
125     INSN_LABEL(dup_x2),
126     INSN_LABEL(dup2),
127     INSN_LABEL(dup2_x1),
128     INSN_LABEL(dup2_x2),
129     INSN_LABEL(swap),
130     INSN_LABEL(iadd),
131     INSN_LABEL(ladd),
132     INSN_LABEL(fadd),
133     INSN_LABEL(dadd),
134     INSN_LABEL(isub),
135     INSN_LABEL(lsub),
136     INSN_LABEL(fsub),
137     INSN_LABEL(dsub),
138     INSN_LABEL(imul),
139     INSN_LABEL(lmul),
140     INSN_LABEL(fmul),
141     INSN_LABEL(dmul),
142     INSN_LABEL(idiv),
143     INSN_LABEL(ldiv),
144     INSN_LABEL(fdiv),
145     INSN_LABEL(ddiv),
146     INSN_LABEL(irem),
147     INSN_LABEL(lrem),
148     INSN_LABEL(frem),
149     INSN_LABEL(drem),
150     INSN_LABEL(ineg),
151     INSN_LABEL(lneg),
152     INSN_LABEL(fneg),
153     INSN_LABEL(dneg),
154     INSN_LABEL(ishl),
155     INSN_LABEL(lshl),
156     INSN_LABEL(ishr),
157     INSN_LABEL(lshr),
158     INSN_LABEL(iushr),
159     INSN_LABEL(lushr),
160     INSN_LABEL(iand),
161     INSN_LABEL(land),
162     INSN_LABEL(ior),
163     INSN_LABEL(lor),
164     INSN_LABEL(ixor),
165     INSN_LABEL(lxor),
166     INSN_LABEL(iinc),
167     INSN_LABEL(i2l),
168     INSN_LABEL(i2f),
169     INSN_LABEL(i2d),
170     INSN_LABEL(l2i),
171     INSN_LABEL(l2f),
172     INSN_LABEL(l2d),
173     INSN_LABEL(f2i),
174     INSN_LABEL(f2l),
175     INSN_LABEL(f2d),
176     INSN_LABEL(d2i),
177     INSN_LABEL(d2l),
178     INSN_LABEL(d2f),
179     INSN_LABEL(i2b),
180     INSN_LABEL(i2c),
181     INSN_LABEL(i2s),
182     INSN_LABEL(lcmp),
183     INSN_LABEL(fcmpl),
184     INSN_LABEL(fcmpg),
185     INSN_LABEL(dcmpl),
186     INSN_LABEL(dcmpg),
187     INSN_LABEL(ifeq),
188     INSN_LABEL(ifne),
189     INSN_LABEL(iflt),
190     INSN_LABEL(ifge),
191     INSN_LABEL(ifgt),
192     INSN_LABEL(ifle),
193     INSN_LABEL(if_icmpeq),
194     INSN_LABEL(if_icmpne),
195     INSN_LABEL(if_icmplt),
196     INSN_LABEL(if_icmpge),
197     INSN_LABEL(if_icmpgt),
198     INSN_LABEL(if_icmple),
199     INSN_LABEL(if_acmpeq),
200     INSN_LABEL(if_acmpne),
201     INSN_LABEL(goto), 
202     INSN_LABEL(jsr),
203     INSN_LABEL(ret),
204     INSN_LABEL(tableswitch),
205     INSN_LABEL(lookupswitch),
206     INSN_LABEL(ireturn),
207     INSN_LABEL(lreturn),
208     INSN_LABEL(freturn),
209     INSN_LABEL(dreturn),
210     INSN_LABEL(areturn),
211     INSN_LABEL(return),
212     INSN_LABEL(getstatic),
213     INSN_LABEL(putstatic),
214     INSN_LABEL(getfield),
215     INSN_LABEL(putfield),
216     INSN_LABEL(invokevirtual),
217     INSN_LABEL(invokespecial),
218     INSN_LABEL(invokestatic),
219     INSN_LABEL(invokeinterface),
220     INSN_LABEL(breakpoint),
221     INSN_LABEL(new),
222     INSN_LABEL(newarray),
223     INSN_LABEL(anewarray),
224     INSN_LABEL(arraylength),
225     INSN_LABEL(athrow),
226     INSN_LABEL(checkcast),
227     INSN_LABEL(instanceof),
228     INSN_LABEL(monitorenter),
229     INSN_LABEL(monitorexit),
230 #ifdef DIRECT_THREADED
231     0, // wide
232 #else
233     INSN_LABEL(wide),
234 #endif
235     INSN_LABEL(multianewarray),
236     INSN_LABEL(ifnull),
237     INSN_LABEL(ifnonnull),
238     INSN_LABEL(goto_w),
239     INSN_LABEL(jsr_w),
240 #ifdef DIRECT_THREADED
241     INSN_LABEL (ldc_class)
242 #else
243     0
244 #endif
245   };
246
247   pc_t pc;
248
249 #ifdef DIRECT_THREADED
250
251 #ifdef DEBUG
252 #undef NEXT_INSN
253 #define NEXT_INSN                                                       \
254   do                                                                    \
255     {                                                                   \
256       if (JVMTI_REQUESTED_EVENT (SingleStep))                           \
257         {                                                               \
258           JNIEnv *env = _Jv_GetCurrentJNIEnv ();                        \
259           jmethodID method = meth->self;                                \
260           jlocation loc = meth->insn_index (pc);                        \
261           _Jv_JVMTI_PostEvent (JVMTI_EVENT_SINGLE_STEP, thread,         \
262                                env, method, loc);                       \
263         }                                                               \
264       goto *((pc++)->insn);                                             \
265     }                                                                   \
266   while (0)
267 #else
268 #undef NEXT_INSN
269 #define NEXT_INSN goto *((pc++)->insn)
270 #endif
271
272 #define INTVAL() ((pc++)->int_val)
273 #define AVAL() ((pc++)->datum)
274
275 #define GET1S() INTVAL ()
276 #define GET2S() INTVAL ()
277 #define GET1U() INTVAL ()
278 #define GET2U() INTVAL ()
279 #define AVAL1U() AVAL ()
280 #define AVAL2U() AVAL ()
281 #define AVAL2UP() AVAL ()
282 #define SKIP_GOTO ++pc
283 #define GOTO_VAL() (insn_slot *) pc->datum
284 #define PCVAL(unionval) unionval.p
285 #define AMPAMP(label) &&label
286
287   // Compile if we must. NOTE: Double-check locking.
288   if (meth->prepared == NULL)
289     {
290       _Jv_MutexLock (&compile_mutex);
291       if (meth->prepared == NULL)
292         meth->compile (insn_target);
293       _Jv_MutexUnlock (&compile_mutex);
294     }
295
296   // If we're only compiling, stop here
297   if (args == NULL)
298     return;
299
300   pc = (insn_slot *) meth->prepared;
301
302 #else
303
304 #ifdef DEBUG
305 #define NEXT_INSN                                                       \
306   do                                                                    \
307     {                                                                   \
308       if (JVMTI_REQUESTED_EVENT (SingleStep))                           \
309         {                                                               \
310           JNIEnv *env = _Jv_GetCurrentJNIEnv ();                        \
311           jmethodID method = meth->self;                                \
312           jlocation loc = meth->insn_index (pc);                        \
313           _Jv_JVMTI_PostEvent (JVMTI_EVENT_SINGLE_STEP, thread,         \
314                                env, method, loc);                       \
315         }                                                               \
316       goto *(insn_target[*pc++])
317 #else
318 #define NEXT_INSN goto *(insn_target[*pc++])
319 #endif
320
321 #define GET1S() get1s (pc++)
322 #define GET2S() (pc += 2, get2s (pc- 2))
323 #define GET1U() get1u (pc++)
324 #define GET2U() (pc += 2, get2u (pc - 2))
325   // Note that these could be more efficient when not handling 'ldc
326   // class'.
327 #define AVAL1U()                                                \
328   ({ int index = get1u (pc++);                                  \
329     _Jv_Linker::resolve_pool_entry (meth->defining_class, index).o; })
330 #define AVAL2U()                                                \
331   ({ int index = get2u (pc); pc += 2;                           \
332     _Jv_Linker::resolve_pool_entry (meth->defining_class, index).o; })
333   // Note that we don't need to resolve the pool entry here as class
334   // constants are never wide.
335 #define AVAL2UP() ({ int index = get2u (pc); pc += 2; &pool_data[index]; })
336 #define SKIP_GOTO pc += 2
337 #define GOTO_VAL() pc - 1 + get2s (pc)
338 #define PCVAL(unionval) unionval.i
339 #define AMPAMP(label) NULL
340
341   pc = meth->bytecode ();
342
343 #endif /* DIRECT_THREADED */
344
345 #define TAKE_GOTO pc = GOTO_VAL ()
346
347   /* Go straight at it!  the ffi raw format matches the internal
348      stack representation exactly.  At least, that's the idea.
349   */
350   memcpy ((void*) locals, (void*) args, meth->args_raw_size);
351
352   _Jv_word *pool_data = meth->defining_class->constants.data;
353
354   /* These three are temporaries for common code used by several
355      instructions.  */
356   void (*fun)();
357   _Jv_ResolvedMethod* rmeth;
358   int tmpval;
359
360   try
361     {
362       // We keep nop around.  It is used if we're interpreting the
363       // bytecodes and not doing direct threading.
364     insn_nop:
365       NEXT_INSN;
366
367       /* The first few instructions here are ordered according to their
368          frequency, in the hope that this will improve code locality a
369          little.  */
370
371     insn_aload_0:               // 0x2a
372       LOADA (0);
373       NEXT_INSN;
374
375     insn_iload:         // 0x15
376       LOADI (GET1U ());
377       NEXT_INSN;
378
379     insn_iload_1:               // 0x1b
380       LOADI (1);
381       NEXT_INSN;
382
383     insn_invokevirtual: // 0xb6
384       {
385         SAVE_PC();
386         int index = GET2U ();
387
388         /* _Jv_Linker::resolve_pool_entry returns immediately if the
389          * value already is resolved.  If we want to clutter up the
390          * code here to gain a little performance, then we can check
391          * the corresponding bit JV_CONSTANT_ResolvedFlag in the tag
392          * directly.  For now, I don't think it is worth it.  */
393
394         rmeth = (_Jv_Linker::resolve_pool_entry (meth->defining_class,
395                                                    index)).rmethod;
396
397         sp -= rmeth->stack_item_count;
398
399         if (rmeth->method->accflags & Modifier::FINAL)
400           {
401             // We can't rely on NULLCHECK working if the method is final.
402             if (! sp[0].o)
403               throw_null_pointer_exception ();
404
405             // Final methods might not appear in the vtable.
406             fun = (void (*)()) rmeth->method->ncode;
407           }
408         else
409           {
410             NULLCHECK (sp[0].o);
411             jobject rcv = sp[0].o;
412             _Jv_VTable *table = *(_Jv_VTable**) rcv;
413             fun = (void (*)()) table->get_method (rmeth->method->index);
414           }
415
416 #ifdef DIRECT_THREADED
417         // Rewrite instruction so that we use a faster pre-resolved
418         // method.
419         pc[-2].insn = &&invokevirtual_resolved;
420         pc[-1].datum = rmeth;
421 #endif /* DIRECT_THREADED */
422       }
423       goto perform_invoke;
424
425 #ifdef DIRECT_THREADED
426     invokevirtual_resolved:
427       {
428         SAVE_PC();
429         rmeth = (_Jv_ResolvedMethod *) AVAL ();
430         sp -= rmeth->stack_item_count;
431
432         if (rmeth->method->accflags & Modifier::FINAL)
433           {
434             // We can't rely on NULLCHECK working if the method is final.
435             if (! sp[0].o)
436               throw_null_pointer_exception ();
437
438             // Final methods might not appear in the vtable.
439             fun = (void (*)()) rmeth->method->ncode;
440           }
441         else
442           {
443             jobject rcv = sp[0].o;
444             _Jv_VTable *table = *(_Jv_VTable**) rcv;
445             fun = (void (*)()) table->get_method (rmeth->method->index);
446           }
447       }
448       goto perform_invoke;
449 #endif /* DIRECT_THREADED */
450
451     perform_invoke:
452       {
453         /* here goes the magic again... */
454         ffi_cif *cif = &rmeth->cif;
455         ffi_raw *raw = (ffi_raw*) sp;
456
457         _Jv_value rvalue;
458
459 #if FFI_NATIVE_RAW_API
460         /* We assume that this is only implemented if it's correct      */
461         /* to use it here.  On a 64 bit machine, it never is.           */
462         ffi_raw_call (cif, fun, (void*)&rvalue, raw);
463 #else
464         ffi_java_raw_call (cif, fun, (void*)&rvalue, raw);
465 #endif
466
467         int rtype = cif->rtype->type;
468
469         /* the likelyhood of object, int, or void return is very high,
470          * so those are checked before the switch */
471         if (rtype == FFI_TYPE_POINTER)
472           {
473             PUSHA (rvalue.object_value);
474           }
475         else if (rtype == FFI_TYPE_SINT32)
476           {
477             PUSHI (rvalue.int_value);
478           }
479         else if (rtype == FFI_TYPE_VOID)
480           {
481             /* skip */
482           }
483         else
484           {
485             switch (rtype)
486               {
487               case FFI_TYPE_SINT8:
488                 PUSHI ((jbyte)(rvalue.int_value & 0xff));
489                 break;
490
491               case FFI_TYPE_SINT16:
492                 PUSHI ((jshort)(rvalue.int_value & 0xffff));
493                 break;
494
495               case FFI_TYPE_UINT16:
496                 PUSHI (rvalue.int_value & 0xffff);
497                 break;
498
499               case FFI_TYPE_FLOAT:
500                 PUSHF (rvalue.float_value);
501                 break;
502
503               case FFI_TYPE_DOUBLE:
504                 PUSHD (rvalue.double_value);
505                 break;
506
507               case FFI_TYPE_SINT64:
508                 PUSHL (rvalue.long_value);
509                 break;
510
511               default:
512                 throw_internal_error ("unknown return type in invokeXXX");
513               }
514           }
515       }
516       NEXT_INSN;
517
518     insn_aconst_null:
519       PUSHA (NULL);
520       NEXT_INSN;
521
522     insn_iconst_m1:
523       PUSHI (-1);
524       NEXT_INSN;
525
526     insn_iconst_0:
527       PUSHI (0);
528       NEXT_INSN;
529
530     insn_iconst_1:
531       PUSHI (1);
532       NEXT_INSN;
533
534     insn_iconst_2:
535       PUSHI (2);
536       NEXT_INSN;
537
538     insn_iconst_3:
539       PUSHI (3);
540       NEXT_INSN;
541
542     insn_iconst_4:
543       PUSHI (4);
544       NEXT_INSN;
545
546     insn_iconst_5:
547       PUSHI (5);
548       NEXT_INSN;
549
550     insn_lconst_0:
551       PUSHL (0);
552       NEXT_INSN;
553
554     insn_lconst_1:
555       PUSHL (1);
556       NEXT_INSN;
557
558     insn_fconst_0:
559       PUSHF (0);
560       NEXT_INSN;
561
562     insn_fconst_1:
563       PUSHF (1);
564       NEXT_INSN;
565
566     insn_fconst_2:
567       PUSHF (2);
568       NEXT_INSN;
569
570     insn_dconst_0:
571       PUSHD (0);
572       NEXT_INSN;
573
574     insn_dconst_1:
575       PUSHD (1);
576       NEXT_INSN;
577
578     insn_bipush:
579       // For direct threaded, bipush and sipush are the same.
580 #ifndef DIRECT_THREADED
581       PUSHI (GET1S ());
582       NEXT_INSN;
583 #endif /* DIRECT_THREADED */
584     insn_sipush:
585       PUSHI (GET2S ());
586       NEXT_INSN;
587
588     insn_ldc:
589       // For direct threaded, ldc and ldc_w are the same.
590 #ifndef DIRECT_THREADED
591       PUSHA ((jobject) AVAL1U ());
592       NEXT_INSN;
593 #endif /* DIRECT_THREADED */
594     insn_ldc_w:
595       PUSHA ((jobject) AVAL2U ());
596       NEXT_INSN;
597
598 #ifdef DIRECT_THREADED
599       // For direct threaded we have a separate 'ldc class' operation.
600     insn_ldc_class:
601       {
602         SAVE_PC();
603         // We could rewrite the instruction at this point.
604         int index = INTVAL ();
605         jobject k = (_Jv_Linker::resolve_pool_entry (meth->defining_class,
606                                                      index)).o;
607         PUSHA (k);
608       }
609       NEXT_INSN;
610 #endif /* DIRECT_THREADED */
611
612     insn_ldc2_w:
613       {
614         void *where = AVAL2UP ();
615         memcpy (sp, where, 2*sizeof (_Jv_word));
616         sp += 2;
617       }
618       NEXT_INSN;
619
620     insn_lload:
621       LOADL (GET1U ());
622       NEXT_INSN;
623
624     insn_fload:
625       LOADF (GET1U ());
626       NEXT_INSN;
627
628     insn_dload:
629       LOADD (GET1U ());
630       NEXT_INSN;
631
632     insn_aload:
633       LOADA (GET1U ());
634       NEXT_INSN;
635
636     insn_iload_0:
637       LOADI (0);
638       NEXT_INSN;
639
640     insn_iload_2:
641       LOADI (2);
642       NEXT_INSN;
643
644     insn_iload_3:
645       LOADI (3);
646       NEXT_INSN;
647
648     insn_lload_0:
649       LOADL (0);
650       NEXT_INSN;
651
652     insn_lload_1:
653       LOADL (1);
654       NEXT_INSN;
655
656     insn_lload_2:
657       LOADL (2);
658       NEXT_INSN;
659
660     insn_lload_3:
661       LOADL (3);
662       NEXT_INSN;
663
664     insn_fload_0:
665       LOADF (0);
666       NEXT_INSN;
667
668     insn_fload_1:
669       LOADF (1);
670       NEXT_INSN;
671
672     insn_fload_2:
673       LOADF (2);
674       NEXT_INSN;
675
676     insn_fload_3:
677       LOADF (3);
678       NEXT_INSN;
679
680     insn_dload_0:
681       LOADD (0);
682       NEXT_INSN;
683
684     insn_dload_1:
685       LOADD (1);
686       NEXT_INSN;
687
688     insn_dload_2:
689       LOADD (2);
690       NEXT_INSN;
691
692     insn_dload_3:
693       LOADD (3);
694       NEXT_INSN;
695
696     insn_aload_1:
697       LOADA(1);
698       NEXT_INSN;
699
700     insn_aload_2:
701       LOADA(2);
702       NEXT_INSN;
703
704     insn_aload_3:
705       LOADA(3);
706       NEXT_INSN;
707
708     insn_iaload:
709       {
710         jint index = POPI();
711         jintArray arr = (jintArray) POPA();
712         NULLARRAYCHECK (arr);
713         ARRAYBOUNDSCHECK (arr, index);
714         PUSHI( elements(arr)[index] );
715       }
716       NEXT_INSN;
717
718     insn_laload:
719       {
720         jint index = POPI();
721         jlongArray arr = (jlongArray) POPA();
722         NULLARRAYCHECK (arr);
723         ARRAYBOUNDSCHECK (arr, index);
724         PUSHL( elements(arr)[index] );
725       }
726       NEXT_INSN;
727
728     insn_faload:
729       {
730         jint index = POPI();
731         jfloatArray arr = (jfloatArray) POPA();
732         NULLARRAYCHECK (arr);
733         ARRAYBOUNDSCHECK (arr, index);
734         PUSHF( elements(arr)[index] );
735       }
736       NEXT_INSN;
737
738     insn_daload:
739       {
740         jint index = POPI();
741         jdoubleArray arr = (jdoubleArray) POPA();
742         NULLARRAYCHECK (arr);
743         ARRAYBOUNDSCHECK (arr, index);
744         PUSHD( elements(arr)[index] );
745       }
746       NEXT_INSN;
747
748     insn_aaload:
749       {
750         jint index = POPI();
751         jobjectArray arr = (jobjectArray) POPA();
752         NULLARRAYCHECK (arr);
753         ARRAYBOUNDSCHECK (arr, index);
754         PUSHA( elements(arr)[index] );
755       }
756       NEXT_INSN;
757
758     insn_baload:
759       {
760         jint index = POPI();
761         jbyteArray arr = (jbyteArray) POPA();
762         NULLARRAYCHECK (arr);
763         ARRAYBOUNDSCHECK (arr, index);
764         PUSHI( elements(arr)[index] );
765       }
766       NEXT_INSN;
767
768     insn_caload:
769       {
770         jint index = POPI();
771         jcharArray arr = (jcharArray) POPA();
772         NULLARRAYCHECK (arr);
773         ARRAYBOUNDSCHECK (arr, index);
774         PUSHI( elements(arr)[index] );
775       }
776       NEXT_INSN;
777
778     insn_saload:
779       {
780         jint index = POPI();
781         jshortArray arr = (jshortArray) POPA();
782         NULLARRAYCHECK (arr);
783         ARRAYBOUNDSCHECK (arr, index);
784         PUSHI( elements(arr)[index] );
785       }
786       NEXT_INSN;
787
788     insn_istore:
789       STOREI (GET1U ());
790       NEXT_INSN;
791
792     insn_lstore:
793       STOREL (GET1U ());
794       NEXT_INSN;
795
796     insn_fstore:
797       STOREF (GET1U ());
798       NEXT_INSN;
799
800     insn_dstore:
801       STORED (GET1U ());
802       NEXT_INSN;
803
804     insn_astore:
805       STOREA (GET1U ());
806       NEXT_INSN;
807
808     insn_istore_0:
809       STOREI (0);
810       NEXT_INSN;
811
812     insn_istore_1:
813       STOREI (1);
814       NEXT_INSN;
815
816     insn_istore_2:
817       STOREI (2);
818       NEXT_INSN;
819
820     insn_istore_3:
821       STOREI (3);
822       NEXT_INSN;
823
824     insn_lstore_0:
825       STOREL (0);
826       NEXT_INSN;
827
828     insn_lstore_1:
829       STOREL (1);
830       NEXT_INSN;
831
832     insn_lstore_2:
833       STOREL (2);
834       NEXT_INSN;
835
836     insn_lstore_3:
837       STOREL (3);
838       NEXT_INSN;
839
840     insn_fstore_0:
841       STOREF (0);
842       NEXT_INSN;
843
844     insn_fstore_1:
845       STOREF (1);
846       NEXT_INSN;
847
848     insn_fstore_2:
849       STOREF (2);
850       NEXT_INSN;
851
852     insn_fstore_3:
853       STOREF (3);
854       NEXT_INSN;
855
856     insn_dstore_0:
857       STORED (0);
858       NEXT_INSN;
859
860     insn_dstore_1:
861       STORED (1);
862       NEXT_INSN;
863
864     insn_dstore_2:
865       STORED (2);
866       NEXT_INSN;
867
868     insn_dstore_3:
869       STORED (3);
870       NEXT_INSN;
871
872     insn_astore_0:
873       STOREA(0);
874       NEXT_INSN;
875
876     insn_astore_1:
877       STOREA(1);
878       NEXT_INSN;
879
880     insn_astore_2:
881       STOREA(2);
882       NEXT_INSN;
883
884     insn_astore_3:
885       STOREA(3);
886       NEXT_INSN;
887
888     insn_iastore:
889       {
890         jint value = POPI();
891         jint index  = POPI();
892         jintArray arr = (jintArray) POPA();
893         NULLARRAYCHECK (arr);
894         ARRAYBOUNDSCHECK (arr, index);
895         elements(arr)[index] = value;
896       }
897       NEXT_INSN;
898
899     insn_lastore:
900       {
901         jlong value = POPL();
902         jint index  = POPI();
903         jlongArray arr = (jlongArray) POPA();
904         NULLARRAYCHECK (arr);
905         ARRAYBOUNDSCHECK (arr, index);
906         elements(arr)[index] = value;
907       }
908       NEXT_INSN;
909
910     insn_fastore:
911       {
912         jfloat value = POPF();
913         jint index  = POPI();
914         jfloatArray arr = (jfloatArray) POPA();
915         NULLARRAYCHECK (arr);
916         ARRAYBOUNDSCHECK (arr, index);
917         elements(arr)[index] = value;
918       }
919       NEXT_INSN;
920
921     insn_dastore:
922       {
923         jdouble value = POPD();
924         jint index  = POPI();
925         jdoubleArray arr = (jdoubleArray) POPA();
926         NULLARRAYCHECK (arr);
927         ARRAYBOUNDSCHECK (arr, index);
928         elements(arr)[index] = value;
929       }
930       NEXT_INSN;
931
932     insn_aastore:
933       {
934         jobject value = POPA();
935         jint index  = POPI();
936         jobjectArray arr = (jobjectArray) POPA();
937         NULLARRAYCHECK (arr);
938         ARRAYBOUNDSCHECK (arr, index);
939         _Jv_CheckArrayStore (arr, value);
940         elements(arr)[index] = value;
941       }
942       NEXT_INSN;
943
944     insn_bastore:
945       {
946         jbyte value = (jbyte) POPI();
947         jint index  = POPI();
948         jbyteArray arr = (jbyteArray) POPA();
949         NULLARRAYCHECK (arr);
950         ARRAYBOUNDSCHECK (arr, index);
951         elements(arr)[index] = value;
952       }
953       NEXT_INSN;
954
955     insn_castore:
956       {
957         jchar value = (jchar) POPI();
958         jint index  = POPI();
959         jcharArray arr = (jcharArray) POPA();
960         NULLARRAYCHECK (arr);
961         ARRAYBOUNDSCHECK (arr, index);
962         elements(arr)[index] = value;
963       }
964       NEXT_INSN;
965
966     insn_sastore:
967       {
968         jshort value = (jshort) POPI();
969         jint index  = POPI();
970         jshortArray arr = (jshortArray) POPA();
971         NULLARRAYCHECK (arr);
972         ARRAYBOUNDSCHECK (arr, index);
973         elements(arr)[index] = value;
974       }
975       NEXT_INSN;
976
977     insn_pop:
978       sp -= 1;
979       NEXT_INSN;
980
981     insn_pop2:
982       sp -= 2;
983       NEXT_INSN;
984
985     insn_dup:
986       sp[0] = sp[-1];
987       sp += 1;
988       NEXT_INSN;
989
990     insn_dup_x1:
991       dupx (sp, 1, 1); sp+=1;
992       NEXT_INSN;
993
994     insn_dup_x2:
995       dupx (sp, 1, 2); sp+=1;
996       NEXT_INSN;
997
998     insn_dup2:
999       sp[0] = sp[-2];
1000       sp[1] = sp[-1];
1001       sp += 2;
1002       NEXT_INSN;
1003
1004     insn_dup2_x1:
1005       dupx (sp, 2, 1); sp+=2;
1006       NEXT_INSN;
1007
1008     insn_dup2_x2:
1009       dupx (sp, 2, 2); sp+=2;
1010       NEXT_INSN;
1011
1012     insn_swap:
1013       {
1014         jobject tmp1 = POPA();
1015         jobject tmp2 = POPA();
1016         PUSHA (tmp1);
1017         PUSHA (tmp2);
1018       }
1019       NEXT_INSN;
1020
1021     insn_iadd:
1022       BINOPI(+);
1023       NEXT_INSN;
1024
1025     insn_ladd:
1026       BINOPL(+);
1027       NEXT_INSN;
1028
1029     insn_fadd:
1030       BINOPF(+);
1031       NEXT_INSN;
1032
1033     insn_dadd:
1034       BINOPD(+);
1035       NEXT_INSN;
1036
1037     insn_isub:
1038       BINOPI(-);
1039       NEXT_INSN;
1040
1041     insn_lsub:
1042       BINOPL(-);
1043       NEXT_INSN;
1044
1045     insn_fsub:
1046       BINOPF(-);
1047       NEXT_INSN;
1048
1049     insn_dsub:
1050       BINOPD(-);
1051       NEXT_INSN;
1052
1053     insn_imul:
1054       BINOPI(*);
1055       NEXT_INSN;
1056
1057     insn_lmul:
1058       BINOPL(*);
1059       NEXT_INSN;
1060
1061     insn_fmul:
1062       BINOPF(*);
1063       NEXT_INSN;
1064
1065     insn_dmul:
1066       BINOPD(*);
1067       NEXT_INSN;
1068
1069     insn_idiv:
1070       {
1071         SAVE_PC();
1072         jint value2 = POPI();
1073         jint value1 = POPI();
1074         jint res = _Jv_divI (value1, value2);
1075         PUSHI (res);
1076       }
1077       NEXT_INSN;
1078
1079     insn_ldiv:
1080       {
1081         SAVE_PC();
1082         jlong value2 = POPL();
1083         jlong value1 = POPL();
1084         jlong res = _Jv_divJ (value1, value2);
1085         PUSHL (res);
1086       }
1087       NEXT_INSN;
1088
1089     insn_fdiv:
1090       {
1091         jfloat value2 = POPF();
1092         jfloat value1 = POPF();
1093         jfloat res = value1 / value2;
1094         PUSHF (res);
1095       }
1096       NEXT_INSN;
1097
1098     insn_ddiv:
1099       {
1100         jdouble value2 = POPD();
1101         jdouble value1 = POPD();
1102         jdouble res = value1 / value2;
1103         PUSHD (res);
1104       }
1105       NEXT_INSN;
1106
1107     insn_irem:
1108       {
1109         SAVE_PC();
1110         jint value2 = POPI();
1111         jint value1 =  POPI();
1112         jint res = _Jv_remI (value1, value2);
1113         PUSHI (res);
1114       }
1115       NEXT_INSN;
1116
1117     insn_lrem:
1118       {
1119         SAVE_PC();
1120         jlong value2 = POPL();
1121         jlong value1 = POPL();
1122         jlong res = _Jv_remJ (value1, value2);
1123         PUSHL (res);
1124       }
1125       NEXT_INSN;
1126
1127     insn_frem:
1128       {
1129         jfloat value2 = POPF();
1130         jfloat value1 = POPF();
1131         jfloat res    = __ieee754_fmod (value1, value2);
1132         PUSHF (res);
1133       }
1134       NEXT_INSN;
1135
1136     insn_drem:
1137       {
1138         jdouble value2 = POPD();
1139         jdouble value1 = POPD();
1140         jdouble res    = __ieee754_fmod (value1, value2);
1141         PUSHD (res);
1142       }
1143       NEXT_INSN;
1144
1145     insn_ineg:
1146       {
1147         jint value = POPI();
1148         PUSHI (value * -1);
1149       }
1150       NEXT_INSN;
1151
1152     insn_lneg:
1153       {
1154         jlong value = POPL();
1155         PUSHL (value * -1);
1156       }
1157       NEXT_INSN;
1158
1159     insn_fneg:
1160       {
1161         jfloat value = POPF();
1162         PUSHF (value * -1);
1163       }
1164       NEXT_INSN;
1165
1166     insn_dneg:
1167       {
1168         jdouble value = POPD();
1169         PUSHD (value * -1);
1170       }
1171       NEXT_INSN;
1172
1173     insn_ishl:
1174       {
1175         jint shift = (POPI() & 0x1f);
1176         jint value = POPI();
1177         PUSHI (value << shift);
1178       }
1179       NEXT_INSN;
1180
1181     insn_lshl:
1182       {
1183         jint shift = (POPI() & 0x3f);
1184         jlong value = POPL();
1185         PUSHL (value << shift);
1186       }
1187       NEXT_INSN;
1188
1189     insn_ishr:
1190       {
1191         jint shift = (POPI() & 0x1f);
1192         jint value = POPI();
1193         PUSHI (value >> shift);
1194       }
1195       NEXT_INSN;
1196
1197     insn_lshr:
1198       {
1199         jint shift = (POPI() & 0x3f);
1200         jlong value = POPL();
1201         PUSHL (value >> shift);
1202       }
1203       NEXT_INSN;
1204
1205     insn_iushr:
1206       {
1207         jint shift = (POPI() & 0x1f);
1208         _Jv_uint value = (_Jv_uint) POPI();
1209         PUSHI ((jint) (value >> shift));
1210       }
1211       NEXT_INSN;
1212
1213     insn_lushr:
1214       {
1215         jint shift = (POPI() & 0x3f);
1216         _Jv_ulong value = (_Jv_ulong) POPL();
1217         PUSHL ((jlong) (value >> shift));
1218       }
1219       NEXT_INSN;
1220
1221     insn_iand:
1222       BINOPI (&);
1223       NEXT_INSN;
1224
1225     insn_land:
1226       BINOPL (&);
1227       NEXT_INSN;
1228
1229     insn_ior:
1230       BINOPI (|);
1231       NEXT_INSN;
1232
1233     insn_lor:
1234       BINOPL (|);
1235       NEXT_INSN;
1236
1237     insn_ixor:
1238       BINOPI (^);
1239       NEXT_INSN;
1240
1241     insn_lxor:
1242       BINOPL (^);
1243       NEXT_INSN;
1244
1245     insn_iinc:
1246       {
1247         jint index  = GET1U ();
1248         jint amount = GET1S ();
1249         locals[index].i += amount;
1250       }
1251       NEXT_INSN;
1252
1253     insn_i2l:
1254       {jlong value = POPI(); PUSHL (value);}
1255       NEXT_INSN;
1256
1257     insn_i2f:
1258       {jfloat value = POPI(); PUSHF (value);}
1259       NEXT_INSN;
1260
1261     insn_i2d:
1262       {jdouble value = POPI(); PUSHD (value);}
1263       NEXT_INSN;
1264
1265     insn_l2i:
1266       {jint value = POPL(); PUSHI (value);}
1267       NEXT_INSN;
1268
1269     insn_l2f:
1270       {jfloat value = POPL(); PUSHF (value);}
1271       NEXT_INSN;
1272
1273     insn_l2d:
1274       {jdouble value = POPL(); PUSHD (value);}
1275       NEXT_INSN;
1276
1277     insn_f2i:
1278       {
1279         using namespace java::lang;
1280         jint value = convert (POPF (), Integer::MIN_VALUE, Integer::MAX_VALUE);
1281         PUSHI(value);
1282       }
1283       NEXT_INSN;
1284
1285     insn_f2l:
1286       {
1287         using namespace java::lang;
1288         jlong value = convert (POPF (), Long::MIN_VALUE, Long::MAX_VALUE);
1289         PUSHL(value);
1290       }
1291       NEXT_INSN;
1292
1293     insn_f2d:
1294       { jdouble value = POPF (); PUSHD(value); }
1295       NEXT_INSN;
1296
1297     insn_d2i:
1298       {
1299         using namespace java::lang;
1300         jint value = convert (POPD (), Integer::MIN_VALUE, Integer::MAX_VALUE);
1301         PUSHI(value);
1302       }
1303       NEXT_INSN;
1304
1305     insn_d2l:
1306       {
1307         using namespace java::lang;
1308         jlong value = convert (POPD (), Long::MIN_VALUE, Long::MAX_VALUE);
1309         PUSHL(value);
1310       }
1311       NEXT_INSN;
1312
1313     insn_d2f:
1314       { jfloat value = POPD (); PUSHF(value); }
1315       NEXT_INSN;
1316
1317     insn_i2b:
1318       { jbyte value = POPI (); PUSHI(value); }
1319       NEXT_INSN;
1320
1321     insn_i2c:
1322       { jchar value = POPI (); PUSHI(value); }
1323       NEXT_INSN;
1324
1325     insn_i2s:
1326       { jshort value = POPI (); PUSHI(value); }
1327       NEXT_INSN;
1328
1329     insn_lcmp:
1330       {
1331         jlong value2 = POPL ();
1332         jlong value1 = POPL ();
1333         if (value1 > value2)
1334           { PUSHI (1); }
1335         else if (value1 == value2)
1336           { PUSHI (0); }
1337         else
1338           { PUSHI (-1); }
1339       }
1340       NEXT_INSN;
1341
1342     insn_fcmpl:
1343       tmpval = -1;
1344       goto fcmp;
1345
1346     insn_fcmpg:
1347       tmpval = 1;
1348
1349     fcmp:
1350       {
1351         jfloat value2 = POPF ();
1352         jfloat value1 = POPF ();
1353         if (value1 > value2)
1354           PUSHI (1);
1355         else if (value1 == value2)
1356           PUSHI (0);
1357         else if (value1 < value2)
1358           PUSHI (-1);
1359         else
1360           PUSHI (tmpval);
1361       }
1362       NEXT_INSN;
1363
1364     insn_dcmpl:
1365       tmpval = -1;
1366       goto dcmp;
1367
1368     insn_dcmpg:
1369       tmpval = 1;
1370
1371     dcmp:
1372       {
1373         jdouble value2 = POPD ();
1374         jdouble value1 = POPD ();
1375         if (value1 > value2)
1376           PUSHI (1);
1377         else if (value1 == value2)
1378           PUSHI (0);
1379         else if (value1 < value2)
1380           PUSHI (-1);
1381         else
1382           PUSHI (tmpval);
1383       }
1384       NEXT_INSN;
1385
1386     insn_ifeq:
1387       {
1388         if (POPI() == 0)
1389           TAKE_GOTO;
1390         else
1391           SKIP_GOTO;
1392       }
1393       NEXT_INSN;
1394
1395     insn_ifne:
1396       {
1397         if (POPI() != 0)
1398           TAKE_GOTO;
1399         else
1400           SKIP_GOTO;
1401       }
1402       NEXT_INSN;
1403
1404     insn_iflt:
1405       {
1406         if (POPI() < 0)
1407           TAKE_GOTO;
1408         else
1409           SKIP_GOTO;
1410       }
1411       NEXT_INSN;
1412
1413     insn_ifge:
1414       {
1415         if (POPI() >= 0)
1416           TAKE_GOTO;
1417         else
1418           SKIP_GOTO;
1419       }
1420       NEXT_INSN;
1421
1422     insn_ifgt:
1423       {
1424         if (POPI() > 0)
1425           TAKE_GOTO;
1426         else
1427           SKIP_GOTO;
1428       }
1429       NEXT_INSN;
1430
1431     insn_ifle:
1432       {
1433         if (POPI() <= 0)
1434           TAKE_GOTO;
1435         else
1436           SKIP_GOTO;
1437       }
1438       NEXT_INSN;
1439
1440     insn_if_icmpeq:
1441       {
1442         jint value2 = POPI();
1443         jint value1 = POPI();
1444         if (value1 == value2)
1445           TAKE_GOTO;
1446         else
1447           SKIP_GOTO;
1448       }
1449       NEXT_INSN;
1450
1451     insn_if_icmpne:
1452       {
1453         jint value2 = POPI();
1454         jint value1 = POPI();
1455         if (value1 != value2)
1456           TAKE_GOTO;
1457         else
1458           SKIP_GOTO;
1459       }
1460       NEXT_INSN;
1461
1462     insn_if_icmplt:
1463       {
1464         jint value2 = POPI();
1465         jint value1 = POPI();
1466         if (value1 < value2)
1467           TAKE_GOTO;
1468         else
1469           SKIP_GOTO;
1470       }
1471       NEXT_INSN;
1472
1473     insn_if_icmpge:
1474       {
1475         jint value2 = POPI();
1476         jint value1 = POPI();
1477         if (value1 >= value2)
1478           TAKE_GOTO;
1479         else
1480           SKIP_GOTO;
1481       }
1482       NEXT_INSN;
1483
1484     insn_if_icmpgt:
1485       {
1486         jint value2 = POPI();
1487         jint value1 = POPI();
1488         if (value1 > value2)
1489           TAKE_GOTO;
1490         else
1491           SKIP_GOTO;
1492       }
1493       NEXT_INSN;
1494
1495     insn_if_icmple:
1496       {
1497         jint value2 = POPI();
1498         jint value1 = POPI();
1499         if (value1 <= value2)
1500           TAKE_GOTO;
1501         else
1502           SKIP_GOTO;
1503       }
1504       NEXT_INSN;
1505
1506     insn_if_acmpeq:
1507       {
1508         jobject value2 = POPA();
1509         jobject value1 = POPA();
1510         if (value1 == value2)
1511           TAKE_GOTO;
1512         else
1513           SKIP_GOTO;
1514       }
1515       NEXT_INSN;
1516
1517     insn_if_acmpne:
1518       {
1519         jobject value2 = POPA();
1520         jobject value1 = POPA();
1521         if (value1 != value2)
1522           TAKE_GOTO;
1523         else
1524           SKIP_GOTO;
1525       }
1526       NEXT_INSN;
1527
1528     insn_goto_w:
1529 #ifndef DIRECT_THREADED
1530       // For direct threaded, goto and goto_w are the same.
1531       pc = pc - 1 + get4 (pc);
1532       NEXT_INSN;
1533 #endif /* DIRECT_THREADED */
1534     insn_goto:
1535       TAKE_GOTO;
1536       NEXT_INSN;
1537
1538     insn_jsr_w:
1539 #ifndef DIRECT_THREADED
1540       // For direct threaded, jsr and jsr_w are the same.
1541       {
1542         pc_t next = pc - 1 + get4 (pc);
1543         pc += 4;
1544         PUSHA ((jobject) pc);
1545         pc = next;
1546       }
1547       NEXT_INSN;
1548 #endif /* DIRECT_THREADED */
1549     insn_jsr:
1550       {
1551         pc_t next = GOTO_VAL();
1552         SKIP_GOTO;
1553         PUSHA ((jobject) pc);
1554         pc = next;
1555       }
1556       NEXT_INSN;
1557
1558     insn_ret:
1559       {
1560         jint index = GET1U ();
1561         pc = (pc_t) PEEKA (index);
1562       }
1563       NEXT_INSN;
1564
1565     insn_tableswitch:
1566       {
1567 #ifdef DIRECT_THREADED
1568         void *def = (pc++)->datum;
1569
1570         int index = POPI();
1571
1572         jint low = INTVAL ();
1573         jint high = INTVAL ();
1574
1575         if (index < low || index > high)
1576           pc = (insn_slot *) def;
1577         else
1578           pc = (insn_slot *) ((pc + index - low)->datum);
1579 #else
1580         pc_t base_pc = pc - 1;
1581         int index = POPI ();
1582
1583         pc_t base = (pc_t) meth->bytecode ();
1584         while ((pc - base) % 4 != 0)
1585           ++pc;
1586
1587         jint def = get4 (pc);
1588         jint low = get4 (pc + 4);
1589         jint high = get4 (pc + 8);
1590         if (index < low || index > high)
1591           pc = base_pc + def;
1592         else
1593           pc = base_pc + get4 (pc + 4 * (index - low + 3));
1594 #endif /* DIRECT_THREADED */
1595       }
1596       NEXT_INSN;
1597
1598     insn_lookupswitch:
1599       {
1600 #ifdef DIRECT_THREADED
1601         void *def = (pc++)->insn;
1602
1603         int index = POPI();
1604
1605         jint npairs = INTVAL ();
1606
1607         int max = npairs - 1;
1608         int min = 0;
1609
1610         // Simple binary search...
1611         while (min < max)
1612           {
1613             int half = (min + max) / 2;
1614             int match = pc[2 * half].int_val;
1615
1616             if (index == match)
1617               {
1618                 // Found it.
1619                 pc = (insn_slot *) pc[2 * half + 1].datum;
1620                 NEXT_INSN;
1621               }
1622             else if (index < match)
1623               // We can use HALF - 1 here because we check again on
1624               // loop exit.
1625               max = half - 1;
1626             else
1627               // We can use HALF + 1 here because we check again on
1628               // loop exit.
1629               min = half + 1;
1630           }
1631         if (index == pc[2 * min].int_val)
1632           pc = (insn_slot *) pc[2 * min + 1].datum;
1633         else
1634           pc = (insn_slot *) def;
1635 #else
1636         unsigned char *base_pc = pc-1;
1637         int index = POPI();
1638
1639         unsigned char* base = meth->bytecode ();
1640         while ((pc-base) % 4 != 0)
1641           ++pc;
1642
1643         jint def     = get4 (pc);
1644         jint npairs  = get4 (pc+4);
1645
1646         int max = npairs-1;
1647         int min = 0;
1648
1649         // Simple binary search...
1650         while (min < max)
1651           {
1652             int half = (min+max)/2;
1653             int match = get4 (pc+ 4*(2 + 2*half));
1654
1655             if (index == match)
1656               min = max = half;
1657             else if (index < match)
1658               // We can use HALF - 1 here because we check again on
1659               // loop exit.
1660               max = half - 1;
1661             else
1662               // We can use HALF + 1 here because we check again on
1663               // loop exit.
1664               min = half + 1;
1665           }
1666
1667         if (index == get4 (pc+ 4*(2 + 2*min)))
1668           pc = base_pc + get4 (pc+ 4*(2 + 2*min + 1));
1669         else
1670           pc = base_pc + def;    
1671 #endif /* DIRECT_THREADED */
1672       }
1673       NEXT_INSN;
1674
1675     insn_areturn:
1676       *(jobject *) retp = POPA ();
1677       return;
1678
1679     insn_lreturn:
1680       *(jlong *) retp = POPL ();
1681       return;
1682
1683     insn_freturn:
1684       *(jfloat *) retp = POPF ();
1685       return;
1686
1687     insn_dreturn:
1688       *(jdouble *) retp = POPD ();
1689       return;
1690
1691     insn_ireturn:
1692       *(jint *) retp = POPI ();
1693       return;
1694
1695     insn_return:
1696       return;
1697
1698     insn_getstatic:
1699       {
1700         jint fieldref_index = GET2U ();
1701         SAVE_PC(); // Constant pool resolution could throw.
1702         _Jv_Linker::resolve_pool_entry (meth->defining_class, fieldref_index);
1703         _Jv_Field *field = pool_data[fieldref_index].field;
1704
1705         if ((field->flags & Modifier::STATIC) == 0)
1706           throw_incompatible_class_change_error 
1707             (JvNewStringLatin1 ("field no longer static"));
1708
1709         jclass type = field->type;
1710
1711         // We rewrite the instruction once we discover what it refers
1712         // to.
1713         void *newinsn = NULL;
1714         if (type->isPrimitive ())
1715           {
1716             switch (type->size_in_bytes)
1717               {
1718               case 1:
1719                 PUSHI (*field->u.byte_addr);
1720                 newinsn = AMPAMP (getstatic_resolved_1);
1721                 break;
1722
1723               case 2:
1724                 if (type == JvPrimClass (char))
1725                   {
1726                     PUSHI (*field->u.char_addr);
1727                     newinsn = AMPAMP (getstatic_resolved_char);
1728                   }
1729                 else
1730                   {
1731                     PUSHI (*field->u.short_addr);
1732                     newinsn = AMPAMP (getstatic_resolved_short);
1733                   }
1734                 break;
1735
1736               case 4:
1737                 PUSHI(*field->u.int_addr);
1738                 newinsn = AMPAMP (getstatic_resolved_4);
1739                 break;
1740
1741               case 8:
1742                 PUSHL(*field->u.long_addr);
1743                 newinsn = AMPAMP (getstatic_resolved_8);
1744                 break;
1745               }
1746           }
1747         else
1748           {
1749             PUSHA(*field->u.object_addr);
1750             newinsn = AMPAMP (getstatic_resolved_obj);
1751           }
1752
1753 #ifdef DIRECT_THREADED
1754         pc[-2].insn = newinsn;
1755         pc[-1].datum = field->u.addr;
1756 #endif /* DIRECT_THREADED */
1757       }
1758       NEXT_INSN;
1759
1760 #ifdef DIRECT_THREADED
1761     getstatic_resolved_1:
1762       PUSHI (*(jbyte *) AVAL ());
1763       NEXT_INSN;
1764
1765     getstatic_resolved_char:
1766       PUSHI (*(jchar *) AVAL ());
1767       NEXT_INSN;
1768
1769     getstatic_resolved_short:
1770       PUSHI (*(jshort *) AVAL ());
1771       NEXT_INSN;
1772
1773     getstatic_resolved_4:
1774       PUSHI (*(jint *) AVAL ());
1775       NEXT_INSN;
1776
1777     getstatic_resolved_8:
1778       PUSHL (*(jlong *) AVAL ());
1779       NEXT_INSN;
1780
1781     getstatic_resolved_obj:
1782       PUSHA (*(jobject *) AVAL ());
1783       NEXT_INSN;
1784 #endif /* DIRECT_THREADED */
1785
1786     insn_getfield:
1787       {
1788         SAVE_PC();
1789         jint fieldref_index = GET2U ();
1790         _Jv_Linker::resolve_pool_entry (meth->defining_class, fieldref_index);
1791         _Jv_Field *field = pool_data[fieldref_index].field;
1792
1793         if ((field->flags & Modifier::STATIC) != 0)
1794           throw_incompatible_class_change_error 
1795             (JvNewStringLatin1 ("field is static"));
1796
1797         jclass type = field->type;
1798         jint field_offset = field->u.boffset;
1799
1800         jobject obj   = POPA();
1801         NULLCHECK(obj);
1802
1803         void *newinsn = NULL;
1804         _Jv_value *val = (_Jv_value *) ((char *)obj + field_offset);
1805         if (type->isPrimitive ())
1806           {
1807             switch (type->size_in_bytes)
1808               {
1809               case 1:
1810                 PUSHI (val->byte_value);
1811                 newinsn = AMPAMP (getfield_resolved_1);
1812                 break;
1813
1814               case 2:
1815                 if (type == JvPrimClass (char))
1816                   {
1817                     PUSHI (val->char_value);
1818                     newinsn = AMPAMP (getfield_resolved_char);
1819                   }
1820                 else
1821                   {
1822                     PUSHI (val->short_value);
1823                     newinsn = AMPAMP (getfield_resolved_short);
1824                   }
1825                 break;
1826
1827               case 4:
1828                 PUSHI (val->int_value);
1829                 newinsn = AMPAMP (getfield_resolved_4);
1830                 break;
1831
1832               case 8:
1833                 PUSHL (val->long_value);
1834                 newinsn = AMPAMP (getfield_resolved_8);
1835                 break;
1836               }
1837           }
1838         else
1839           {
1840             PUSHA (val->object_value);
1841             newinsn = AMPAMP (getfield_resolved_obj);
1842           }
1843
1844 #ifdef DIRECT_THREADED
1845         pc[-2].insn = newinsn;
1846         pc[-1].int_val = field_offset;
1847 #endif /* DIRECT_THREADED */
1848       }
1849       NEXT_INSN;
1850
1851 #ifdef DIRECT_THREADED
1852     getfield_resolved_1:
1853       {
1854         char *obj = (char *) POPA ();
1855         NULLCHECK (obj);
1856         PUSHI (*(jbyte *) (obj + INTVAL ()));
1857       }
1858       NEXT_INSN;
1859
1860     getfield_resolved_char:
1861       {
1862         char *obj = (char *) POPA ();
1863         NULLCHECK (obj);
1864         PUSHI (*(jchar *) (obj + INTVAL ()));
1865       }
1866       NEXT_INSN;
1867
1868     getfield_resolved_short:
1869       {
1870         char *obj = (char *) POPA ();
1871         NULLCHECK (obj);
1872         PUSHI (*(jshort *) (obj + INTVAL ()));
1873       }
1874       NEXT_INSN;
1875
1876     getfield_resolved_4:
1877       {
1878         char *obj = (char *) POPA ();
1879         NULLCHECK (obj);
1880         PUSHI (*(jint *) (obj + INTVAL ()));
1881       }
1882       NEXT_INSN;
1883
1884     getfield_resolved_8:
1885       {
1886         char *obj = (char *) POPA ();
1887         NULLCHECK (obj);
1888         PUSHL (*(jlong *) (obj + INTVAL ()));
1889       }
1890       NEXT_INSN;
1891
1892     getfield_resolved_obj:
1893       {
1894         char *obj = (char *) POPA ();
1895         NULLCHECK (obj);
1896         PUSHA (*(jobject *) (obj + INTVAL ()));
1897       }
1898       NEXT_INSN;
1899 #endif /* DIRECT_THREADED */
1900
1901     insn_putstatic:
1902       {
1903         SAVE_PC();
1904         jint fieldref_index = GET2U ();
1905         _Jv_Linker::resolve_pool_entry (meth->defining_class, fieldref_index);
1906         _Jv_Field *field = pool_data[fieldref_index].field;
1907
1908         jclass type = field->type;
1909
1910         // ResolvePoolEntry cannot check this
1911         if ((field->flags & Modifier::STATIC) == 0)
1912           throw_incompatible_class_change_error 
1913             (JvNewStringLatin1 ("field no longer static"));
1914
1915         void *newinsn = NULL;
1916         if (type->isPrimitive ())
1917           {
1918             switch (type->size_in_bytes) 
1919               {
1920               case 1:
1921                 {
1922                   jint value = POPI();
1923                   *field->u.byte_addr = value;
1924                   newinsn = AMPAMP (putstatic_resolved_1);
1925                   break;
1926                 }
1927
1928               case 2:
1929                 {
1930                   jint value = POPI();
1931                   *field->u.char_addr = value;
1932                   newinsn = AMPAMP (putstatic_resolved_2);
1933                   break;
1934                 }
1935
1936               case 4:
1937                 {
1938                   jint value = POPI();
1939                   *field->u.int_addr = value;
1940                   newinsn = AMPAMP (putstatic_resolved_4);
1941                   break;
1942                 }
1943
1944               case 8:
1945                 {
1946                   jlong value = POPL();
1947                   *field->u.long_addr = value;
1948                   newinsn = AMPAMP (putstatic_resolved_8);
1949                   break;
1950                 }
1951               }
1952           }
1953         else
1954           {
1955             jobject value = POPA();
1956             *field->u.object_addr = value;
1957             newinsn = AMPAMP (putstatic_resolved_obj);
1958           }
1959
1960 #ifdef DIRECT_THREADED
1961         pc[-2].insn = newinsn;
1962         pc[-1].datum = field->u.addr;
1963 #endif /* DIRECT_THREADED */
1964       }
1965       NEXT_INSN;
1966
1967 #ifdef DIRECT_THREADED
1968     putstatic_resolved_1:
1969       *(jbyte *) AVAL () = POPI ();
1970       NEXT_INSN;
1971
1972     putstatic_resolved_2:
1973       *(jchar *) AVAL () = POPI ();
1974       NEXT_INSN;
1975
1976     putstatic_resolved_4:
1977       *(jint *) AVAL () = POPI ();
1978       NEXT_INSN;
1979
1980     putstatic_resolved_8:
1981       *(jlong *) AVAL () = POPL ();
1982       NEXT_INSN;
1983
1984     putstatic_resolved_obj:
1985       *(jobject *) AVAL () = POPA ();
1986       NEXT_INSN;
1987 #endif /* DIRECT_THREADED */
1988
1989     insn_putfield:
1990       {
1991         SAVE_PC();
1992         jint fieldref_index = GET2U ();
1993         _Jv_Linker::resolve_pool_entry (meth->defining_class, fieldref_index);
1994         _Jv_Field *field = pool_data[fieldref_index].field;
1995
1996         jclass type = field->type;
1997
1998         if ((field->flags & Modifier::STATIC) != 0)
1999           throw_incompatible_class_change_error 
2000             (JvNewStringLatin1 ("field is static"));
2001
2002         jint field_offset = field->u.boffset;
2003
2004         void *newinsn = NULL;
2005         if (type->isPrimitive ())
2006           {
2007             switch (type->size_in_bytes) 
2008               {
2009               case 1:
2010                 {
2011                   jint    value = POPI();
2012                   jobject obj   = POPA();
2013                   NULLCHECK(obj);
2014                   *(jbyte*) ((char*)obj + field_offset) = value;
2015                   newinsn = AMPAMP (putfield_resolved_1);
2016                   break;
2017                 }
2018
2019               case 2:
2020                 {
2021                   jint    value = POPI();
2022                   jobject obj   = POPA();
2023                   NULLCHECK(obj);
2024                   *(jchar*) ((char*)obj + field_offset) = value;
2025                   newinsn = AMPAMP (putfield_resolved_2);
2026                   break;
2027                 }
2028
2029               case 4:
2030                 {
2031                   jint    value = POPI();
2032                   jobject obj   = POPA();
2033                   NULLCHECK(obj);
2034                   *(jint*) ((char*)obj + field_offset) = value;
2035                   newinsn = AMPAMP (putfield_resolved_4);
2036                   break;
2037                 }
2038
2039               case 8:
2040                 {
2041                   jlong   value = POPL();
2042                   jobject obj   = POPA();
2043                   NULLCHECK(obj);
2044                   *(jlong*) ((char*)obj + field_offset) = value;
2045                   newinsn = AMPAMP (putfield_resolved_8);
2046                   break;
2047                 }
2048               }
2049           }
2050         else
2051           {
2052             jobject value = POPA();
2053             jobject obj   = POPA();
2054             NULLCHECK(obj);
2055             *(jobject*) ((char*)obj + field_offset) = value;
2056             newinsn = AMPAMP (putfield_resolved_obj);
2057           }
2058
2059 #ifdef DIRECT_THREADED
2060         pc[-2].insn = newinsn;
2061         pc[-1].int_val = field_offset;
2062 #endif /* DIRECT_THREADED */
2063       }
2064       NEXT_INSN;
2065
2066 #ifdef DIRECT_THREADED
2067     putfield_resolved_1:
2068       {
2069         jint val = POPI ();
2070         char *obj = (char *) POPA ();
2071         NULLCHECK (obj);
2072         *(jbyte *) (obj + INTVAL ()) = val;
2073       }
2074       NEXT_INSN;
2075
2076     putfield_resolved_2:
2077       {
2078         jint val = POPI ();
2079         char *obj = (char *) POPA ();
2080         NULLCHECK (obj);
2081         *(jchar *) (obj + INTVAL ()) = val;
2082       }
2083       NEXT_INSN;
2084
2085     putfield_resolved_4:
2086       {
2087         jint val = POPI ();
2088         char *obj = (char *) POPA ();
2089         NULLCHECK (obj);
2090         *(jint *) (obj + INTVAL ()) = val;
2091       }
2092       NEXT_INSN;
2093
2094     putfield_resolved_8:
2095       {
2096         jlong val = POPL ();
2097         char *obj = (char *) POPA ();
2098         NULLCHECK (obj);
2099         *(jlong *) (obj + INTVAL ()) = val;
2100       }
2101       NEXT_INSN;
2102
2103     putfield_resolved_obj:
2104       {
2105         jobject val = POPA ();
2106         char *obj = (char *) POPA ();
2107         NULLCHECK (obj);
2108         *(jobject *) (obj + INTVAL ()) = val;
2109       }
2110       NEXT_INSN;
2111 #endif /* DIRECT_THREADED */
2112
2113     insn_invokespecial:
2114       {
2115         SAVE_PC();
2116         int index = GET2U ();
2117
2118         rmeth = (_Jv_Linker::resolve_pool_entry (meth->defining_class,
2119                                                    index)).rmethod;
2120
2121         sp -= rmeth->stack_item_count;
2122
2123         // We don't use NULLCHECK here because we can't rely on that
2124         // working for <init>.  So instead we do an explicit test.
2125         if (! sp[0].o)
2126           {
2127             SAVE_PC();
2128             throw_null_pointer_exception ();
2129           }
2130
2131         fun = (void (*)()) rmeth->method->ncode;
2132
2133 #ifdef DIRECT_THREADED
2134         // Rewrite instruction so that we use a faster pre-resolved
2135         // method.
2136         pc[-2].insn = &&invokespecial_resolved;
2137         pc[-1].datum = rmeth;
2138 #endif /* DIRECT_THREADED */
2139       }
2140       goto perform_invoke;
2141
2142 #ifdef DIRECT_THREADED
2143     invokespecial_resolved:
2144       {
2145         SAVE_PC();
2146         rmeth = (_Jv_ResolvedMethod *) AVAL ();
2147         sp -= rmeth->stack_item_count;
2148         // We don't use NULLCHECK here because we can't rely on that
2149         // working for <init>.  So instead we do an explicit test.
2150         if (! sp[0].o)
2151           {
2152             throw_null_pointer_exception ();
2153           }
2154         fun = (void (*)()) rmeth->method->ncode;
2155       }
2156       goto perform_invoke;
2157 #endif /* DIRECT_THREADED */
2158
2159     insn_invokestatic:
2160       {
2161         SAVE_PC();
2162         int index = GET2U ();
2163
2164         rmeth = (_Jv_Linker::resolve_pool_entry (meth->defining_class,
2165                                                    index)).rmethod;
2166
2167         sp -= rmeth->stack_item_count;
2168
2169         fun = (void (*)()) rmeth->method->ncode;
2170
2171 #ifdef DIRECT_THREADED
2172         // Rewrite instruction so that we use a faster pre-resolved
2173         // method.
2174         pc[-2].insn = &&invokestatic_resolved;
2175         pc[-1].datum = rmeth;
2176 #endif /* DIRECT_THREADED */
2177       }
2178       goto perform_invoke;
2179
2180 #ifdef DIRECT_THREADED
2181     invokestatic_resolved:
2182       {
2183         SAVE_PC();
2184         rmeth = (_Jv_ResolvedMethod *) AVAL ();
2185         sp -= rmeth->stack_item_count;
2186         fun = (void (*)()) rmeth->method->ncode;
2187       }
2188       goto perform_invoke;
2189 #endif /* DIRECT_THREADED */
2190
2191     insn_invokeinterface:
2192       {
2193         SAVE_PC();
2194         int index = GET2U ();
2195
2196         rmeth = (_Jv_Linker::resolve_pool_entry (meth->defining_class,
2197                                                    index)).rmethod;
2198
2199         sp -= rmeth->stack_item_count;
2200
2201         jobject rcv = sp[0].o;
2202
2203         NULLCHECK (rcv);
2204
2205         fun = (void (*)())
2206           _Jv_LookupInterfaceMethod (rcv->getClass (),
2207                                      rmeth->method->name,
2208                                      rmeth->method->signature);
2209
2210 #ifdef DIRECT_THREADED
2211         // Rewrite instruction so that we use a faster pre-resolved
2212         // method.
2213         pc[-2].insn = &&invokeinterface_resolved;
2214         pc[-1].datum = rmeth;
2215 #else
2216         // Skip dummy bytes.
2217         pc += 2;
2218 #endif /* DIRECT_THREADED */
2219       }
2220       goto perform_invoke;
2221
2222 #ifdef DIRECT_THREADED
2223     invokeinterface_resolved:
2224       {
2225         SAVE_PC();
2226         rmeth = (_Jv_ResolvedMethod *) AVAL ();
2227         sp -= rmeth->stack_item_count;
2228         jobject rcv = sp[0].o;
2229         NULLCHECK (rcv);
2230         fun = (void (*)())
2231           _Jv_LookupInterfaceMethod (rcv->getClass (),
2232                                      rmeth->method->name,
2233                                      rmeth->method->signature);
2234       }
2235       goto perform_invoke;
2236 #endif /* DIRECT_THREADED */
2237
2238     insn_new:
2239       {
2240         SAVE_PC();
2241         int index = GET2U ();
2242         jclass klass = (_Jv_Linker::resolve_pool_entry (meth->defining_class,
2243                                                           index)).clazz;
2244         /* VM spec, section 3.11.5 */
2245         if ((klass->getModifiers() & Modifier::ABSTRACT)
2246             || klass->isInterface())
2247           throw new java::lang::InstantiationException;
2248         jobject res = _Jv_AllocObject (klass);
2249         PUSHA (res);
2250
2251 #ifdef DIRECT_THREADED
2252         pc[-2].insn = &&new_resolved;
2253         pc[-1].datum = klass;
2254 #endif /* DIRECT_THREADED */
2255       }
2256       NEXT_INSN;
2257
2258 #ifdef DIRECT_THREADED
2259     new_resolved:
2260       {
2261         jclass klass = (jclass) AVAL ();
2262         jobject res = _Jv_AllocObject (klass);
2263         PUSHA (res);
2264       }
2265       NEXT_INSN;
2266 #endif /* DIRECT_THREADED */
2267
2268     insn_newarray:
2269       {
2270         int atype = GET1U ();
2271         int size  = POPI();
2272         jobject result = _Jv_NewArray (atype, size);
2273         PUSHA (result);
2274       }
2275       NEXT_INSN;
2276
2277     insn_anewarray:
2278       {
2279         SAVE_PC();
2280         int index = GET2U ();
2281         jclass klass = (_Jv_Linker::resolve_pool_entry (meth->defining_class,
2282                                                           index)).clazz;
2283         int size  = POPI();
2284         jobject result = _Jv_NewObjectArray (size, klass, 0);
2285         PUSHA (result);
2286
2287 #ifdef DIRECT_THREADED
2288         pc[-2].insn = &&anewarray_resolved;
2289         pc[-1].datum = klass;
2290 #endif /* DIRECT_THREADED */
2291       }
2292       NEXT_INSN;
2293
2294 #ifdef DIRECT_THREADED
2295     anewarray_resolved:
2296       {
2297         jclass klass = (jclass) AVAL ();
2298         int size = POPI ();
2299         jobject result = _Jv_NewObjectArray (size, klass, 0);
2300         PUSHA (result);
2301       }
2302       NEXT_INSN;
2303 #endif /* DIRECT_THREADED */
2304
2305     insn_arraylength:
2306       {
2307         __JArray *arr = (__JArray*)POPA();
2308         NULLARRAYCHECK (arr);
2309         PUSHI (arr->length);
2310       }
2311       NEXT_INSN;
2312
2313     insn_athrow:
2314       {
2315         jobject value = POPA();
2316         throw static_cast<jthrowable>(value);
2317       }
2318       NEXT_INSN;
2319
2320     insn_checkcast:
2321       {
2322         SAVE_PC();
2323         jobject value = POPA();
2324         jint index = GET2U ();
2325         jclass to = (_Jv_Linker::resolve_pool_entry (meth->defining_class,
2326                                                        index)).clazz;
2327
2328         value = (jobject) _Jv_CheckCast (to, value);
2329
2330         PUSHA (value);
2331
2332 #ifdef DIRECT_THREADED
2333         pc[-2].insn = &&checkcast_resolved;
2334         pc[-1].datum = to;
2335 #endif /* DIRECT_THREADED */
2336       }
2337       NEXT_INSN;
2338
2339 #ifdef DIRECT_THREADED
2340     checkcast_resolved:
2341       {
2342         SAVE_PC();
2343         jobject value = POPA ();
2344         jclass to = (jclass) AVAL ();
2345         value = (jobject) _Jv_CheckCast (to, value);
2346         PUSHA (value);
2347       }
2348       NEXT_INSN;
2349 #endif /* DIRECT_THREADED */
2350
2351     insn_instanceof:
2352       {
2353         SAVE_PC();
2354         jobject value = POPA();
2355         jint index = GET2U ();
2356         jclass to = (_Jv_Linker::resolve_pool_entry (meth->defining_class,
2357                                                        index)).clazz;
2358         PUSHI (to->isInstance (value));
2359
2360 #ifdef DIRECT_THREADED
2361         pc[-2].insn = &&instanceof_resolved;
2362         pc[-1].datum = to;
2363 #endif /* DIRECT_THREADED */
2364       }
2365       NEXT_INSN;
2366
2367 #ifdef DIRECT_THREADED
2368     instanceof_resolved:
2369       {
2370         jobject value = POPA ();
2371         jclass to = (jclass) AVAL ();
2372         PUSHI (to->isInstance (value));
2373       }
2374       NEXT_INSN;
2375 #endif /* DIRECT_THREADED */
2376
2377     insn_monitorenter:
2378       {
2379         jobject value = POPA();
2380         NULLCHECK(value);
2381         _Jv_MonitorEnter (value);
2382       }
2383       NEXT_INSN;
2384
2385     insn_monitorexit:
2386       {
2387         jobject value = POPA();
2388         NULLCHECK(value);
2389         _Jv_MonitorExit (value);
2390       }
2391       NEXT_INSN;
2392
2393     insn_ifnull:
2394       {
2395         jobject val = POPA();
2396         if (val == NULL)
2397           TAKE_GOTO;
2398         else
2399           SKIP_GOTO;
2400       }
2401       NEXT_INSN;
2402
2403     insn_ifnonnull:
2404       {
2405         jobject val = POPA();
2406         if (val != NULL)
2407           TAKE_GOTO;
2408         else
2409           SKIP_GOTO;
2410       }
2411       NEXT_INSN;
2412
2413     insn_multianewarray:
2414       {
2415         SAVE_PC();
2416         int kind_index = GET2U ();
2417         int dim        = GET1U ();
2418
2419         jclass type    
2420           = (_Jv_Linker::resolve_pool_entry (meth->defining_class,
2421                                                kind_index)).clazz;
2422         jint *sizes    = (jint*) __builtin_alloca (sizeof (jint)*dim);
2423
2424         for (int i = dim - 1; i >= 0; i--)
2425           {
2426             sizes[i] = POPI ();
2427           }
2428
2429         jobject res    = _Jv_NewMultiArray (type,dim, sizes);
2430
2431         PUSHA (res);
2432       }
2433       NEXT_INSN;
2434
2435 #ifndef DIRECT_THREADED
2436     insn_wide:
2437       {
2438         jint the_mod_op = get1u (pc++);
2439         jint wide       = get2u (pc); pc += 2;
2440
2441         switch (the_mod_op)
2442           {
2443           case op_istore:
2444             STOREI (wide);
2445             NEXT_INSN;
2446
2447           case op_fstore:
2448             STOREF (wide);
2449             NEXT_INSN;
2450
2451           case op_astore:
2452             STOREA (wide);
2453             NEXT_INSN;
2454
2455           case op_lload:
2456             LOADL (wide);
2457             NEXT_INSN;
2458
2459           case op_dload:
2460             LOADD (wide);
2461             NEXT_INSN;
2462
2463           case op_iload:
2464             LOADI (wide);
2465             NEXT_INSN;
2466
2467           case op_fload:
2468             LOADF (wide);
2469             NEXT_INSN;
2470
2471           case op_aload:
2472             LOADA (wide);
2473             NEXT_INSN;
2474
2475           case op_lstore:
2476             STOREL (wide);
2477             NEXT_INSN;
2478
2479           case op_dstore:
2480             STORED (wide);
2481             NEXT_INSN;
2482
2483           case op_ret:
2484             pc = (unsigned char*) PEEKA (wide);
2485             NEXT_INSN;
2486
2487           case op_iinc:
2488             {
2489               jint amount = get2s (pc); pc += 2;
2490               jint value = PEEKI (wide);
2491               POKEI (wide, value+amount);
2492             }
2493             NEXT_INSN;
2494
2495           default:
2496             throw_internal_error ("illegal bytecode modified by wide");
2497           }
2498
2499       }
2500 #endif /* DIRECT_THREADED */
2501
2502     insn_breakpoint:
2503       {
2504         JvAssert (JVMTI_REQUESTED_EVENT (Breakpoint));
2505
2506         // Send JVMTI notification
2507         using namespace ::java::lang;
2508         jmethodID method = meth->self;
2509         jlocation location = meth->insn_index (pc - 1);
2510         Thread *thread = Thread::currentThread ();
2511         JNIEnv *jni_env = _Jv_GetCurrentJNIEnv ();
2512
2513         _Jv_JVMTI_PostEvent (JVMTI_EVENT_BREAKPOINT, thread, jni_env,
2514                              method, location);
2515
2516         // Continue execution
2517         using namespace gnu::gcj::jvmti;
2518         Breakpoint *bp
2519           = BreakpointManager::getBreakpoint (reinterpret_cast<jlong> (method),
2520                                               location);
2521         JvAssert (bp != NULL);
2522
2523         pc_t opc = reinterpret_cast<pc_t> (bp->getInsn ());
2524
2525 #ifdef DIRECT_THREADED
2526         goto *(opc->insn);
2527 #else
2528         goto *(insn_target[*opc]);
2529 #endif
2530       }
2531     }
2532   catch (java::lang::Throwable *ex)
2533     {
2534 #ifdef DIRECT_THREADED
2535       void *logical_pc = (void *) ((insn_slot *) pc - 1);
2536 #else
2537       int logical_pc = pc - 1 - meth->bytecode ();
2538 #endif
2539       _Jv_InterpException *exc = meth->exceptions ();
2540       jclass exc_class = ex->getClass ();
2541
2542       for (int i = 0; i < meth->exc_count; i++)
2543         {
2544           if (PCVAL (exc[i].start_pc) <= logical_pc
2545               && logical_pc < PCVAL (exc[i].end_pc))
2546             {
2547 #ifdef DIRECT_THREADED
2548               jclass handler = (jclass) exc[i].handler_type.p;
2549 #else
2550               jclass handler = NULL;
2551               if (exc[i].handler_type.i != 0)
2552                 handler = (_Jv_Linker::resolve_pool_entry (meth->defining_class,
2553                                                            exc[i].handler_type.i)).clazz;
2554 #endif /* DIRECT_THREADED */
2555
2556               if (handler == NULL || handler->isAssignableFrom (exc_class))
2557                 {
2558
2559 #ifdef DIRECT_THREADED
2560                   pc = (insn_slot *) exc[i].handler_pc.p;
2561 #else
2562                   pc = meth->bytecode () + exc[i].handler_pc.i;
2563 #endif /* DIRECT_THREADED */
2564                   sp = stack;
2565                   sp++->o = ex; // Push exception.
2566                   NEXT_INSN;
2567                 }
2568             }
2569         }
2570
2571       // No handler, so re-throw.
2572       throw ex;
2573     }