OSDN Git Service

* passes.c (rest_of_handle_jump): Remove dead code.
[pf3gnuchains/gcc-fork.git] / libjava / interpret.cc
1 // interpret.cc - Code for the interpreter
2
3 /* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 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 /* Author: Kresten Krab Thorup <krab@gnu.org>  */
12
13 #include <config.h>
14
15 // Define this to get the direct-threaded interpreter.  If undefined,
16 // we revert to a basic bytecode interpreter.  The former is faster
17 // but uses more memory.
18 #define DIRECT_THREADED
19
20 #pragma implementation "java-interp.h"
21
22 #include <jvm.h>
23 #include <java-cpool.h>
24 #include <java-interp.h>
25 #include <java/lang/System.h>
26 #include <java/lang/String.h>
27 #include <java/lang/Integer.h>
28 #include <java/lang/Long.h>
29 #include <java/lang/StringBuffer.h>
30 #include <java/lang/Class.h>
31 #include <java/lang/reflect/Modifier.h>
32 #include <java/lang/ClassCastException.h>
33 #include <java/lang/VirtualMachineError.h>
34 #include <java/lang/InternalError.h>
35 #include <java/lang/NullPointerException.h>
36 #include <java/lang/ArithmeticException.h>
37 #include <java/lang/IncompatibleClassChangeError.h>
38 #include <java/lang/Thread.h>
39 #include <java-insns.h>
40 #include <java-signal.h>
41
42 #ifdef INTERPRETER
43
44 #include <stdlib.h>
45
46 using namespace gcj;
47
48 static void throw_internal_error (char *msg)
49   __attribute__ ((__noreturn__));
50 static void throw_incompatible_class_change_error (jstring msg)
51   __attribute__ ((__noreturn__));
52 #ifndef HANDLE_SEGV
53 static void throw_null_pointer_exception ()
54   __attribute__ ((__noreturn__));
55 #endif
56
57 #ifdef DIRECT_THREADED
58 // Lock to ensure that methods are not compiled concurrently.
59 // We could use a finer-grained lock here, however it is not safe to use
60 // the Class monitor as user code in another thread could hold it.
61 static _Jv_Mutex_t compile_mutex;
62
63 void
64 _Jv_InitInterpreter()
65 {
66   _Jv_MutexInit (&compile_mutex);
67 }
68 #else
69 void _Jv_InitInterpreter() {}
70 #endif
71
72 extern "C" double __ieee754_fmod (double,double);
73
74 // This represents a single slot in the "compiled" form of the
75 // bytecode.
76 union insn_slot
77 {
78   // Address of code.
79   void *insn;
80   // An integer value used by an instruction.
81   jint int_val;
82   // A pointer value used by an instruction.
83   void *datum;
84 };
85
86 // The type of the PC depends on whether we're doing direct threading
87 // or a more ordinary bytecode interpreter.
88 #ifdef DIRECT_THREADED
89 typedef insn_slot *pc_t;
90 #else
91 typedef unsigned char *pc_t;
92 #endif
93
94 static inline void dupx (_Jv_word *sp, int n, int x)
95 {
96   // first "slide" n+x elements n to the right
97   int top = n-1;
98   for (int i = 0; i < n+x; i++)
99     {
100       sp[(top-i)] = sp[(top-i)-n];
101     }
102   
103   // next, copy the n top elements, n+x down
104   for (int i = 0; i < n; i++)
105     {
106       sp[top-(n+x)-i] = sp[top-i];
107     }
108   
109 }
110
111 // Used to convert from floating types to integral types.
112 template<typename TO, typename FROM>
113 static inline TO
114 convert (FROM val, TO min, TO max)
115 {
116   TO ret;
117   if (val >= (FROM) max)
118     ret = max;
119   else if (val <= (FROM) min)
120     ret = min;
121   else if (val != val)
122     ret = 0;
123   else
124     ret = (TO) val;
125   return ret;
126 }
127
128 #define PUSHA(V)  (sp++)->o = (V)
129 #define PUSHI(V)  (sp++)->i = (V)
130 #define PUSHF(V)  (sp++)->f = (V)
131 #if SIZEOF_VOID_P == 8
132 # define PUSHL(V)   (sp->l = (V), sp += 2)
133 # define PUSHD(V)   (sp->d = (V), sp += 2)
134 #else
135 # define PUSHL(V)  do { _Jv_word2 w2; w2.l=(V); \
136                         (sp++)->ia[0] = w2.ia[0]; \
137                         (sp++)->ia[0] = w2.ia[1]; } while (0)
138 # define PUSHD(V)  do { _Jv_word2 w2; w2.d=(V); \
139                         (sp++)->ia[0] = w2.ia[0]; \
140                         (sp++)->ia[0] = w2.ia[1]; } while (0)
141 #endif
142
143 #define POPA()    ((--sp)->o)
144 #define POPI()    ((jint) (--sp)->i) // cast since it may be promoted
145 #define POPF()    ((jfloat) (--sp)->f)
146 #if SIZEOF_VOID_P == 8
147 # define POPL()   (sp -= 2, (jlong) sp->l)
148 # define POPD()   (sp -= 2, (jdouble) sp->d)
149 #else
150 # define POPL()    ({ _Jv_word2 w2; \
151                      w2.ia[1] = (--sp)->ia[0]; \
152                      w2.ia[0] = (--sp)->ia[0]; w2.l; })
153 # define POPD()    ({ _Jv_word2 w2; \
154                      w2.ia[1] = (--sp)->ia[0]; \
155                      w2.ia[0] = (--sp)->ia[0]; w2.d; })
156 #endif
157
158 #define LOADA(I)  (sp++)->o = locals[I].o
159 #define LOADI(I)  (sp++)->i = locals[I].i
160 #define LOADF(I)  (sp++)->f = locals[I].f
161 #if SIZEOF_VOID_P == 8
162 # define LOADL(I)  (sp->l = locals[I].l, sp += 2)
163 # define LOADD(I)  (sp->d = locals[I].d, sp += 2)
164 #else
165 # define LOADL(I)  do { jint __idx = (I); \
166                         (sp++)->ia[0] = locals[__idx].ia[0]; \
167                         (sp++)->ia[0] = locals[__idx+1].ia[0]; \
168                    } while (0)
169 # define LOADD(I)  LOADL(I)
170 #endif
171
172 #define STOREA(I) locals[I].o = (--sp)->o
173 #define STOREI(I) locals[I].i = (--sp)->i
174 #define STOREF(I) locals[I].f = (--sp)->f
175 #if SIZEOF_VOID_P == 8
176 # define STOREL(I) (sp -= 2, locals[I].l = sp->l)
177 # define STORED(I) (sp -= 2, locals[I].d = sp->d)
178 #else
179 # define STOREL(I) do { jint __idx = (I); \
180                        locals[__idx+1].ia[0] = (--sp)->ia[0]; \
181                        locals[__idx].ia[0] = (--sp)->ia[0]; \
182                    } while (0)
183 # define STORED(I) STOREL(I)
184 #endif
185
186 #define PEEKI(I)  (locals+(I))->i
187 #define PEEKA(I)  (locals+(I))->o
188
189 #define POKEI(I,V)  ((locals+(I))->i = (V))
190
191
192 #define BINOPI(OP) { \
193    jint value2 = POPI(); \
194    jint value1 = POPI(); \
195    PUSHI(value1 OP value2); \
196 }
197
198 #define BINOPF(OP) { \
199    jfloat value2 = POPF(); \
200    jfloat value1 = POPF(); \
201    PUSHF(value1 OP value2); \
202 }
203
204 #define BINOPL(OP) { \
205    jlong value2 = POPL(); \
206    jlong value1 = POPL(); \
207    PUSHL(value1 OP value2); \
208 }
209
210 #define BINOPD(OP) { \
211    jdouble value2 = POPD(); \
212    jdouble value1 = POPD(); \
213    PUSHD(value1 OP value2); \
214 }
215
216 static inline jint get1s(unsigned char* loc) {
217   return *(signed char*)loc;
218 }
219
220 static inline jint get1u(unsigned char* loc) {
221   return *loc;
222 }
223
224 static inline jint get2s(unsigned char* loc) {
225   return (((jint)*(signed char*)loc) << 8) | ((jint)*(loc+1));
226 }
227
228 static inline jint get2u(unsigned char* loc) {
229   return (((jint)(*loc)) << 8) | ((jint)*(loc+1));
230 }
231
232 static jint get4(unsigned char* loc) {
233   return (((jint)(loc[0])) << 24) 
234        | (((jint)(loc[1])) << 16) 
235        | (((jint)(loc[2])) << 8) 
236        | (((jint)(loc[3])) << 0);
237 }
238
239
240 #ifdef HANDLE_SEGV
241 #define NULLCHECK(X) 
242 #define NULLARRAYCHECK(X)
243 #else
244 #define NULLCHECK(X) \
245   do { if ((X)==NULL) throw_null_pointer_exception (); } while (0)
246 #define NULLARRAYCHECK(X) \
247   do { if ((X)==NULL) { throw_null_pointer_exception (); } } while (0)
248 #endif
249
250 #define ARRAYBOUNDSCHECK(array, index)                                        \
251   do                                                                          \
252     {                                                                         \
253       if (((unsigned) index) >= (unsigned) (array->length))                   \
254         _Jv_ThrowBadArrayIndex (index);                                       \
255     }                                                                         \
256   while (0)
257
258 void
259 _Jv_InterpMethod::run_normal (ffi_cif *,
260                               void* ret,
261                               ffi_raw * args,
262                               void* __this)
263 {
264   _Jv_InterpMethod *_this = (_Jv_InterpMethod *) __this;
265   _this->run (ret, args);
266 }
267
268 void
269 _Jv_InterpMethod::run_synch_object (ffi_cif *,
270                                     void* ret,
271                                     ffi_raw * args,
272                                     void* __this)
273 {
274   _Jv_InterpMethod *_this = (_Jv_InterpMethod *) __this;
275
276   jobject rcv = (jobject) args[0].ptr;
277   JvSynchronize mutex (rcv);
278
279   _this->run (ret, args);
280 }
281
282 void
283 _Jv_InterpMethod::run_class (ffi_cif *,
284                              void* ret,
285                              ffi_raw * args,
286                              void* __this)
287 {
288   _Jv_InterpMethod *_this = (_Jv_InterpMethod *) __this;
289   _Jv_InitClass (_this->defining_class);
290   _this->run (ret, args);
291 }
292
293 void
294 _Jv_InterpMethod::run_synch_class (ffi_cif *,
295                                    void* ret,
296                                    ffi_raw * args,
297                                    void* __this)
298 {
299   _Jv_InterpMethod *_this = (_Jv_InterpMethod *) __this;
300
301   jclass sync = _this->defining_class;
302   _Jv_InitClass (sync);
303   JvSynchronize mutex (sync);
304
305   _this->run (ret, args);
306 }
307
308 #ifdef DIRECT_THREADED
309 // "Compile" a method by turning it from bytecode to direct-threaded
310 // code.
311 void
312 _Jv_InterpMethod::compile (const void * const *insn_targets)
313 {
314   insn_slot *insns = NULL;
315   int next = 0;
316   unsigned char *codestart = bytecode ();
317   unsigned char *end = codestart + code_length;
318   _Jv_word *pool_data = defining_class->constants.data;
319
320 #define SET_ONE(Field, Value)                                                 \
321   do                                                                          \
322     {                                                                         \
323       if (first_pass)                                                         \
324         ++next;                                                               \
325       else                                                                    \
326         insns[next++].Field = Value;                                          \
327     }                                                                         \
328   while (0)
329
330 #define SET_INSN(Value) SET_ONE (insn, (void *) Value)
331 #define SET_INT(Value) SET_ONE (int_val, Value)
332 #define SET_DATUM(Value) SET_ONE (datum, Value)
333
334   // Map from bytecode PC to slot in INSNS.
335   int *pc_mapping = (int *) __builtin_alloca (sizeof (int) * code_length);
336   for (int i = 0; i < code_length; ++i)
337     pc_mapping[i] = -1;
338
339   for (int i = 0; i < 2; ++i)
340     {
341       jboolean first_pass = i == 0;
342
343       if (! first_pass)
344         {
345           insns = (insn_slot *) _Jv_AllocBytes (sizeof (insn_slot) * next);
346           next = 0;
347         }
348
349       unsigned char *pc = codestart;
350       while (pc < end)
351         {
352           int base_pc_val = pc - codestart;
353           if (first_pass)
354             pc_mapping[base_pc_val] = next;
355
356           java_opcode opcode = (java_opcode) *pc++;
357           // Just elide NOPs.
358           if (opcode == op_nop)
359             continue;
360           SET_INSN (insn_targets[opcode]);
361
362           switch (opcode)
363             {
364             case op_nop:
365             case op_aconst_null:
366             case op_iconst_m1:
367             case op_iconst_0:
368             case op_iconst_1:
369             case op_iconst_2:
370             case op_iconst_3:
371             case op_iconst_4:
372             case op_iconst_5:
373             case op_lconst_0:
374             case op_lconst_1:
375             case op_fconst_0:
376             case op_fconst_1:
377             case op_fconst_2:
378             case op_dconst_0:
379             case op_dconst_1:
380             case op_iload_0:
381             case op_iload_1:
382             case op_iload_2:
383             case op_iload_3:
384             case op_lload_0:
385             case op_lload_1:
386             case op_lload_2:
387             case op_lload_3:
388             case op_fload_0:
389             case op_fload_1:
390             case op_fload_2:
391             case op_fload_3:
392             case op_dload_0:
393             case op_dload_1:
394             case op_dload_2:
395             case op_dload_3:
396             case op_aload_0:
397             case op_aload_1:
398             case op_aload_2:
399             case op_aload_3:
400             case op_iaload:
401             case op_laload:
402             case op_faload:
403             case op_daload:
404             case op_aaload:
405             case op_baload:
406             case op_caload:
407             case op_saload:
408             case op_istore_0:
409             case op_istore_1:
410             case op_istore_2:
411             case op_istore_3:
412             case op_lstore_0:
413             case op_lstore_1:
414             case op_lstore_2:
415             case op_lstore_3:
416             case op_fstore_0:
417             case op_fstore_1:
418             case op_fstore_2:
419             case op_fstore_3:
420             case op_dstore_0:
421             case op_dstore_1:
422             case op_dstore_2:
423             case op_dstore_3:
424             case op_astore_0:
425             case op_astore_1:
426             case op_astore_2:
427             case op_astore_3:
428             case op_iastore:
429             case op_lastore:
430             case op_fastore:
431             case op_dastore:
432             case op_aastore:
433             case op_bastore:
434             case op_castore:
435             case op_sastore:
436             case op_pop:
437             case op_pop2:
438             case op_dup:
439             case op_dup_x1:
440             case op_dup_x2:
441             case op_dup2:
442             case op_dup2_x1:
443             case op_dup2_x2:
444             case op_swap:
445             case op_iadd:
446             case op_isub:
447             case op_imul:
448             case op_idiv:
449             case op_irem:
450             case op_ishl:
451             case op_ishr:
452             case op_iushr:
453             case op_iand:
454             case op_ior:
455             case op_ixor:
456             case op_ladd:
457             case op_lsub:
458             case op_lmul:
459             case op_ldiv:
460             case op_lrem:
461             case op_lshl:
462             case op_lshr:
463             case op_lushr:
464             case op_land:
465             case op_lor:
466             case op_lxor:
467             case op_fadd:
468             case op_fsub:
469             case op_fmul:
470             case op_fdiv:
471             case op_frem:
472             case op_dadd:
473             case op_dsub:
474             case op_dmul:
475             case op_ddiv:
476             case op_drem:
477             case op_ineg:
478             case op_i2b:
479             case op_i2c:
480             case op_i2s:
481             case op_lneg:
482             case op_fneg:
483             case op_dneg:
484             case op_i2l:
485             case op_i2f:
486             case op_i2d:
487             case op_l2i:
488             case op_l2f:
489             case op_l2d:
490             case op_f2i:
491             case op_f2l:
492             case op_f2d:
493             case op_d2i:
494             case op_d2l:
495             case op_d2f:
496             case op_lcmp:
497             case op_fcmpl:
498             case op_fcmpg:
499             case op_dcmpl:
500             case op_dcmpg:
501             case op_monitorenter:
502             case op_monitorexit:
503             case op_ireturn:
504             case op_lreturn:
505             case op_freturn:
506             case op_dreturn:
507             case op_areturn:
508             case op_return:
509             case op_athrow:
510             case op_arraylength:
511               // No argument, nothing else to do.
512               break;
513
514             case op_bipush:
515               SET_INT (get1s (pc));
516               ++pc;
517               break;
518
519             case op_ldc:
520               {
521                 int index = get1u (pc);
522                 ++pc;
523                 SET_DATUM (pool_data[index].o);
524               }
525               break;
526
527             case op_ret:
528             case op_iload:
529             case op_lload:
530             case op_fload:
531             case op_dload:
532             case op_aload:
533             case op_istore:
534             case op_lstore:
535             case op_fstore:
536             case op_dstore:
537             case op_astore:
538             case op_newarray:
539               SET_INT (get1u (pc));
540               ++pc;
541               break;
542
543             case op_iinc:
544               SET_INT (get1u (pc));
545               SET_INT (get1s (pc + 1));
546               pc += 2;
547               break;
548
549             case op_ldc_w:
550               {
551                 int index = get2u (pc);
552                 pc += 2;
553                 SET_DATUM (pool_data[index].o);
554               }
555               break;
556
557             case op_ldc2_w:
558               {
559                 int index = get2u (pc);
560                 pc += 2;
561                 SET_DATUM (&pool_data[index]);
562               }
563               break;
564
565             case op_sipush:
566               SET_INT (get2s (pc));
567               pc += 2;
568               break;
569
570             case op_new:
571             case op_getstatic:
572             case op_getfield:
573             case op_putfield:
574             case op_putstatic:
575             case op_anewarray:
576             case op_instanceof:
577             case op_checkcast:
578             case op_invokespecial:
579             case op_invokestatic:
580             case op_invokevirtual:
581               SET_INT (get2u (pc));
582               pc += 2;
583               break;
584
585             case op_multianewarray:
586               SET_INT (get2u (pc));
587               SET_INT (get1u (pc + 2));
588               pc += 3;
589               break;
590
591             case op_jsr:
592             case op_ifeq:
593             case op_ifne:
594             case op_iflt:
595             case op_ifge:
596             case op_ifgt:
597             case op_ifle:
598             case op_if_icmpeq:
599             case op_if_icmpne:
600             case op_if_icmplt:
601             case op_if_icmpge:
602             case op_if_icmpgt:
603             case op_if_icmple:
604             case op_if_acmpeq:
605             case op_if_acmpne:
606             case op_ifnull:
607             case op_ifnonnull:
608             case op_goto:
609               {
610                 int offset = get2s (pc);
611                 pc += 2;
612
613                 int new_pc = base_pc_val + offset;
614
615                 bool orig_was_goto = opcode == op_goto;
616
617                 // Thread jumps.  We limit the loop count; this lets
618                 // us avoid infinite loops if the bytecode contains
619                 // such.  `10' is arbitrary.
620                 int count = 10;
621                 while (codestart[new_pc] == op_goto && count-- > 0)
622                   new_pc += get2s (&codestart[new_pc + 1]);
623
624                 // If the jump takes us to a `return' instruction and
625                 // the original branch was an unconditional goto, then
626                 // we hoist the return.
627                 opcode = (java_opcode) codestart[new_pc];
628                 if (orig_was_goto
629                     && (opcode == op_ireturn || opcode == op_lreturn
630                         || opcode == op_freturn || opcode == op_dreturn
631                         || opcode == op_areturn || opcode == op_return))
632                   {
633                     --next;
634                     SET_INSN (insn_targets[opcode]);
635                   }
636                 else
637                   SET_DATUM (&insns[pc_mapping[new_pc]]);
638               }
639               break;
640
641             case op_tableswitch:
642               {
643                 while ((pc - codestart) % 4 != 0)
644                   ++pc;
645
646                 jint def = get4 (pc);
647                 SET_DATUM (&insns[pc_mapping[base_pc_val + def]]);
648                 pc += 4;
649
650                 int low = get4 (pc);
651                 SET_INT (low);
652                 pc += 4;
653                 int high = get4 (pc);
654                 SET_INT (high);
655                 pc += 4;
656
657                 for (int i = low; i <= high; ++i)
658                   {
659                     SET_DATUM (&insns[pc_mapping[base_pc_val + get4 (pc)]]);
660                     pc += 4;
661                   }
662               }
663               break;
664
665             case op_lookupswitch:
666               {
667                 while ((pc - codestart) % 4 != 0)
668                   ++pc;
669
670                 jint def = get4 (pc);
671                 SET_DATUM (&insns[pc_mapping[base_pc_val + def]]);
672                 pc += 4;
673
674                 jint npairs = get4 (pc);
675                 pc += 4;
676                 SET_INT (npairs);
677
678                 while (npairs-- > 0)
679                   {
680                     jint match = get4 (pc);
681                     jint offset = get4 (pc + 4);
682                     SET_INT (match);
683                     SET_DATUM (&insns[pc_mapping[base_pc_val + offset]]);
684                     pc += 8;
685                   }
686               }
687               break;
688
689             case op_invokeinterface:
690               {
691                 jint index = get2u (pc);
692                 pc += 2;
693                 // We ignore the next two bytes.
694                 pc += 2;
695                 SET_INT (index);
696               }
697               break;
698
699             case op_wide:
700               {
701                 opcode = (java_opcode) get1u (pc);
702                 pc += 1;
703                 jint val = get2u (pc);
704                 pc += 2;
705
706                 // We implement narrow and wide instructions using the
707                 // same code in the interpreter.  So we rewrite the
708                 // instruction slot here.
709                 if (! first_pass)
710                   insns[next - 1].insn = (void *) insn_targets[opcode];
711                 SET_INT (val);
712
713                 if (opcode == op_iinc)
714                   {
715                     SET_INT (get2s (pc));
716                     pc += 2;
717                   }
718               }
719               break;
720
721             case op_jsr_w:
722             case op_goto_w:
723               {
724                 jint offset = get4 (pc);
725                 pc += 4;
726                 SET_DATUM (&insns[pc_mapping[base_pc_val + offset]]);
727               }
728               break;
729
730             // Some "can't happen" cases that we include for
731             // error-checking purposes.
732             case op_putfield_1:
733             case op_putfield_2:
734             case op_putfield_4:
735             case op_putfield_8:
736             case op_putfield_a:
737             case op_putstatic_1:
738             case op_putstatic_2:
739             case op_putstatic_4:
740             case op_putstatic_8:
741             case op_putstatic_a:
742             case op_getfield_1:
743             case op_getfield_2s:
744             case op_getfield_2u:
745             case op_getfield_4:
746             case op_getfield_8:
747             case op_getfield_a:
748             case op_getstatic_1:
749             case op_getstatic_2s:
750             case op_getstatic_2u:
751             case op_getstatic_4:
752             case op_getstatic_8:
753             case op_getstatic_a:
754             default:
755               // Fail somehow.
756               break;
757             }
758         }
759     }
760
761   // Now update exceptions.
762   _Jv_InterpException *exc = exceptions ();
763   for (int i = 0; i < exc_count; ++i)
764     {
765       exc[i].start_pc.p = &insns[pc_mapping[exc[i].start_pc.i]];
766       exc[i].end_pc.p = &insns[pc_mapping[exc[i].end_pc.i]];
767       exc[i].handler_pc.p = &insns[pc_mapping[exc[i].handler_pc.i]];
768       jclass handler = (_Jv_ResolvePoolEntry (defining_class,
769                                               exc[i].handler_type.i)).clazz;
770       exc[i].handler_type.p = handler;
771     }
772
773   prepared = insns;
774 }
775 #endif /* DIRECT_THREADED */
776
777 // These exist so that the stack-tracing code can find the boundaries
778 // of the interpreter.
779 void *_Jv_StartOfInterpreter;
780 void *_Jv_EndOfInterpreter;
781 extern "C" void *_Unwind_FindEnclosingFunction (void *pc);
782
783 void
784 _Jv_InterpMethod::run (void *retp, ffi_raw *args)
785 {
786   using namespace java::lang::reflect;
787
788   // Record the address of the start of this member function in
789   // _Jv_StartOfInterpreter.  Such a write to a global variable
790   // without acquiring a lock is correct iff reads and writes of words
791   // in memory are atomic, but Java requires that anyway.
792  foo:
793   if (_Jv_StartOfInterpreter == NULL)
794     _Jv_StartOfInterpreter = _Unwind_FindEnclosingFunction (&&foo);
795
796   // FRAME_DESC registers this particular invocation as the top-most
797   // interpreter frame.  This lets the stack tracing code (for
798   // Throwable) print information about the method being interpreted
799   // rather than about the interpreter itself.  FRAME_DESC has a
800   // destructor so it cleans up automatically when the interpreter
801   // returns.
802   java::lang::Thread *thread = java::lang::Thread::currentThread();
803   _Jv_MethodChain frame_desc (this,
804                               (_Jv_MethodChain **) &thread->interp_frame);
805
806   _Jv_word stack[max_stack];
807   _Jv_word *sp = stack;
808
809   _Jv_word locals[max_locals];
810
811   /* Go straight at it!  the ffi raw format matches the internal
812      stack representation exactly.  At least, that's the idea.
813   */
814   memcpy ((void*) locals, (void*) args, args_raw_size);
815
816   _Jv_word *pool_data = defining_class->constants.data;
817
818   /* These three are temporaries for common code used by several
819      instructions.  */
820   void (*fun)();
821   _Jv_ResolvedMethod* rmeth;
822   int tmpval;
823
824 #define INSN_LABEL(op) &&insn_##op
825
826   static const void *const insn_target[] = 
827   {
828     INSN_LABEL(nop),
829     INSN_LABEL(aconst_null),
830     INSN_LABEL(iconst_m1),
831     INSN_LABEL(iconst_0),
832     INSN_LABEL(iconst_1),
833     INSN_LABEL(iconst_2),
834     INSN_LABEL(iconst_3),
835     INSN_LABEL(iconst_4),
836     INSN_LABEL(iconst_5),
837     INSN_LABEL(lconst_0),
838     INSN_LABEL(lconst_1),
839     INSN_LABEL(fconst_0),
840     INSN_LABEL(fconst_1),
841     INSN_LABEL(fconst_2),
842     INSN_LABEL(dconst_0),
843     INSN_LABEL(dconst_1),
844     INSN_LABEL(bipush),
845     INSN_LABEL(sipush),
846     INSN_LABEL(ldc),
847     INSN_LABEL(ldc_w),
848     INSN_LABEL(ldc2_w),
849     INSN_LABEL(iload),
850     INSN_LABEL(lload),
851     INSN_LABEL(fload),
852     INSN_LABEL(dload),
853     INSN_LABEL(aload),
854     INSN_LABEL(iload_0),
855     INSN_LABEL(iload_1),
856     INSN_LABEL(iload_2),
857     INSN_LABEL(iload_3),
858     INSN_LABEL(lload_0),
859     INSN_LABEL(lload_1),
860     INSN_LABEL(lload_2),
861     INSN_LABEL(lload_3),
862     INSN_LABEL(fload_0),
863     INSN_LABEL(fload_1),
864     INSN_LABEL(fload_2),
865     INSN_LABEL(fload_3),
866     INSN_LABEL(dload_0),
867     INSN_LABEL(dload_1),
868     INSN_LABEL(dload_2),
869     INSN_LABEL(dload_3),
870     INSN_LABEL(aload_0),
871     INSN_LABEL(aload_1),
872     INSN_LABEL(aload_2),
873     INSN_LABEL(aload_3),
874     INSN_LABEL(iaload),
875     INSN_LABEL(laload),
876     INSN_LABEL(faload),
877     INSN_LABEL(daload),
878     INSN_LABEL(aaload),
879     INSN_LABEL(baload),
880     INSN_LABEL(caload),
881     INSN_LABEL(saload),
882     INSN_LABEL(istore),
883     INSN_LABEL(lstore),
884     INSN_LABEL(fstore),
885     INSN_LABEL(dstore),
886     INSN_LABEL(astore),
887     INSN_LABEL(istore_0),
888     INSN_LABEL(istore_1),
889     INSN_LABEL(istore_2),
890     INSN_LABEL(istore_3),
891     INSN_LABEL(lstore_0),
892     INSN_LABEL(lstore_1),
893     INSN_LABEL(lstore_2),
894     INSN_LABEL(lstore_3),
895     INSN_LABEL(fstore_0),
896     INSN_LABEL(fstore_1),
897     INSN_LABEL(fstore_2),
898     INSN_LABEL(fstore_3),
899     INSN_LABEL(dstore_0),
900     INSN_LABEL(dstore_1),
901     INSN_LABEL(dstore_2),
902     INSN_LABEL(dstore_3),
903     INSN_LABEL(astore_0),
904     INSN_LABEL(astore_1),
905     INSN_LABEL(astore_2),
906     INSN_LABEL(astore_3),
907     INSN_LABEL(iastore),
908     INSN_LABEL(lastore),
909     INSN_LABEL(fastore),
910     INSN_LABEL(dastore),
911     INSN_LABEL(aastore),
912     INSN_LABEL(bastore),
913     INSN_LABEL(castore),
914     INSN_LABEL(sastore),
915     INSN_LABEL(pop),
916     INSN_LABEL(pop2),
917     INSN_LABEL(dup),
918     INSN_LABEL(dup_x1),
919     INSN_LABEL(dup_x2),
920     INSN_LABEL(dup2),
921     INSN_LABEL(dup2_x1),
922     INSN_LABEL(dup2_x2),
923     INSN_LABEL(swap),
924     INSN_LABEL(iadd),
925     INSN_LABEL(ladd),
926     INSN_LABEL(fadd),
927     INSN_LABEL(dadd),
928     INSN_LABEL(isub),
929     INSN_LABEL(lsub),
930     INSN_LABEL(fsub),
931     INSN_LABEL(dsub),
932     INSN_LABEL(imul),
933     INSN_LABEL(lmul),
934     INSN_LABEL(fmul),
935     INSN_LABEL(dmul),
936     INSN_LABEL(idiv),
937     INSN_LABEL(ldiv),
938     INSN_LABEL(fdiv),
939     INSN_LABEL(ddiv),
940     INSN_LABEL(irem),
941     INSN_LABEL(lrem),
942     INSN_LABEL(frem),
943     INSN_LABEL(drem),
944     INSN_LABEL(ineg),
945     INSN_LABEL(lneg),
946     INSN_LABEL(fneg),
947     INSN_LABEL(dneg),
948     INSN_LABEL(ishl),
949     INSN_LABEL(lshl),
950     INSN_LABEL(ishr),
951     INSN_LABEL(lshr),
952     INSN_LABEL(iushr),
953     INSN_LABEL(lushr),
954     INSN_LABEL(iand),
955     INSN_LABEL(land),
956     INSN_LABEL(ior),
957     INSN_LABEL(lor),
958     INSN_LABEL(ixor),
959     INSN_LABEL(lxor),
960     INSN_LABEL(iinc),
961     INSN_LABEL(i2l),
962     INSN_LABEL(i2f),
963     INSN_LABEL(i2d),
964     INSN_LABEL(l2i),
965     INSN_LABEL(l2f),
966     INSN_LABEL(l2d),
967     INSN_LABEL(f2i),
968     INSN_LABEL(f2l),
969     INSN_LABEL(f2d),
970     INSN_LABEL(d2i),
971     INSN_LABEL(d2l),
972     INSN_LABEL(d2f),
973     INSN_LABEL(i2b),
974     INSN_LABEL(i2c),
975     INSN_LABEL(i2s),
976     INSN_LABEL(lcmp),
977     INSN_LABEL(fcmpl),
978     INSN_LABEL(fcmpg),
979     INSN_LABEL(dcmpl),
980     INSN_LABEL(dcmpg),
981     INSN_LABEL(ifeq),
982     INSN_LABEL(ifne),
983     INSN_LABEL(iflt),
984     INSN_LABEL(ifge),
985     INSN_LABEL(ifgt),
986     INSN_LABEL(ifle),
987     INSN_LABEL(if_icmpeq),
988     INSN_LABEL(if_icmpne),
989     INSN_LABEL(if_icmplt),
990     INSN_LABEL(if_icmpge),
991     INSN_LABEL(if_icmpgt),
992     INSN_LABEL(if_icmple),
993     INSN_LABEL(if_acmpeq),
994     INSN_LABEL(if_acmpne),
995     INSN_LABEL(goto), 
996     INSN_LABEL(jsr),
997     INSN_LABEL(ret),
998     INSN_LABEL(tableswitch),
999     INSN_LABEL(lookupswitch),
1000     INSN_LABEL(ireturn),
1001     INSN_LABEL(lreturn),
1002     INSN_LABEL(freturn),
1003     INSN_LABEL(dreturn),
1004     INSN_LABEL(areturn),
1005     INSN_LABEL(return),
1006     INSN_LABEL(getstatic),
1007     INSN_LABEL(putstatic),
1008     INSN_LABEL(getfield),
1009     INSN_LABEL(putfield),
1010     INSN_LABEL(invokevirtual),
1011     INSN_LABEL(invokespecial),
1012     INSN_LABEL(invokestatic),
1013     INSN_LABEL(invokeinterface),
1014     0, /* Unused.  */
1015     INSN_LABEL(new),
1016     INSN_LABEL(newarray),
1017     INSN_LABEL(anewarray),
1018     INSN_LABEL(arraylength),
1019     INSN_LABEL(athrow),
1020     INSN_LABEL(checkcast),
1021     INSN_LABEL(instanceof),
1022     INSN_LABEL(monitorenter),
1023     INSN_LABEL(monitorexit),
1024 #ifdef DIRECT_THREADED
1025     0, // wide
1026 #else
1027     INSN_LABEL(wide),
1028 #endif
1029     INSN_LABEL(multianewarray),
1030     INSN_LABEL(ifnull),
1031     INSN_LABEL(ifnonnull),
1032     INSN_LABEL(goto_w),
1033     INSN_LABEL(jsr_w),
1034     0
1035   };
1036
1037   pc_t pc;
1038
1039 #ifdef DIRECT_THREADED
1040
1041 #define NEXT_INSN goto *((pc++)->insn)
1042 #define INTVAL() ((pc++)->int_val)
1043 #define AVAL() ((pc++)->datum)
1044
1045 #define GET1S() INTVAL ()
1046 #define GET2S() INTVAL ()
1047 #define GET1U() INTVAL ()
1048 #define GET2U() INTVAL ()
1049 #define AVAL1U() AVAL ()
1050 #define AVAL2U() AVAL ()
1051 #define AVAL2UP() AVAL ()
1052 #define SKIP_GOTO ++pc
1053 #define GOTO_VAL() (insn_slot *) pc->datum
1054 #define PCVAL(unionval) unionval.p
1055 #define AMPAMP(label) &&label
1056
1057   // Compile if we must. NOTE: Double-check locking.
1058   if (prepared == NULL)
1059     {
1060       _Jv_MutexLock (&compile_mutex);
1061       if (prepared == NULL)
1062         compile (insn_target);
1063       _Jv_MutexUnlock (&compile_mutex);
1064     }
1065   pc = (insn_slot *) prepared;
1066
1067 #else
1068
1069 #define NEXT_INSN goto *(insn_target[*pc++])
1070
1071 #define GET1S() get1s (pc++)
1072 #define GET2S() (pc += 2, get2s (pc- 2))
1073 #define GET1U() get1u (pc++)
1074 #define GET2U() (pc += 2, get2u (pc - 2))
1075 #define AVAL1U() ({ int index = get1u (pc++); pool_data[index].o; })
1076 #define AVAL2U() ({ int index = get2u (pc); pc += 2; pool_data[index].o; })
1077 #define AVAL2UP() ({ int index = get2u (pc); pc += 2; &pool_data[index]; })
1078 #define SKIP_GOTO pc += 2
1079 #define GOTO_VAL() pc - 1 + get2s (pc)
1080 #define PCVAL(unionval) unionval.i
1081 #define AMPAMP(label) NULL
1082
1083   pc = bytecode ();
1084
1085 #endif /* DIRECT_THREADED */
1086
1087 #define TAKE_GOTO pc = GOTO_VAL ()
1088
1089   try
1090     {
1091       // We keep nop around.  It is used if we're interpreting the
1092       // bytecodes and not doing direct threading.
1093     insn_nop:
1094       NEXT_INSN;
1095
1096       /* The first few instructions here are ordered according to their
1097          frequency, in the hope that this will improve code locality a
1098          little.  */
1099
1100     insn_aload_0:               // 0x2a
1101       LOADA (0);
1102       NEXT_INSN;
1103
1104     insn_iload:         // 0x15
1105       LOADI (GET1U ());
1106       NEXT_INSN;
1107
1108     insn_iload_1:               // 0x1b
1109       LOADI (1);
1110       NEXT_INSN;
1111
1112     insn_invokevirtual: // 0xb6
1113       {
1114         int index = GET2U ();
1115
1116         /* _Jv_ResolvePoolEntry returns immediately if the value already
1117          * is resolved.  If we want to clutter up the code here to gain
1118          * a little performance, then we can check the corresponding bit
1119          * JV_CONSTANT_ResolvedFlag in the tag directly.  For now, I
1120          * don't think it is worth it.  */
1121
1122         rmeth = (_Jv_ResolvePoolEntry (defining_class, index)).rmethod;
1123
1124         sp -= rmeth->stack_item_count;
1125         // We don't use NULLCHECK here because we can't rely on that
1126         // working if the method is final.  So instead we do an
1127         // explicit test.
1128         if (! sp[0].o)
1129           throw new java::lang::NullPointerException;
1130
1131         if (rmeth->vtable_index == -1)
1132           {
1133             // final methods do not appear in the vtable,
1134             // if it does not appear in the superclass.
1135             fun = (void (*)()) rmeth->method->ncode;
1136           }
1137         else
1138           {
1139             jobject rcv = sp[0].o;
1140             _Jv_VTable *table = *(_Jv_VTable**) rcv;
1141             fun = (void (*)()) table->get_method (rmeth->vtable_index);
1142           }
1143
1144 #ifdef DIRECT_THREADED
1145         // Rewrite instruction so that we use a faster pre-resolved
1146         // method.
1147         pc[-2].insn = &&invokevirtual_resolved;
1148         pc[-1].datum = rmeth;
1149 #endif /* DIRECT_THREADED */
1150       }
1151       goto perform_invoke;
1152
1153 #ifdef DIRECT_THREADED
1154     invokevirtual_resolved:
1155       {
1156         rmeth = (_Jv_ResolvedMethod *) AVAL ();
1157         sp -= rmeth->stack_item_count;
1158         // We don't use NULLCHECK here because we can't rely on that
1159         // working if the method is final.  So instead we do an
1160         // explicit test.
1161         if (! sp[0].o)
1162           throw new java::lang::NullPointerException;
1163
1164         if (rmeth->vtable_index == -1)
1165           {
1166             // final methods do not appear in the vtable,
1167             // if it does not appear in the superclass.
1168             fun = (void (*)()) rmeth->method->ncode;
1169           }
1170         else
1171           {
1172             jobject rcv = sp[0].o;
1173             _Jv_VTable *table = *(_Jv_VTable**) rcv;
1174             fun = (void (*)()) table->get_method (rmeth->vtable_index);
1175           }
1176       }
1177       goto perform_invoke;
1178 #endif /* DIRECT_THREADED */
1179
1180     perform_invoke:
1181       {
1182         /* here goes the magic again... */
1183         ffi_cif *cif = &rmeth->cif;
1184         ffi_raw *raw = (ffi_raw*) sp;
1185
1186         _Jv_value rvalue;
1187
1188 #if FFI_NATIVE_RAW_API
1189         /* We assume that this is only implemented if it's correct      */
1190         /* to use it here.  On a 64 bit machine, it never is.           */
1191         ffi_raw_call (cif, fun, (void*)&rvalue, raw);
1192 #else
1193         ffi_java_raw_call (cif, fun, (void*)&rvalue, raw);
1194 #endif
1195
1196         int rtype = cif->rtype->type;
1197
1198         /* the likelyhood of object, int, or void return is very high,
1199          * so those are checked before the switch */
1200         if (rtype == FFI_TYPE_POINTER)
1201           {
1202             PUSHA (rvalue.object_value);
1203           }
1204         else if (rtype == FFI_TYPE_SINT32)
1205           {
1206             PUSHI (rvalue.int_value);
1207           }
1208         else if (rtype == FFI_TYPE_VOID)
1209           {
1210             /* skip */
1211           }
1212         else
1213           {
1214             switch (rtype)
1215               {
1216               case FFI_TYPE_SINT8:
1217                 PUSHI ((jbyte)(rvalue.int_value & 0xff));
1218                 break;
1219
1220               case FFI_TYPE_SINT16:
1221                 PUSHI ((jshort)(rvalue.int_value & 0xffff));
1222                 break;
1223
1224               case FFI_TYPE_UINT16:
1225                 PUSHI (rvalue.int_value & 0xffff);
1226                 break;
1227
1228               case FFI_TYPE_FLOAT:
1229                 PUSHF (rvalue.float_value);
1230                 break;
1231
1232               case FFI_TYPE_DOUBLE:
1233                 PUSHD (rvalue.double_value);
1234                 break;
1235
1236               case FFI_TYPE_SINT64:
1237                 PUSHL (rvalue.long_value);
1238                 break;
1239
1240               default:
1241                 throw_internal_error ("unknown return type in invokeXXX");
1242               }
1243           }
1244       }
1245       NEXT_INSN;
1246
1247     insn_aconst_null:
1248       PUSHA (NULL);
1249       NEXT_INSN;
1250
1251     insn_iconst_m1:
1252       PUSHI (-1);
1253       NEXT_INSN;
1254
1255     insn_iconst_0:
1256       PUSHI (0);
1257       NEXT_INSN;
1258
1259     insn_iconst_1:
1260       PUSHI (1);
1261       NEXT_INSN;
1262
1263     insn_iconst_2:
1264       PUSHI (2);
1265       NEXT_INSN;
1266
1267     insn_iconst_3:
1268       PUSHI (3);
1269       NEXT_INSN;
1270
1271     insn_iconst_4:
1272       PUSHI (4);
1273       NEXT_INSN;
1274
1275     insn_iconst_5:
1276       PUSHI (5);
1277       NEXT_INSN;
1278
1279     insn_lconst_0:
1280       PUSHL (0);
1281       NEXT_INSN;
1282
1283     insn_lconst_1:
1284       PUSHL (1);
1285       NEXT_INSN;
1286
1287     insn_fconst_0:
1288       PUSHF (0);
1289       NEXT_INSN;
1290
1291     insn_fconst_1:
1292       PUSHF (1);
1293       NEXT_INSN;
1294
1295     insn_fconst_2:
1296       PUSHF (2);
1297       NEXT_INSN;
1298
1299     insn_dconst_0:
1300       PUSHD (0);
1301       NEXT_INSN;
1302
1303     insn_dconst_1:
1304       PUSHD (1);
1305       NEXT_INSN;
1306
1307     insn_bipush:
1308       // For direct threaded, bipush and sipush are the same.
1309 #ifndef DIRECT_THREADED
1310       PUSHI (GET1S ());
1311       NEXT_INSN;
1312 #endif /* DIRECT_THREADED */
1313     insn_sipush:
1314       PUSHI (GET2S ());
1315       NEXT_INSN;
1316
1317     insn_ldc:
1318       // For direct threaded, ldc and ldc_w are the same.
1319 #ifndef DIRECT_THREADED
1320       PUSHA ((jobject) AVAL1U ());
1321       NEXT_INSN;
1322 #endif /* DIRECT_THREADED */
1323     insn_ldc_w:
1324       PUSHA ((jobject) AVAL2U ());
1325       NEXT_INSN;
1326
1327     insn_ldc2_w:
1328       {
1329         void *where = AVAL2UP ();
1330         memcpy (sp, where, 2*sizeof (_Jv_word));
1331         sp += 2;
1332       }
1333       NEXT_INSN;
1334
1335     insn_lload:
1336       LOADL (GET1U ());
1337       NEXT_INSN;
1338
1339     insn_fload:
1340       LOADF (GET1U ());
1341       NEXT_INSN;
1342
1343     insn_dload:
1344       LOADD (GET1U ());
1345       NEXT_INSN;
1346
1347     insn_aload:
1348       LOADA (GET1U ());
1349       NEXT_INSN;
1350
1351     insn_iload_0:
1352       LOADI (0);
1353       NEXT_INSN;
1354
1355     insn_iload_2:
1356       LOADI (2);
1357       NEXT_INSN;
1358
1359     insn_iload_3:
1360       LOADI (3);
1361       NEXT_INSN;
1362
1363     insn_lload_0:
1364       LOADL (0);
1365       NEXT_INSN;
1366
1367     insn_lload_1:
1368       LOADL (1);
1369       NEXT_INSN;
1370
1371     insn_lload_2:
1372       LOADL (2);
1373       NEXT_INSN;
1374
1375     insn_lload_3:
1376       LOADL (3);
1377       NEXT_INSN;
1378
1379     insn_fload_0:
1380       LOADF (0);
1381       NEXT_INSN;
1382
1383     insn_fload_1:
1384       LOADF (1);
1385       NEXT_INSN;
1386
1387     insn_fload_2:
1388       LOADF (2);
1389       NEXT_INSN;
1390
1391     insn_fload_3:
1392       LOADF (3);
1393       NEXT_INSN;
1394
1395     insn_dload_0:
1396       LOADD (0);
1397       NEXT_INSN;
1398
1399     insn_dload_1:
1400       LOADD (1);
1401       NEXT_INSN;
1402
1403     insn_dload_2:
1404       LOADD (2);
1405       NEXT_INSN;
1406
1407     insn_dload_3:
1408       LOADD (3);
1409       NEXT_INSN;
1410
1411     insn_aload_1:
1412       LOADA(1);
1413       NEXT_INSN;
1414
1415     insn_aload_2:
1416       LOADA(2);
1417       NEXT_INSN;
1418
1419     insn_aload_3:
1420       LOADA(3);
1421       NEXT_INSN;
1422
1423     insn_iaload:
1424       {
1425         jint index = POPI();
1426         jintArray arr = (jintArray) POPA();
1427         NULLARRAYCHECK (arr);
1428         ARRAYBOUNDSCHECK (arr, index);
1429         PUSHI( elements(arr)[index] );
1430       }
1431       NEXT_INSN;
1432
1433     insn_laload:
1434       {
1435         jint index = POPI();
1436         jlongArray arr = (jlongArray) POPA();
1437         NULLARRAYCHECK (arr);
1438         ARRAYBOUNDSCHECK (arr, index);
1439         PUSHL( elements(arr)[index] );
1440       }
1441       NEXT_INSN;
1442
1443     insn_faload:
1444       {
1445         jint index = POPI();
1446         jfloatArray arr = (jfloatArray) POPA();
1447         NULLARRAYCHECK (arr);
1448         ARRAYBOUNDSCHECK (arr, index);
1449         PUSHF( elements(arr)[index] );
1450       }
1451       NEXT_INSN;
1452
1453     insn_daload:
1454       {
1455         jint index = POPI();
1456         jdoubleArray arr = (jdoubleArray) POPA();
1457         NULLARRAYCHECK (arr);
1458         ARRAYBOUNDSCHECK (arr, index);
1459         PUSHD( elements(arr)[index] );
1460       }
1461       NEXT_INSN;
1462
1463     insn_aaload:
1464       {
1465         jint index = POPI();
1466         jobjectArray arr = (jobjectArray) POPA();
1467         NULLARRAYCHECK (arr);
1468         ARRAYBOUNDSCHECK (arr, index);
1469         PUSHA( elements(arr)[index] );
1470       }
1471       NEXT_INSN;
1472
1473     insn_baload:
1474       {
1475         jint index = POPI();
1476         jbyteArray arr = (jbyteArray) POPA();
1477         NULLARRAYCHECK (arr);
1478         ARRAYBOUNDSCHECK (arr, index);
1479         PUSHI( elements(arr)[index] );
1480       }
1481       NEXT_INSN;
1482
1483     insn_caload:
1484       {
1485         jint index = POPI();
1486         jcharArray arr = (jcharArray) POPA();
1487         NULLARRAYCHECK (arr);
1488         ARRAYBOUNDSCHECK (arr, index);
1489         PUSHI( elements(arr)[index] );
1490       }
1491       NEXT_INSN;
1492
1493     insn_saload:
1494       {
1495         jint index = POPI();
1496         jshortArray arr = (jshortArray) POPA();
1497         NULLARRAYCHECK (arr);
1498         ARRAYBOUNDSCHECK (arr, index);
1499         PUSHI( elements(arr)[index] );
1500       }
1501       NEXT_INSN;
1502
1503     insn_istore:
1504       STOREI (GET1U ());
1505       NEXT_INSN;
1506
1507     insn_lstore:
1508       STOREL (GET1U ());
1509       NEXT_INSN;
1510
1511     insn_fstore:
1512       STOREF (GET1U ());
1513       NEXT_INSN;
1514
1515     insn_dstore:
1516       STORED (GET1U ());
1517       NEXT_INSN;
1518
1519     insn_astore:
1520       STOREA (GET1U ());
1521       NEXT_INSN;
1522
1523     insn_istore_0:
1524       STOREI (0);
1525       NEXT_INSN;
1526
1527     insn_istore_1:
1528       STOREI (1);
1529       NEXT_INSN;
1530
1531     insn_istore_2:
1532       STOREI (2);
1533       NEXT_INSN;
1534
1535     insn_istore_3:
1536       STOREI (3);
1537       NEXT_INSN;
1538
1539     insn_lstore_0:
1540       STOREL (0);
1541       NEXT_INSN;
1542
1543     insn_lstore_1:
1544       STOREL (1);
1545       NEXT_INSN;
1546
1547     insn_lstore_2:
1548       STOREL (2);
1549       NEXT_INSN;
1550
1551     insn_lstore_3:
1552       STOREL (3);
1553       NEXT_INSN;
1554
1555     insn_fstore_0:
1556       STOREF (0);
1557       NEXT_INSN;
1558
1559     insn_fstore_1:
1560       STOREF (1);
1561       NEXT_INSN;
1562
1563     insn_fstore_2:
1564       STOREF (2);
1565       NEXT_INSN;
1566
1567     insn_fstore_3:
1568       STOREF (3);
1569       NEXT_INSN;
1570
1571     insn_dstore_0:
1572       STORED (0);
1573       NEXT_INSN;
1574
1575     insn_dstore_1:
1576       STORED (1);
1577       NEXT_INSN;
1578
1579     insn_dstore_2:
1580       STORED (2);
1581       NEXT_INSN;
1582
1583     insn_dstore_3:
1584       STORED (3);
1585       NEXT_INSN;
1586
1587     insn_astore_0:
1588       STOREA(0);
1589       NEXT_INSN;
1590
1591     insn_astore_1:
1592       STOREA(1);
1593       NEXT_INSN;
1594
1595     insn_astore_2:
1596       STOREA(2);
1597       NEXT_INSN;
1598
1599     insn_astore_3:
1600       STOREA(3);
1601       NEXT_INSN;
1602
1603     insn_iastore:
1604       {
1605         jint value = POPI();
1606         jint index  = POPI();
1607         jintArray arr = (jintArray) POPA();
1608         NULLARRAYCHECK (arr);
1609         ARRAYBOUNDSCHECK (arr, index);
1610         elements(arr)[index] = value;
1611       }
1612       NEXT_INSN;
1613
1614     insn_lastore:
1615       {
1616         jlong value = POPL();
1617         jint index  = POPI();
1618         jlongArray arr = (jlongArray) POPA();
1619         NULLARRAYCHECK (arr);
1620         ARRAYBOUNDSCHECK (arr, index);
1621         elements(arr)[index] = value;
1622       }
1623       NEXT_INSN;
1624
1625     insn_fastore:
1626       {
1627         jfloat value = POPF();
1628         jint index  = POPI();
1629         jfloatArray arr = (jfloatArray) POPA();
1630         NULLARRAYCHECK (arr);
1631         ARRAYBOUNDSCHECK (arr, index);
1632         elements(arr)[index] = value;
1633       }
1634       NEXT_INSN;
1635
1636     insn_dastore:
1637       {
1638         jdouble value = POPD();
1639         jint index  = POPI();
1640         jdoubleArray arr = (jdoubleArray) POPA();
1641         NULLARRAYCHECK (arr);
1642         ARRAYBOUNDSCHECK (arr, index);
1643         elements(arr)[index] = value;
1644       }
1645       NEXT_INSN;
1646
1647     insn_aastore:
1648       {
1649         jobject value = POPA();
1650         jint index  = POPI();
1651         jobjectArray arr = (jobjectArray) POPA();
1652         NULLARRAYCHECK (arr);
1653         ARRAYBOUNDSCHECK (arr, index);
1654         _Jv_CheckArrayStore (arr, value);
1655         elements(arr)[index] = value;
1656       }
1657       NEXT_INSN;
1658
1659     insn_bastore:
1660       {
1661         jbyte value = (jbyte) POPI();
1662         jint index  = POPI();
1663         jbyteArray arr = (jbyteArray) POPA();
1664         NULLARRAYCHECK (arr);
1665         ARRAYBOUNDSCHECK (arr, index);
1666         elements(arr)[index] = value;
1667       }
1668       NEXT_INSN;
1669
1670     insn_castore:
1671       {
1672         jchar value = (jchar) POPI();
1673         jint index  = POPI();
1674         jcharArray arr = (jcharArray) POPA();
1675         NULLARRAYCHECK (arr);
1676         ARRAYBOUNDSCHECK (arr, index);
1677         elements(arr)[index] = value;
1678       }
1679       NEXT_INSN;
1680
1681     insn_sastore:
1682       {
1683         jshort value = (jshort) POPI();
1684         jint index  = POPI();
1685         jshortArray arr = (jshortArray) POPA();
1686         NULLARRAYCHECK (arr);
1687         ARRAYBOUNDSCHECK (arr, index);
1688         elements(arr)[index] = value;
1689       }
1690       NEXT_INSN;
1691
1692     insn_pop:
1693       sp -= 1;
1694       NEXT_INSN;
1695
1696     insn_pop2:
1697       sp -= 2;
1698       NEXT_INSN;
1699
1700     insn_dup:
1701       sp[0] = sp[-1];
1702       sp += 1;
1703       NEXT_INSN;
1704
1705     insn_dup_x1:
1706       dupx (sp, 1, 1); sp+=1;
1707       NEXT_INSN;
1708
1709     insn_dup_x2:
1710       dupx (sp, 1, 2); sp+=1;
1711       NEXT_INSN;
1712
1713     insn_dup2:
1714       sp[0] = sp[-2];
1715       sp[1] = sp[-1];
1716       sp += 2;
1717       NEXT_INSN;
1718
1719     insn_dup2_x1:
1720       dupx (sp, 2, 1); sp+=2;
1721       NEXT_INSN;
1722
1723     insn_dup2_x2:
1724       dupx (sp, 2, 2); sp+=2;
1725       NEXT_INSN;
1726
1727     insn_swap:
1728       {
1729         jobject tmp1 = POPA();
1730         jobject tmp2 = POPA();
1731         PUSHA (tmp1);
1732         PUSHA (tmp2);
1733       }
1734       NEXT_INSN;
1735
1736     insn_iadd:
1737       BINOPI(+);
1738       NEXT_INSN;
1739
1740     insn_ladd:
1741       BINOPL(+);
1742       NEXT_INSN;
1743
1744     insn_fadd:
1745       BINOPF(+);
1746       NEXT_INSN;
1747
1748     insn_dadd:
1749       BINOPD(+);
1750       NEXT_INSN;
1751
1752     insn_isub:
1753       BINOPI(-);
1754       NEXT_INSN;
1755
1756     insn_lsub:
1757       BINOPL(-);
1758       NEXT_INSN;
1759
1760     insn_fsub:
1761       BINOPF(-);
1762       NEXT_INSN;
1763
1764     insn_dsub:
1765       BINOPD(-);
1766       NEXT_INSN;
1767
1768     insn_imul:
1769       BINOPI(*);
1770       NEXT_INSN;
1771
1772     insn_lmul:
1773       BINOPL(*);
1774       NEXT_INSN;
1775
1776     insn_fmul:
1777       BINOPF(*);
1778       NEXT_INSN;
1779
1780     insn_dmul:
1781       BINOPD(*);
1782       NEXT_INSN;
1783
1784     insn_idiv:
1785       {
1786         jint value2 = POPI();
1787         jint value1 = POPI();
1788         jint res = _Jv_divI (value1, value2);
1789         PUSHI (res);
1790       }
1791       NEXT_INSN;
1792
1793     insn_ldiv:
1794       {
1795         jlong value2 = POPL();
1796         jlong value1 = POPL();
1797         jlong res = _Jv_divJ (value1, value2);
1798         PUSHL (res);
1799       }
1800       NEXT_INSN;
1801
1802     insn_fdiv:
1803       {
1804         jfloat value2 = POPF();
1805         jfloat value1 = POPF();
1806         jfloat res = value1 / value2;
1807         PUSHF (res);
1808       }
1809       NEXT_INSN;
1810
1811     insn_ddiv:
1812       {
1813         jdouble value2 = POPD();
1814         jdouble value1 = POPD();
1815         jdouble res = value1 / value2;
1816         PUSHD (res);
1817       }
1818       NEXT_INSN;
1819
1820     insn_irem:
1821       {
1822         jint value2 = POPI();
1823         jint value1 =  POPI();
1824         jint res = _Jv_remI (value1, value2);
1825         PUSHI (res);
1826       }
1827       NEXT_INSN;
1828
1829     insn_lrem:
1830       {
1831         jlong value2 = POPL();
1832         jlong value1 = POPL();
1833         jlong res = _Jv_remJ (value1, value2);
1834         PUSHL (res);
1835       }
1836       NEXT_INSN;
1837
1838     insn_frem:
1839       {
1840         jfloat value2 = POPF();
1841         jfloat value1 = POPF();
1842         jfloat res    = __ieee754_fmod (value1, value2);
1843         PUSHF (res);
1844       }
1845       NEXT_INSN;
1846
1847     insn_drem:
1848       {
1849         jdouble value2 = POPD();
1850         jdouble value1 = POPD();
1851         jdouble res    = __ieee754_fmod (value1, value2);
1852         PUSHD (res);
1853       }
1854       NEXT_INSN;
1855
1856     insn_ineg:
1857       {
1858         jint value = POPI();
1859         PUSHI (value * -1);
1860       }
1861       NEXT_INSN;
1862
1863     insn_lneg:
1864       {
1865         jlong value = POPL();
1866         PUSHL (value * -1);
1867       }
1868       NEXT_INSN;
1869
1870     insn_fneg:
1871       {
1872         jfloat value = POPF();
1873         PUSHF (value * -1);
1874       }
1875       NEXT_INSN;
1876
1877     insn_dneg:
1878       {
1879         jdouble value = POPD();
1880         PUSHD (value * -1);
1881       }
1882       NEXT_INSN;
1883
1884     insn_ishl:
1885       {
1886         jint shift = (POPI() & 0x1f);
1887         jint value = POPI();
1888         PUSHI (value << shift);
1889       }
1890       NEXT_INSN;
1891
1892     insn_lshl:
1893       {
1894         jint shift = (POPI() & 0x3f);
1895         jlong value = POPL();
1896         PUSHL (value << shift);
1897       }
1898       NEXT_INSN;
1899
1900     insn_ishr:
1901       {
1902         jint shift = (POPI() & 0x1f);
1903         jint value = POPI();
1904         PUSHI (value >> shift);
1905       }
1906       NEXT_INSN;
1907
1908     insn_lshr:
1909       {
1910         jint shift = (POPI() & 0x3f);
1911         jlong value = POPL();
1912         PUSHL (value >> shift);
1913       }
1914       NEXT_INSN;
1915
1916     insn_iushr:
1917       {
1918         jint shift = (POPI() & 0x1f);
1919         _Jv_uint value = (_Jv_uint) POPI();
1920         PUSHI ((jint) (value >> shift));
1921       }
1922       NEXT_INSN;
1923
1924     insn_lushr:
1925       {
1926         jint shift = (POPI() & 0x3f);
1927         _Jv_ulong value = (_Jv_ulong) POPL();
1928         PUSHL ((jlong) (value >> shift));
1929       }
1930       NEXT_INSN;
1931
1932     insn_iand:
1933       BINOPI (&);
1934       NEXT_INSN;
1935
1936     insn_land:
1937       BINOPL (&);
1938       NEXT_INSN;
1939
1940     insn_ior:
1941       BINOPI (|);
1942       NEXT_INSN;
1943
1944     insn_lor:
1945       BINOPL (|);
1946       NEXT_INSN;
1947
1948     insn_ixor:
1949       BINOPI (^);
1950       NEXT_INSN;
1951
1952     insn_lxor:
1953       BINOPL (^);
1954       NEXT_INSN;
1955
1956     insn_iinc:
1957       {
1958         jint index  = GET1U ();
1959         jint amount = GET1S ();
1960         locals[index].i += amount;
1961       }
1962       NEXT_INSN;
1963
1964     insn_i2l:
1965       {jlong value = POPI(); PUSHL (value);}
1966       NEXT_INSN;
1967
1968     insn_i2f:
1969       {jfloat value = POPI(); PUSHF (value);}
1970       NEXT_INSN;
1971
1972     insn_i2d:
1973       {jdouble value = POPI(); PUSHD (value);}
1974       NEXT_INSN;
1975
1976     insn_l2i:
1977       {jint value = POPL(); PUSHI (value);}
1978       NEXT_INSN;
1979
1980     insn_l2f:
1981       {jfloat value = POPL(); PUSHF (value);}
1982       NEXT_INSN;
1983
1984     insn_l2d:
1985       {jdouble value = POPL(); PUSHD (value);}
1986       NEXT_INSN;
1987
1988     insn_f2i:
1989       {
1990         using namespace java::lang;
1991         jint value = convert (POPF (), Integer::MIN_VALUE, Integer::MAX_VALUE);
1992         PUSHI(value);
1993       }
1994       NEXT_INSN;
1995
1996     insn_f2l:
1997       {
1998         using namespace java::lang;
1999         jlong value = convert (POPF (), Long::MIN_VALUE, Long::MAX_VALUE);
2000         PUSHL(value);
2001       }
2002       NEXT_INSN;
2003
2004     insn_f2d:
2005       { jdouble value = POPF (); PUSHD(value); }
2006       NEXT_INSN;
2007
2008     insn_d2i:
2009       {
2010         using namespace java::lang;
2011         jint value = convert (POPD (), Integer::MIN_VALUE, Integer::MAX_VALUE);
2012         PUSHI(value);
2013       }
2014       NEXT_INSN;
2015
2016     insn_d2l:
2017       {
2018         using namespace java::lang;
2019         jlong value = convert (POPD (), Long::MIN_VALUE, Long::MAX_VALUE);
2020         PUSHL(value);
2021       }
2022       NEXT_INSN;
2023
2024     insn_d2f:
2025       { jfloat value = POPD (); PUSHF(value); }
2026       NEXT_INSN;
2027
2028     insn_i2b:
2029       { jbyte value = POPI (); PUSHI(value); }
2030       NEXT_INSN;
2031
2032     insn_i2c:
2033       { jchar value = POPI (); PUSHI(value); }
2034       NEXT_INSN;
2035
2036     insn_i2s:
2037       { jshort value = POPI (); PUSHI(value); }
2038       NEXT_INSN;
2039
2040     insn_lcmp:
2041       {
2042         jlong value2 = POPL ();
2043         jlong value1 = POPL ();
2044         if (value1 > value2)
2045           { PUSHI (1); }
2046         else if (value1 == value2)
2047           { PUSHI (0); }
2048         else
2049           { PUSHI (-1); }
2050       }
2051       NEXT_INSN;
2052
2053     insn_fcmpl:
2054       tmpval = -1;
2055       goto fcmp;
2056
2057     insn_fcmpg:
2058       tmpval = 1;
2059
2060     fcmp:
2061       {
2062         jfloat value2 = POPF ();
2063         jfloat value1 = POPF ();
2064         if (value1 > value2)
2065           PUSHI (1);
2066         else if (value1 == value2)
2067           PUSHI (0);
2068         else if (value1 < value2)
2069           PUSHI (-1);
2070         else
2071           PUSHI (tmpval);
2072       }
2073       NEXT_INSN;
2074
2075     insn_dcmpl:
2076       tmpval = 1;
2077       goto dcmp;
2078
2079     insn_dcmpg:
2080       tmpval = -1;
2081
2082     dcmp:
2083       {
2084         jdouble value2 = POPD ();
2085         jdouble value1 = POPD ();
2086         if (value1 > value2)
2087           PUSHI (1);
2088         else if (value1 == value2)
2089           PUSHI (0);
2090         else if (value1 < value2)
2091           PUSHI (-1);
2092         else
2093           PUSHI (tmpval);
2094       }
2095       NEXT_INSN;
2096
2097     insn_ifeq:
2098       {
2099         if (POPI() == 0)
2100           TAKE_GOTO;
2101         else
2102           SKIP_GOTO;
2103       }
2104       NEXT_INSN;
2105
2106     insn_ifne:
2107       {
2108         if (POPI() != 0)
2109           TAKE_GOTO;
2110         else
2111           SKIP_GOTO;
2112       }
2113       NEXT_INSN;
2114
2115     insn_iflt:
2116       {
2117         if (POPI() < 0)
2118           TAKE_GOTO;
2119         else
2120           SKIP_GOTO;
2121       }
2122       NEXT_INSN;
2123
2124     insn_ifge:
2125       {
2126         if (POPI() >= 0)
2127           TAKE_GOTO;
2128         else
2129           SKIP_GOTO;
2130       }
2131       NEXT_INSN;
2132
2133     insn_ifgt:
2134       {
2135         if (POPI() > 0)
2136           TAKE_GOTO;
2137         else
2138           SKIP_GOTO;
2139       }
2140       NEXT_INSN;
2141
2142     insn_ifle:
2143       {
2144         if (POPI() <= 0)
2145           TAKE_GOTO;
2146         else
2147           SKIP_GOTO;
2148       }
2149       NEXT_INSN;
2150
2151     insn_if_icmpeq:
2152       {
2153         jint value2 = POPI();
2154         jint value1 = POPI();
2155         if (value1 == value2)
2156           TAKE_GOTO;
2157         else
2158           SKIP_GOTO;
2159       }
2160       NEXT_INSN;
2161
2162     insn_if_icmpne:
2163       {
2164         jint value2 = POPI();
2165         jint value1 = POPI();
2166         if (value1 != value2)
2167           TAKE_GOTO;
2168         else
2169           SKIP_GOTO;
2170       }
2171       NEXT_INSN;
2172
2173     insn_if_icmplt:
2174       {
2175         jint value2 = POPI();
2176         jint value1 = POPI();
2177         if (value1 < value2)
2178           TAKE_GOTO;
2179         else
2180           SKIP_GOTO;
2181       }
2182       NEXT_INSN;
2183
2184     insn_if_icmpge:
2185       {
2186         jint value2 = POPI();
2187         jint value1 = POPI();
2188         if (value1 >= value2)
2189           TAKE_GOTO;
2190         else
2191           SKIP_GOTO;
2192       }
2193       NEXT_INSN;
2194
2195     insn_if_icmpgt:
2196       {
2197         jint value2 = POPI();
2198         jint value1 = POPI();
2199         if (value1 > value2)
2200           TAKE_GOTO;
2201         else
2202           SKIP_GOTO;
2203       }
2204       NEXT_INSN;
2205
2206     insn_if_icmple:
2207       {
2208         jint value2 = POPI();
2209         jint value1 = POPI();
2210         if (value1 <= value2)
2211           TAKE_GOTO;
2212         else
2213           SKIP_GOTO;
2214       }
2215       NEXT_INSN;
2216
2217     insn_if_acmpeq:
2218       {
2219         jobject value2 = POPA();
2220         jobject value1 = POPA();
2221         if (value1 == value2)
2222           TAKE_GOTO;
2223         else
2224           SKIP_GOTO;
2225       }
2226       NEXT_INSN;
2227
2228     insn_if_acmpne:
2229       {
2230         jobject value2 = POPA();
2231         jobject value1 = POPA();
2232         if (value1 != value2)
2233           TAKE_GOTO;
2234         else
2235           SKIP_GOTO;
2236       }
2237       NEXT_INSN;
2238
2239     insn_goto_w:
2240 #ifndef DIRECT_THREADED
2241       // For direct threaded, goto and goto_w are the same.
2242       pc = pc - 1 + get4 (pc);
2243       NEXT_INSN;
2244 #endif /* DIRECT_THREADED */
2245     insn_goto:
2246       TAKE_GOTO;
2247       NEXT_INSN;
2248
2249     insn_jsr_w:
2250 #ifndef DIRECT_THREADED
2251       // For direct threaded, jsr and jsr_w are the same.
2252       {
2253         pc_t next = pc - 1 + get4 (pc);
2254         pc += 4;
2255         PUSHA ((jobject) pc);
2256         pc = next;
2257       }
2258       NEXT_INSN;
2259 #endif /* DIRECT_THREADED */
2260     insn_jsr:
2261       {
2262         pc_t next = GOTO_VAL();
2263         SKIP_GOTO;
2264         PUSHA ((jobject) pc);
2265         pc = next;
2266       }
2267       NEXT_INSN;
2268
2269     insn_ret:
2270       {
2271         jint index = GET1U ();
2272         pc = (pc_t) PEEKA (index);
2273       }
2274       NEXT_INSN;
2275
2276     insn_tableswitch:
2277       {
2278 #ifdef DIRECT_THREADED
2279         void *def = (pc++)->datum;
2280
2281         int index = POPI();
2282
2283         jint low = INTVAL ();
2284         jint high = INTVAL ();
2285
2286         if (index < low || index > high)
2287           pc = (insn_slot *) def;
2288         else
2289           pc = (insn_slot *) ((pc + index - low)->datum);
2290 #else
2291         pc_t base_pc = pc - 1;
2292         int index = POPI ();
2293
2294         pc_t base = (pc_t) bytecode ();
2295         while ((pc - base) % 4 != 0)
2296           ++pc;
2297
2298         jint def = get4 (pc);
2299         jint low = get4 (pc + 4);
2300         jint high = get4 (pc + 8);
2301         if (index < low || index > high)
2302           pc = base_pc + def;
2303         else
2304           pc = base_pc + get4 (pc + 4 * (index - low + 3));
2305 #endif /* DIRECT_THREADED */
2306       }
2307       NEXT_INSN;
2308
2309     insn_lookupswitch:
2310       {
2311 #ifdef DIRECT_THREADED
2312         void *def = (pc++)->insn;
2313
2314         int index = POPI();
2315
2316         jint npairs = INTVAL ();
2317
2318         int max = npairs - 1;
2319         int min = 0;
2320
2321         // Simple binary search...
2322         while (min < max)
2323           {
2324             int half = (min + max) / 2;
2325             int match = pc[2 * half].int_val;
2326
2327             if (index == match)
2328               {
2329                 // Found it.
2330                 pc = (insn_slot *) pc[2 * half + 1].datum;
2331                 NEXT_INSN;
2332               }
2333             else if (index < match)
2334               // We can use HALF - 1 here because we check again on
2335               // loop exit.
2336               max = half - 1;
2337             else
2338               // We can use HALF + 1 here because we check again on
2339               // loop exit.
2340               min = half + 1;
2341           }
2342         if (index == pc[2 * min].int_val)
2343           pc = (insn_slot *) pc[2 * min + 1].datum;
2344         else
2345           pc = (insn_slot *) def;
2346 #else
2347         unsigned char *base_pc = pc-1;
2348         int index = POPI();
2349
2350         unsigned char* base = bytecode ();
2351         while ((pc-base) % 4 != 0)
2352           ++pc;
2353
2354         jint def     = get4 (pc);
2355         jint npairs  = get4 (pc+4);
2356
2357         int max = npairs-1;
2358         int min = 0;
2359
2360         // Simple binary search...
2361         while (min < max)
2362           {
2363             int half = (min+max)/2;
2364             int match = get4 (pc+ 4*(2 + 2*half));
2365
2366             if (index == match)
2367               min = max = half;
2368             else if (index < match)
2369               // We can use HALF - 1 here because we check again on
2370               // loop exit.
2371               max = half - 1;
2372             else
2373               // We can use HALF + 1 here because we check again on
2374               // loop exit.
2375               min = half + 1;
2376           }
2377
2378         if (index == get4 (pc+ 4*(2 + 2*min)))
2379           pc = base_pc + get4 (pc+ 4*(2 + 2*min + 1));
2380         else
2381           pc = base_pc + def;    
2382 #endif /* DIRECT_THREADED */
2383       }
2384       NEXT_INSN;
2385
2386     insn_areturn:
2387       *(jobject *) retp = POPA ();
2388       return;
2389
2390     insn_lreturn:
2391       *(jlong *) retp = POPL ();
2392       return;
2393
2394     insn_freturn:
2395       *(jfloat *) retp = POPF ();
2396       return;
2397
2398     insn_dreturn:
2399       *(jdouble *) retp = POPD ();
2400       return;
2401
2402     insn_ireturn:
2403       *(jint *) retp = POPI ();
2404       return;
2405
2406     insn_return:
2407       return;
2408
2409     insn_getstatic:
2410       {
2411         jint fieldref_index = GET2U ();
2412         _Jv_ResolvePoolEntry (defining_class, fieldref_index);
2413         _Jv_Field *field = pool_data[fieldref_index].field;
2414
2415         if ((field->flags & Modifier::STATIC) == 0)
2416           throw_incompatible_class_change_error 
2417             (JvNewStringLatin1 ("field no longer static"));
2418
2419         jclass type = field->type;
2420
2421         // We rewrite the instruction once we discover what it refers
2422         // to.
2423         void *newinsn = NULL;
2424         if (type->isPrimitive ())
2425           {
2426             switch (type->size_in_bytes)
2427               {
2428               case 1:
2429                 PUSHI (*field->u.byte_addr);
2430                 newinsn = AMPAMP (getstatic_resolved_1);
2431                 break;
2432
2433               case 2:
2434                 if (type == JvPrimClass (char))
2435                   {
2436                     PUSHI (*field->u.char_addr);
2437                     newinsn = AMPAMP (getstatic_resolved_char);
2438                   }
2439                 else
2440                   {
2441                     PUSHI (*field->u.short_addr);
2442                     newinsn = AMPAMP (getstatic_resolved_short);
2443                   }
2444                 break;
2445
2446               case 4:
2447                 PUSHI(*field->u.int_addr);
2448                 newinsn = AMPAMP (getstatic_resolved_4);
2449                 break;
2450
2451               case 8:
2452                 PUSHL(*field->u.long_addr);
2453                 newinsn = AMPAMP (getstatic_resolved_8);
2454                 break;
2455               }
2456           }
2457         else
2458           {
2459             PUSHA(*field->u.object_addr);
2460             newinsn = AMPAMP (getstatic_resolved_obj);
2461           }
2462
2463 #ifdef DIRECT_THREADED
2464         pc[-2].insn = newinsn;
2465         pc[-1].datum = field->u.addr;
2466 #endif /* DIRECT_THREADED */
2467       }
2468       NEXT_INSN;
2469
2470 #ifdef DIRECT_THREADED
2471     getstatic_resolved_1:
2472       PUSHI (*(jbyte *) AVAL ());
2473       NEXT_INSN;
2474
2475     getstatic_resolved_char:
2476       PUSHI (*(jchar *) AVAL ());
2477       NEXT_INSN;
2478
2479     getstatic_resolved_short:
2480       PUSHI (*(jshort *) AVAL ());
2481       NEXT_INSN;
2482
2483     getstatic_resolved_4:
2484       PUSHI (*(jint *) AVAL ());
2485       NEXT_INSN;
2486
2487     getstatic_resolved_8:
2488       PUSHL (*(jlong *) AVAL ());
2489       NEXT_INSN;
2490
2491     getstatic_resolved_obj:
2492       PUSHA (*(jobject *) AVAL ());
2493       NEXT_INSN;
2494 #endif /* DIRECT_THREADED */
2495
2496     insn_getfield:
2497       {
2498         jint fieldref_index = GET2U ();
2499         _Jv_ResolvePoolEntry (defining_class, fieldref_index);
2500         _Jv_Field *field = pool_data[fieldref_index].field;
2501
2502         if ((field->flags & Modifier::STATIC) != 0)
2503           throw_incompatible_class_change_error 
2504             (JvNewStringLatin1 ("field is static"));
2505
2506         jclass type = field->type;
2507         jint field_offset = field->u.boffset;
2508         if (field_offset > 0xffff)
2509           throw new java::lang::VirtualMachineError;
2510
2511         jobject obj   = POPA();
2512         NULLCHECK(obj);
2513
2514         void *newinsn = NULL;
2515         _Jv_value *val = (_Jv_value *) ((char *)obj + field_offset);
2516         if (type->isPrimitive ())
2517           {
2518             switch (type->size_in_bytes)
2519               {
2520               case 1:
2521                 PUSHI (val->byte_value);
2522                 newinsn = AMPAMP (getfield_resolved_1);
2523                 break;
2524
2525               case 2:
2526                 if (type == JvPrimClass (char))
2527                   {
2528                     PUSHI (val->char_value);
2529                     newinsn = AMPAMP (getfield_resolved_char);
2530                   }
2531                 else
2532                   {
2533                     PUSHI (val->short_value);
2534                     newinsn = AMPAMP (getfield_resolved_short);
2535                   }
2536                 break;
2537
2538               case 4:
2539                 PUSHI (val->int_value);
2540                 newinsn = AMPAMP (getfield_resolved_4);
2541                 break;
2542
2543               case 8:
2544                 PUSHL (val->long_value);
2545                 newinsn = AMPAMP (getfield_resolved_8);
2546                 break;
2547               }
2548           }
2549         else
2550           {
2551             PUSHA (val->object_value);
2552             newinsn = AMPAMP (getfield_resolved_obj);
2553           }
2554
2555 #ifdef DIRECT_THREADED
2556         pc[-2].insn = newinsn;
2557         pc[-1].int_val = field_offset;
2558 #endif /* DIRECT_THREADED */
2559       }
2560       NEXT_INSN;
2561
2562 #ifdef DIRECT_THREADED
2563     getfield_resolved_1:
2564       {
2565         char *obj = (char *) POPA ();
2566         NULLCHECK (obj);
2567         PUSHI (*(jbyte *) (obj + INTVAL ()));
2568       }
2569       NEXT_INSN;
2570
2571     getfield_resolved_char:
2572       {
2573         char *obj = (char *) POPA ();
2574         NULLCHECK (obj);
2575         PUSHI (*(jchar *) (obj + INTVAL ()));
2576       }
2577       NEXT_INSN;
2578
2579     getfield_resolved_short:
2580       {
2581         char *obj = (char *) POPA ();
2582         NULLCHECK (obj);
2583         PUSHI (*(jshort *) (obj + INTVAL ()));
2584       }
2585       NEXT_INSN;
2586
2587     getfield_resolved_4:
2588       {
2589         char *obj = (char *) POPA ();
2590         NULLCHECK (obj);
2591         PUSHI (*(jint *) (obj + INTVAL ()));
2592       }
2593       NEXT_INSN;
2594
2595     getfield_resolved_8:
2596       {
2597         char *obj = (char *) POPA ();
2598         NULLCHECK (obj);
2599         PUSHL (*(jlong *) (obj + INTVAL ()));
2600       }
2601       NEXT_INSN;
2602
2603     getfield_resolved_obj:
2604       {
2605         char *obj = (char *) POPA ();
2606         NULLCHECK (obj);
2607         PUSHA (*(jobject *) (obj + INTVAL ()));
2608       }
2609       NEXT_INSN;
2610 #endif /* DIRECT_THREADED */
2611
2612     insn_putstatic:
2613       {
2614         jint fieldref_index = GET2U ();
2615         _Jv_ResolvePoolEntry (defining_class, fieldref_index);
2616         _Jv_Field *field = pool_data[fieldref_index].field;
2617
2618         jclass type = field->type;
2619
2620         // ResolvePoolEntry cannot check this
2621         if ((field->flags & Modifier::STATIC) == 0)
2622           throw_incompatible_class_change_error 
2623             (JvNewStringLatin1 ("field no longer static"));
2624
2625         void *newinsn = NULL;
2626         if (type->isPrimitive ())
2627           {
2628             switch (type->size_in_bytes) 
2629               {
2630               case 1:
2631                 {
2632                   jint value = POPI();
2633                   *field->u.byte_addr = value;
2634                   newinsn = AMPAMP (putstatic_resolved_1);
2635                   break;
2636                 }
2637
2638               case 2:
2639                 {
2640                   jint value = POPI();
2641                   *field->u.char_addr = value;
2642                   newinsn = AMPAMP (putstatic_resolved_2);
2643                   break;
2644                 }
2645
2646               case 4:
2647                 {
2648                   jint value = POPI();
2649                   *field->u.int_addr = value;
2650                   newinsn = AMPAMP (putstatic_resolved_4);
2651                   break;
2652                 }
2653
2654               case 8:
2655                 {
2656                   jlong value = POPL();
2657                   *field->u.long_addr = value;
2658                   newinsn = AMPAMP (putstatic_resolved_8);
2659                   break;
2660                 }
2661               }
2662           }
2663         else
2664           {
2665             jobject value = POPA();
2666             *field->u.object_addr = value;
2667             newinsn = AMPAMP (putstatic_resolved_obj);
2668           }
2669
2670 #ifdef DIRECT_THREADED
2671         pc[-2].insn = newinsn;
2672         pc[-1].datum = field->u.addr;
2673 #endif /* DIRECT_THREADED */
2674       }
2675       NEXT_INSN;
2676
2677 #ifdef DIRECT_THREADED
2678     putstatic_resolved_1:
2679       *(jbyte *) AVAL () = POPI ();
2680       NEXT_INSN;
2681
2682     putstatic_resolved_2:
2683       *(jchar *) AVAL () = POPI ();
2684       NEXT_INSN;
2685
2686     putstatic_resolved_4:
2687       *(jint *) AVAL () = POPI ();
2688       NEXT_INSN;
2689
2690     putstatic_resolved_8:
2691       *(jlong *) AVAL () = POPL ();
2692       NEXT_INSN;
2693
2694     putstatic_resolved_obj:
2695       *(jobject *) AVAL () = POPA ();
2696       NEXT_INSN;
2697 #endif /* DIRECT_THREADED */
2698
2699     insn_putfield:
2700       {
2701         jint fieldref_index = GET2U ();
2702         _Jv_ResolvePoolEntry (defining_class, fieldref_index);
2703         _Jv_Field *field = pool_data[fieldref_index].field;
2704
2705         jclass type = field->type;
2706
2707         if ((field->flags & Modifier::STATIC) != 0)
2708           throw_incompatible_class_change_error 
2709             (JvNewStringLatin1 ("field is static"));
2710
2711         jint field_offset = field->u.boffset;
2712         if (field_offset > 0xffff)
2713           throw new java::lang::VirtualMachineError;
2714
2715         void *newinsn = NULL;
2716         if (type->isPrimitive ())
2717           {
2718             switch (type->size_in_bytes) 
2719               {
2720               case 1:
2721                 {
2722                   jint    value = POPI();
2723                   jobject obj   = POPA();
2724                   NULLCHECK(obj);
2725                   *(jbyte*) ((char*)obj + field_offset) = value;
2726                   newinsn = AMPAMP (putfield_resolved_1);
2727                   break;
2728                 }
2729
2730               case 2:
2731                 {
2732                   jint    value = POPI();
2733                   jobject obj   = POPA();
2734                   NULLCHECK(obj);
2735                   *(jchar*) ((char*)obj + field_offset) = value;
2736                   newinsn = AMPAMP (putfield_resolved_2);
2737                   break;
2738                 }
2739
2740               case 4:
2741                 {
2742                   jint    value = POPI();
2743                   jobject obj   = POPA();
2744                   NULLCHECK(obj);
2745                   *(jint*) ((char*)obj + field_offset) = value;
2746                   newinsn = AMPAMP (putfield_resolved_4);
2747                   break;
2748                 }
2749
2750               case 8:
2751                 {
2752                   jlong   value = POPL();
2753                   jobject obj   = POPA();
2754                   NULLCHECK(obj);
2755                   *(jlong*) ((char*)obj + field_offset) = value;
2756                   newinsn = AMPAMP (putfield_resolved_8);
2757                   break;
2758                 }
2759               }
2760           }
2761         else
2762           {
2763             jobject value = POPA();
2764             jobject obj   = POPA();
2765             NULLCHECK(obj);
2766             *(jobject*) ((char*)obj + field_offset) = value;
2767             newinsn = AMPAMP (putfield_resolved_obj);
2768           }
2769
2770 #ifdef DIRECT_THREADED
2771         pc[-2].insn = newinsn;
2772         pc[-1].int_val = field_offset;
2773 #endif /* DIRECT_THREADED */
2774       }
2775       NEXT_INSN;
2776
2777 #ifdef DIRECT_THREADED
2778     putfield_resolved_1:
2779       {
2780         jint val = POPI ();
2781         char *obj = (char *) POPA ();
2782         NULLCHECK (obj);
2783         *(jbyte *) (obj + INTVAL ()) = val;
2784       }
2785       NEXT_INSN;
2786
2787     putfield_resolved_2:
2788       {
2789         jint val = POPI ();
2790         char *obj = (char *) POPA ();
2791         NULLCHECK (obj);
2792         *(jchar *) (obj + INTVAL ()) = val;
2793       }
2794       NEXT_INSN;
2795
2796     putfield_resolved_4:
2797       {
2798         jint val = POPI ();
2799         char *obj = (char *) POPA ();
2800         NULLCHECK (obj);
2801         *(jint *) (obj + INTVAL ()) = val;
2802       }
2803       NEXT_INSN;
2804
2805     putfield_resolved_8:
2806       {
2807         jlong val = POPL ();
2808         char *obj = (char *) POPA ();
2809         NULLCHECK (obj);
2810         *(jlong *) (obj + INTVAL ()) = val;
2811       }
2812       NEXT_INSN;
2813
2814     putfield_resolved_obj:
2815       {
2816         jobject val = POPA ();
2817         char *obj = (char *) POPA ();
2818         NULLCHECK (obj);
2819         *(jobject *) (obj + INTVAL ()) = val;
2820       }
2821       NEXT_INSN;
2822 #endif /* DIRECT_THREADED */
2823
2824     insn_invokespecial:
2825       {
2826         int index = GET2U ();
2827
2828         rmeth = (_Jv_ResolvePoolEntry (defining_class, index)).rmethod;
2829
2830         sp -= rmeth->stack_item_count;
2831
2832         // We don't use NULLCHECK here because we can't rely on that
2833         // working for <init>.  So instead we do an explicit test.
2834         if (! sp[0].o)
2835           throw new java::lang::NullPointerException;
2836
2837         fun = (void (*)()) rmeth->method->ncode;
2838
2839 #ifdef DIRECT_THREADED
2840         // Rewrite instruction so that we use a faster pre-resolved
2841         // method.
2842         pc[-2].insn = &&invokespecial_resolved;
2843         pc[-1].datum = rmeth;
2844 #endif /* DIRECT_THREADED */
2845       }
2846       goto perform_invoke;
2847
2848 #ifdef DIRECT_THREADED
2849     invokespecial_resolved:
2850       {
2851         rmeth = (_Jv_ResolvedMethod *) AVAL ();
2852         sp -= rmeth->stack_item_count;
2853         // We don't use NULLCHECK here because we can't rely on that
2854         // working for <init>.  So instead we do an explicit test.
2855         if (! sp[0].o)
2856           throw new java::lang::NullPointerException;
2857         fun = (void (*)()) rmeth->method->ncode;
2858       }
2859       goto perform_invoke;
2860 #endif /* DIRECT_THREADED */
2861
2862     insn_invokestatic:
2863       {
2864         int index = GET2U ();
2865
2866         rmeth = (_Jv_ResolvePoolEntry (defining_class, index)).rmethod;
2867
2868         sp -= rmeth->stack_item_count;
2869
2870         fun = (void (*)()) rmeth->method->ncode;
2871
2872 #ifdef DIRECT_THREADED
2873         // Rewrite instruction so that we use a faster pre-resolved
2874         // method.
2875         pc[-2].insn = &&invokestatic_resolved;
2876         pc[-1].datum = rmeth;
2877 #endif /* DIRECT_THREADED */
2878       }
2879       goto perform_invoke;
2880
2881 #ifdef DIRECT_THREADED
2882     invokestatic_resolved:
2883       {
2884         rmeth = (_Jv_ResolvedMethod *) AVAL ();
2885         sp -= rmeth->stack_item_count;
2886         fun = (void (*)()) rmeth->method->ncode;
2887       }
2888       goto perform_invoke;
2889 #endif /* DIRECT_THREADED */
2890
2891     insn_invokeinterface:
2892       {
2893         int index = GET2U ();
2894
2895         rmeth = (_Jv_ResolvePoolEntry (defining_class, index)).rmethod;
2896
2897         sp -= rmeth->stack_item_count;
2898
2899         jobject rcv = sp[0].o;
2900
2901         NULLCHECK (rcv);
2902
2903         fun = (void (*)())
2904           _Jv_LookupInterfaceMethod (rcv->getClass (),
2905                                      rmeth->method->name,
2906                                      rmeth->method->signature);
2907
2908 #ifdef DIRECT_THREADED
2909         // Rewrite instruction so that we use a faster pre-resolved
2910         // method.
2911         pc[-2].insn = &&invokeinterface_resolved;
2912         pc[-1].datum = rmeth;
2913 #else
2914         // Skip dummy bytes.
2915         pc += 2;
2916 #endif /* DIRECT_THREADED */
2917       }
2918       goto perform_invoke;
2919
2920 #ifdef DIRECT_THREADED
2921     invokeinterface_resolved:
2922       {
2923         rmeth = (_Jv_ResolvedMethod *) AVAL ();
2924         sp -= rmeth->stack_item_count;
2925         jobject rcv = sp[0].o;
2926         NULLCHECK (rcv);
2927         fun = (void (*)())
2928           _Jv_LookupInterfaceMethod (rcv->getClass (),
2929                                      rmeth->method->name,
2930                                      rmeth->method->signature);
2931       }
2932       goto perform_invoke;
2933 #endif /* DIRECT_THREADED */
2934
2935     insn_new:
2936       {
2937         int index = GET2U ();
2938         jclass klass = (_Jv_ResolvePoolEntry (defining_class, index)).clazz;
2939         jobject res = _Jv_AllocObject (klass);
2940         PUSHA (res);
2941
2942 #ifdef DIRECT_THREADED
2943         pc[-2].insn = &&new_resolved;
2944         pc[-1].datum = klass;
2945 #endif /* DIRECT_THREADED */
2946       }
2947       NEXT_INSN;
2948
2949 #ifdef DIRECT_THREADED
2950     new_resolved:
2951       {
2952         jclass klass = (jclass) AVAL ();
2953         jobject res = _Jv_AllocObject (klass);
2954         PUSHA (res);
2955       }
2956       NEXT_INSN;
2957 #endif /* DIRECT_THREADED */
2958
2959     insn_newarray:
2960       {
2961         int atype = GET1U ();
2962         int size  = POPI();
2963         jobject result = _Jv_NewArray (atype, size);
2964         PUSHA (result);
2965       }
2966       NEXT_INSN;
2967
2968     insn_anewarray:
2969       {
2970         int index = GET2U ();
2971         jclass klass = (_Jv_ResolvePoolEntry (defining_class, index)).clazz;
2972         int size  = POPI();
2973         jobject result = _Jv_NewObjectArray (size, klass, 0);
2974         PUSHA (result);
2975
2976 #ifdef DIRECT_THREADED
2977         pc[-2].insn = &&anewarray_resolved;
2978         pc[-1].datum = klass;
2979 #endif /* DIRECT_THREADED */
2980       }
2981       NEXT_INSN;
2982
2983 #ifdef DIRECT_THREADED
2984     anewarray_resolved:
2985       {
2986         jclass klass = (jclass) AVAL ();
2987         int size = POPI ();
2988         jobject result = _Jv_NewObjectArray (size, klass, 0);
2989         PUSHA (result);
2990       }
2991       NEXT_INSN;
2992 #endif /* DIRECT_THREADED */
2993
2994     insn_arraylength:
2995       {
2996         __JArray *arr = (__JArray*)POPA();
2997         NULLARRAYCHECK (arr);
2998         PUSHI (arr->length);
2999       }
3000       NEXT_INSN;
3001
3002     insn_athrow:
3003       {
3004         jobject value = POPA();
3005         throw static_cast<jthrowable>(value);
3006       }
3007       NEXT_INSN;
3008
3009     insn_checkcast:
3010       {
3011         jobject value = POPA();
3012         jint index = GET2U ();
3013         jclass to = (_Jv_ResolvePoolEntry (defining_class, index)).clazz;
3014
3015         if (value != NULL && ! to->isInstance (value))
3016           throw new java::lang::ClassCastException (to->getName());
3017
3018         PUSHA (value);
3019
3020 #ifdef DIRECT_THREADED
3021         pc[-2].insn = &&checkcast_resolved;
3022         pc[-1].datum = to;
3023 #endif /* DIRECT_THREADED */
3024       }
3025       NEXT_INSN;
3026
3027 #ifdef DIRECT_THREADED
3028     checkcast_resolved:
3029       {
3030         jobject value = POPA ();
3031         jclass to = (jclass) AVAL ();
3032         if (value != NULL && ! to->isInstance (value))
3033           throw new java::lang::ClassCastException (to->getName());
3034         PUSHA (value);
3035       }
3036       NEXT_INSN;
3037 #endif /* DIRECT_THREADED */
3038
3039     insn_instanceof:
3040       {
3041         jobject value = POPA();
3042         jint index = GET2U ();
3043         jclass to = (_Jv_ResolvePoolEntry (defining_class, index)).clazz;
3044         PUSHI (to->isInstance (value));
3045
3046 #ifdef DIRECT_THREADED
3047         pc[-2].insn = &&instanceof_resolved;
3048         pc[-1].datum = to;
3049 #endif /* DIRECT_THREADED */
3050       }
3051       NEXT_INSN;
3052
3053 #ifdef DIRECT_THREADED
3054     instanceof_resolved:
3055       {
3056         jobject value = POPA ();
3057         jclass to = (jclass) AVAL ();
3058         PUSHI (to->isInstance (value));
3059       }
3060       NEXT_INSN;
3061 #endif /* DIRECT_THREADED */
3062
3063     insn_monitorenter:
3064       {
3065         jobject value = POPA();
3066         NULLCHECK(value);
3067         _Jv_MonitorEnter (value);
3068       }
3069       NEXT_INSN;
3070
3071     insn_monitorexit:
3072       {
3073         jobject value = POPA();
3074         NULLCHECK(value);
3075         _Jv_MonitorExit (value);
3076       }
3077       NEXT_INSN;
3078
3079     insn_ifnull:
3080       {
3081         jobject val = POPA();
3082         if (val == NULL)
3083           TAKE_GOTO;
3084         else
3085           SKIP_GOTO;
3086       }
3087       NEXT_INSN;
3088
3089     insn_ifnonnull:
3090       {
3091         jobject val = POPA();
3092         if (val != NULL)
3093           TAKE_GOTO;
3094         else
3095           SKIP_GOTO;
3096       }
3097       NEXT_INSN;
3098
3099     insn_multianewarray:
3100       {
3101         int kind_index = GET2U ();
3102         int dim        = GET1U ();
3103
3104         jclass type    
3105           = (_Jv_ResolvePoolEntry (defining_class, kind_index)).clazz;
3106         jint *sizes    = (jint*) __builtin_alloca (sizeof (jint)*dim);
3107
3108         for (int i = dim - 1; i >= 0; i--)
3109           {
3110             sizes[i] = POPI ();
3111           }
3112
3113         jobject res    = _Jv_NewMultiArray (type,dim, sizes);
3114
3115         PUSHA (res);
3116       }
3117       NEXT_INSN;
3118
3119 #ifndef DIRECT_THREADED
3120     insn_wide:
3121       {
3122         jint the_mod_op = get1u (pc++);
3123         jint wide       = get2u (pc); pc += 2;
3124
3125         switch (the_mod_op)
3126           {
3127           case op_istore:
3128             STOREI (wide);
3129             NEXT_INSN;
3130
3131           case op_fstore:
3132             STOREF (wide);
3133             NEXT_INSN;
3134
3135           case op_astore:
3136             STOREA (wide);
3137             NEXT_INSN;
3138
3139           case op_lload:
3140             LOADL (wide);
3141             NEXT_INSN;
3142
3143           case op_dload:
3144             LOADD (wide);
3145             NEXT_INSN;
3146
3147           case op_iload:
3148             LOADI (wide);
3149             NEXT_INSN;
3150
3151           case op_fload:
3152             LOADF (wide);
3153             NEXT_INSN;
3154
3155           case op_aload:
3156             LOADA (wide);
3157             NEXT_INSN;
3158
3159           case op_lstore:
3160             STOREL (wide);
3161             NEXT_INSN;
3162
3163           case op_dstore:
3164             STORED (wide);
3165             NEXT_INSN;
3166
3167           case op_ret:
3168             pc = (unsigned char*) PEEKA (wide);
3169             NEXT_INSN;
3170
3171           case op_iinc:
3172             {
3173               jint amount = get2s (pc); pc += 2;
3174               jint value = PEEKI (wide);
3175               POKEI (wide, value+amount);
3176             }
3177             NEXT_INSN;
3178
3179           default:
3180             throw_internal_error ("illegal bytecode modified by wide");
3181           }
3182
3183       }
3184 #endif /* DIRECT_THREADED */
3185     }
3186   catch (java::lang::Throwable *ex)
3187     {
3188 #ifdef DIRECT_THREADED
3189       void *logical_pc = (void *) ((insn_slot *) pc - 1);
3190 #else
3191       int logical_pc = pc - 1 - bytecode ();
3192 #endif
3193       _Jv_InterpException *exc = exceptions ();
3194       jclass exc_class = ex->getClass ();
3195
3196       for (int i = 0; i < exc_count; i++)
3197         {
3198           if (PCVAL (exc[i].start_pc) <= logical_pc
3199               && logical_pc < PCVAL (exc[i].end_pc))
3200             {
3201 #ifdef DIRECT_THREADED
3202               jclass handler = (jclass) exc[i].handler_type.p;
3203 #else
3204               jclass handler = NULL;
3205               if (exc[i].handler_type.i != 0)
3206                 handler = (_Jv_ResolvePoolEntry (defining_class,
3207                                                  exc[i].handler_type.i)).clazz;
3208 #endif /* DIRECT_THREADED */
3209
3210               if (handler == NULL || handler->isAssignableFrom (exc_class))
3211                 {
3212 #ifdef DIRECT_THREADED
3213                   pc = (insn_slot *) exc[i].handler_pc.p;
3214 #else
3215                   pc = bytecode () + exc[i].handler_pc.i;
3216 #endif /* DIRECT_THREADED */
3217                   sp = stack;
3218                   sp++->o = ex; // Push exception.
3219                   NEXT_INSN;
3220                 }
3221             }
3222         }
3223
3224       // No handler, so re-throw.
3225       throw ex;
3226     }
3227 }
3228
3229 static void
3230 throw_internal_error (char *msg)
3231 {
3232   throw new java::lang::InternalError (JvNewStringLatin1 (msg));
3233 }
3234
3235 static void 
3236 throw_incompatible_class_change_error (jstring msg)
3237 {
3238   throw new java::lang::IncompatibleClassChangeError (msg);
3239 }
3240
3241 #ifndef HANDLE_SEGV
3242 static java::lang::NullPointerException *null_pointer_exc;
3243 static void 
3244 throw_null_pointer_exception ()
3245 {
3246   if (null_pointer_exc == NULL)
3247     null_pointer_exc = new java::lang::NullPointerException;
3248
3249   throw null_pointer_exc;
3250 }
3251 #endif
3252
3253 #endif // INTERPRETER