OSDN Git Service

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