OSDN Git Service

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