OSDN Git Service

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