OSDN Git Service

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