OSDN Git Service

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