OSDN Git Service

* interpret.cc (get_local_var_table) [DIRECT_THREADED]: Make sure the
[pf3gnuchains/gcc-fork.git] / libjava / interpret.cc
1 // interpret.cc - Code for the interpreter
2
3 /* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation
4
5    This file is part of libgcj.
6
7 This software is copyrighted work licensed under the terms of the
8 Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
9 details.  */
10
11 /* Author: Kresten Krab Thorup <krab@gnu.org>  */
12
13 #include <config.h>
14 #include <platform.h>
15
16 #pragma implementation "java-interp.h"
17
18 #include <jvm.h>
19 #include <java-cpool.h>
20 #include <java-interp.h>
21 #include <java/lang/System.h>
22 #include <java/lang/String.h>
23 #include <java/lang/Integer.h>
24 #include <java/lang/Long.h>
25 #include <java/lang/StringBuffer.h>
26 #include <java/lang/Class.h>
27 #include <java/lang/reflect/Modifier.h>
28 #include <java/lang/InternalError.h>
29 #include <java/lang/NullPointerException.h>
30 #include <java/lang/ArithmeticException.h>
31 #include <java/lang/IncompatibleClassChangeError.h>
32 #include <java/lang/InstantiationException.h>
33 #include <java/lang/Thread.h>
34 #include <java-insns.h>
35 #include <java-signal.h>
36 #include <java/lang/ClassFormatError.h>
37 #include <execution.h>
38 #include <java/lang/reflect/Modifier.h>
39
40 #include <jvmti.h>
41 #include "jvmti-int.h"
42
43 #include <gnu/gcj/jvmti/Breakpoint.h>
44 #include <gnu/gcj/jvmti/BreakpointManager.h>
45
46 #ifdef INTERPRETER
47
48 // Execution engine for interpreted code.
49 _Jv_InterpreterEngine _Jv_soleInterpreterEngine;
50
51 #include <stdlib.h>
52
53 using namespace gcj;
54
55 static void throw_internal_error (const char *msg)
56   __attribute__ ((__noreturn__));
57 static void throw_incompatible_class_change_error (jstring msg)
58   __attribute__ ((__noreturn__));
59 static void throw_null_pointer_exception ()
60   __attribute__ ((__noreturn__));
61
62 static void throw_class_format_error (jstring msg)
63         __attribute__ ((__noreturn__));
64 static void throw_class_format_error (const char *msg)
65         __attribute__ ((__noreturn__));
66
67 static void find_catch_location (jthrowable, jthread, jmethodID *, jlong *);
68
69 // A macro to facilitate JVMTI exception reporting
70 #define REPORT_EXCEPTION(Jthrowable)                    \
71   do {                                                  \
72     if (JVMTI_REQUESTED_EVENT (Exception))              \
73       _Jv_ReportJVMTIExceptionThrow (Jthrowable);       \
74   }                                                     \
75   while (0)
76
77 #ifdef DIRECT_THREADED
78 // Lock to ensure that methods are not compiled concurrently.
79 // We could use a finer-grained lock here, however it is not safe to use
80 // the Class monitor as user code in another thread could hold it.
81 static _Jv_Mutex_t compile_mutex;
82
83 void
84 _Jv_InitInterpreter()
85 {
86   _Jv_MutexInit (&compile_mutex);
87 }
88 #else
89 void _Jv_InitInterpreter() {}
90 #endif
91
92 // The breakpoint instruction. For the direct threaded case,
93 // _Jv_InterpMethod::compile will initialize breakpoint_insn
94 // the first time it is called.
95 #ifdef DIRECT_THREADED
96 insn_slot _Jv_InterpMethod::bp_insn_slot;
97 pc_t _Jv_InterpMethod::breakpoint_insn = NULL;
98 #else
99 unsigned char _Jv_InterpMethod::bp_insn_opcode
100   = static_cast<unsigned char> (op_breakpoint);
101 pc_t _Jv_InterpMethod::breakpoint_insn = &_Jv_InterpMethod::bp_insn_opcode;
102 #endif
103
104 extern "C" double __ieee754_fmod (double,double);
105
106 static inline void dupx (_Jv_word *sp, int n, int x)
107 {
108   // first "slide" n+x elements n to the right
109   int top = n-1;
110   for (int i = 0; i < n+x; i++)
111     {
112       sp[(top-i)] = sp[(top-i)-n];
113     }
114   
115   // next, copy the n top elements, n+x down
116   for (int i = 0; i < n; i++)
117     {
118       sp[top-(n+x)-i] = sp[top-i];
119     }
120 }
121
122 // Used to convert from floating types to integral types.
123 template<typename TO, typename FROM>
124 static inline TO
125 convert (FROM val, TO min, TO max)
126 {
127   TO ret;
128   if (val >= (FROM) max)
129     ret = max;
130   else if (val <= (FROM) min)
131     ret = min;
132   else if (val != val)
133     ret = 0;
134   else
135     ret = (TO) val;
136   return ret;
137 }
138
139 #define PUSHA(V)  (sp++)->o = (V)
140 #define PUSHI(V)  (sp++)->i = (V)
141 #define PUSHF(V)  (sp++)->f = (V)
142 #if SIZEOF_VOID_P == 8
143 # define PUSHL(V)   (sp->l = (V), sp += 2)
144 # define PUSHD(V)   (sp->d = (V), sp += 2)
145 #else
146 # define PUSHL(V)  do { _Jv_word2 w2; w2.l=(V); \
147                         (sp++)->ia[0] = w2.ia[0]; \
148                         (sp++)->ia[0] = w2.ia[1]; } while (0)
149 # define PUSHD(V)  do { _Jv_word2 w2; w2.d=(V); \
150                         (sp++)->ia[0] = w2.ia[0]; \
151                         (sp++)->ia[0] = w2.ia[1]; } while (0)
152 #endif
153
154 #define POPA()    ((--sp)->o)
155 #define POPI()    ((jint) (--sp)->i) // cast since it may be promoted
156 #define POPF()    ((jfloat) (--sp)->f)
157 #if SIZEOF_VOID_P == 8
158 # define POPL()   (sp -= 2, (jlong) sp->l)
159 # define POPD()   (sp -= 2, (jdouble) sp->d)
160 #else
161 # define POPL()    ({ _Jv_word2 w2; \
162                      w2.ia[1] = (--sp)->ia[0]; \
163                      w2.ia[0] = (--sp)->ia[0]; w2.l; })
164 # define POPD()    ({ _Jv_word2 w2; \
165                      w2.ia[1] = (--sp)->ia[0]; \
166                      w2.ia[0] = (--sp)->ia[0]; w2.d; })
167 #endif
168
169 #define LOADA(I)  (sp++)->o = locals[I].o
170 #define LOADI(I)  (sp++)->i = locals[I].i
171 #define LOADF(I)  (sp++)->f = locals[I].f
172 #if SIZEOF_VOID_P == 8
173 # define LOADL(I)  (sp->l = locals[I].l, sp += 2)
174 # define LOADD(I)  (sp->d = locals[I].d, sp += 2)
175 #else
176 # define LOADL(I)  do { jint __idx = (I); \
177                         (sp++)->ia[0] = locals[__idx].ia[0]; \
178                         (sp++)->ia[0] = locals[__idx+1].ia[0]; \
179                    } while (0)
180 # define LOADD(I)  LOADL(I)
181 #endif
182
183 #define STOREA(I)                       \
184   do                                    \
185     {                                   \
186       jint __idx = (I);                 \
187       DEBUG_LOCALS_INSN (__idx, 'o');   \
188       locals[__idx].o = (--sp)->o;      \
189     }                                   \
190   while (0)
191 #define STOREI(I)                       \
192   do                                    \
193     {                                   \
194       jint __idx = (I);                 \
195       DEBUG_LOCALS_INSN (__idx, 'i');   \
196       locals[__idx].i = (--sp)->i;      \
197   } while (0)
198 #define STOREF(I)                       \
199   do                                    \
200     {                                   \
201       jint __idx = (I);                 \
202       DEBUG_LOCALS_INSN (__idx, 'f');   \
203       locals[__idx].f = (--sp)->f;      \
204     }                                   \
205   while (0)
206 #if SIZEOF_VOID_P == 8
207 # define STOREL(I) \
208   do                                            \
209     {                                           \
210       jint __idx = (I);                         \
211       DEBUG_LOCALS_INSN (__idx, 'l');           \
212       DEBUG_LOCALS_INSN (__idx + 1, 'x');       \
213       (sp -= 2, locals[__idx].l = sp->l);       \
214     }                                           \
215   while (0)
216 # define STORED(I)                              \
217   do                                            \
218     {                                           \
219       jint __idx = (I);                         \
220       DEBUG_LOCALS_INSN (__idx, 'd');           \
221       DEBUG_LOCALS_INSN (__idx + 1, 'x');       \
222       (sp -= 2, locals[__idx].d = sp->d);       \
223     }                                           \
224   while (0)
225
226 #else
227 # define STOREL(I)                              \
228   do                                            \
229     {                                           \
230       jint __idx = (I);                         \
231       DEBUG_LOCALS_INSN (__idx, 'l');           \
232       DEBUG_LOCALS_INSN (__idx + 1, 'x');       \
233       locals[__idx + 1].ia[0] = (--sp)->ia[0];  \
234       locals[__idx].ia[0] = (--sp)->ia[0];      \
235     }                                           \
236   while (0)
237 # define STORED(I)                              \
238   do {                                          \
239     jint __idx = (I);                           \
240     DEBUG_LOCALS_INSN (__idx, 'd');             \
241     DEBUG_LOCALS_INSN (__idx + 1, 'x');         \
242     locals[__idx + 1].ia[0] = (--sp)->ia[0];    \
243     locals[__idx].ia[0] = (--sp)->ia[0];        \
244   } while (0)
245 #endif
246
247 #define PEEKI(I)  (locals+(I))->i
248 #define PEEKA(I)  (locals+(I))->o
249
250 #define POKEI(I,V)                      \
251   do                                    \
252     {                                   \
253       jint __idx = (I);                 \
254       DEBUG_LOCALS_INSN (__idx, 'i');   \
255       ((locals + __idx)->i = (V));      \
256     }                                   \
257   while (0)
258
259
260 #define BINOPI(OP) { \
261    jint value2 = POPI(); \
262    jint value1 = POPI(); \
263    PUSHI(value1 OP value2); \
264 }
265
266 #define BINOPF(OP) { \
267    jfloat value2 = POPF(); \
268    jfloat value1 = POPF(); \
269    PUSHF(value1 OP value2); \
270 }
271
272 #define BINOPL(OP) { \
273    jlong value2 = POPL(); \
274    jlong value1 = POPL(); \
275    PUSHL(value1 OP value2); \
276 }
277
278 #define BINOPD(OP) { \
279    jdouble value2 = POPD(); \
280    jdouble value1 = POPD(); \
281    PUSHD(value1 OP value2); \
282 }
283
284 static inline jint
285 get1s (unsigned char* loc)
286 {
287   return *(signed char*)loc;
288 }
289
290 static inline jint
291 get1u (unsigned char* loc)
292 {
293   return *loc;
294 }
295
296 static inline jint
297 get2s(unsigned char* loc)
298 {
299   return (((jint)*(signed char*)loc) << 8) | ((jint)*(loc+1));
300 }
301
302 static inline jint
303 get2u (unsigned char* loc)
304 {
305   return (((jint)(*loc)) << 8) | ((jint)*(loc+1));
306 }
307
308 static jint
309 get4 (unsigned char* loc)
310 {
311   return (((jint)(loc[0])) << 24) 
312        | (((jint)(loc[1])) << 16) 
313        | (((jint)(loc[2])) << 8) 
314        | (((jint)(loc[3])) << 0);
315 }
316
317 #define SAVE_PC() frame_desc.pc = pc
318
319 // We used to define this conditionally, depending on HANDLE_SEGV.
320 // However, that runs into a problem if a chunk in low memory is
321 // mapped and we try to look at a field near the end of a large
322 // object.  See PR 26858 for details.  It is, most likely, relatively
323 // inexpensive to simply do this check always.
324 #define NULLCHECK(X) \
325   do { SAVE_PC(); if ((X)==NULL) throw_null_pointer_exception (); } while (0)
326
327 // Note that we can still conditionally define NULLARRAYCHECK, since
328 // we know that all uses of an array will first reference the length
329 // field, which is first -- and thus will trigger a SEGV.
330 #ifdef HANDLE_SEGV
331 #define NULLARRAYCHECK(X) SAVE_PC()
332 #else
333 #define NULLARRAYCHECK(X)                                       \
334   do                                                            \
335     {                                                           \
336       SAVE_PC();                                                \
337       if ((X) == NULL) { throw_null_pointer_exception (); }     \
338     } while (0)
339 #endif
340
341 #define ARRAYBOUNDSCHECK(array, index)                          \
342   do                                                            \
343     {                                                           \
344       if (((unsigned) index) >= (unsigned) (array->length))     \
345         _Jv_ThrowBadArrayIndex (index);                         \
346     } while (0)
347
348 void
349 _Jv_InterpMethod::run_normal (ffi_cif *,
350                               void *ret,
351                               ffi_raw *args,
352                               void *__this)
353 {
354   _Jv_InterpMethod *_this = (_Jv_InterpMethod *) __this;
355   run (ret, args, _this);
356 }
357
358 void
359 _Jv_InterpMethod::run_normal_debug (ffi_cif *,
360                                     void *ret,
361                                     ffi_raw *args,
362                                     void *__this)
363 {
364   _Jv_InterpMethod *_this = (_Jv_InterpMethod *) __this;
365   run_debug (ret, args, _this);
366 }
367
368 void
369 _Jv_InterpMethod::run_synch_object (ffi_cif *,
370                                     void *ret,
371                                     ffi_raw *args,
372                                     void *__this)
373 {
374   _Jv_InterpMethod *_this = (_Jv_InterpMethod *) __this;
375
376   jobject rcv = (jobject) args[0].ptr;
377   JvSynchronize mutex (rcv);
378
379   run (ret, args, _this);
380 }
381
382 void
383 _Jv_InterpMethod::run_synch_object_debug (ffi_cif *,
384                                           void *ret,
385                                           ffi_raw *args,
386                                           void *__this)
387 {
388   _Jv_InterpMethod *_this = (_Jv_InterpMethod *) __this;
389
390   jobject rcv = (jobject) args[0].ptr;
391   JvSynchronize mutex (rcv);
392
393   run_debug (ret, args, _this);
394 }
395
396 void
397 _Jv_InterpMethod::run_class (ffi_cif *,
398                              void *ret,
399                              ffi_raw *args,
400                              void *__this)
401 {
402   _Jv_InterpMethod *_this = (_Jv_InterpMethod *) __this;
403   _Jv_InitClass (_this->defining_class);
404   run (ret, args, _this);
405 }
406
407 void
408 _Jv_InterpMethod::run_class_debug (ffi_cif *,
409                                    void *ret,
410                                    ffi_raw *args,
411                                    void *__this)
412 {
413   _Jv_InterpMethod *_this = (_Jv_InterpMethod *) __this;
414   _Jv_InitClass (_this->defining_class);
415   run_debug (ret, args, _this);
416 }
417
418 void
419 _Jv_InterpMethod::run_synch_class (ffi_cif *,
420                                    void *ret,
421                                    ffi_raw *args,
422                                    void *__this)
423 {
424   _Jv_InterpMethod *_this = (_Jv_InterpMethod *) __this;
425
426   jclass sync = _this->defining_class;
427   _Jv_InitClass (sync);
428   JvSynchronize mutex (sync);
429
430   run (ret, args, _this);
431 }
432
433 void
434 _Jv_InterpMethod::run_synch_class_debug (ffi_cif *,
435                                          void *ret,
436                                          ffi_raw *args,
437                                          void *__this)
438 {
439   _Jv_InterpMethod *_this = (_Jv_InterpMethod *) __this;
440
441   jclass sync = _this->defining_class;
442   _Jv_InitClass (sync);
443   JvSynchronize mutex (sync);
444
445   run_debug (ret, args, _this);
446 }
447
448 #ifdef DIRECT_THREADED
449 // "Compile" a method by turning it from bytecode to direct-threaded
450 // code.
451 void
452 _Jv_InterpMethod::compile (const void * const *insn_targets)
453 {
454   insn_slot *insns = NULL;
455   int next = 0;
456   unsigned char *codestart = bytecode ();
457   unsigned char *end = codestart + code_length;
458   _Jv_word *pool_data = defining_class->constants.data;
459
460 #define SET_ONE(Field, Value)                                                 \
461   do                                                                          \
462     {                                                                         \
463       if (first_pass)                                                         \
464         ++next;                                                               \
465       else                                                                    \
466         insns[next++].Field = Value;                                          \
467     }                                                                         \
468   while (0)
469
470 #define SET_INSN(Value) SET_ONE (insn, (void *) Value)
471 #define SET_INT(Value) SET_ONE (int_val, Value)
472 #define SET_DATUM(Value) SET_ONE (datum, Value)
473
474   // Map from bytecode PC to slot in INSNS.
475   int *pc_mapping = (int *) __builtin_alloca (sizeof (int) * code_length);
476   for (int i = 0; i < code_length; ++i)
477     pc_mapping[i] = -1;
478
479   for (int i = 0; i < 2; ++i)
480     {
481       jboolean first_pass = i == 0;
482
483       if (! first_pass)
484         {
485           insns = (insn_slot *) _Jv_AllocBytes (sizeof (insn_slot) * next);
486           number_insn_slots = next;
487           next = 0;
488         }
489
490       unsigned char *pc = codestart;
491       while (pc < end)
492         {
493           int base_pc_val = pc - codestart;
494           if (first_pass)
495             pc_mapping[base_pc_val] = next;
496
497           java_opcode opcode = (java_opcode) *pc++;
498           // Just elide NOPs.
499           if (opcode == op_nop)
500             continue;
501           SET_INSN (insn_targets[opcode]);
502
503           switch (opcode)
504             {
505             case op_nop:
506             case op_aconst_null:
507             case op_iconst_m1:
508             case op_iconst_0:
509             case op_iconst_1:
510             case op_iconst_2:
511             case op_iconst_3:
512             case op_iconst_4:
513             case op_iconst_5:
514             case op_lconst_0:
515             case op_lconst_1:
516             case op_fconst_0:
517             case op_fconst_1:
518             case op_fconst_2:
519             case op_dconst_0:
520             case op_dconst_1:
521             case op_iload_0:
522             case op_iload_1:
523             case op_iload_2:
524             case op_iload_3:
525             case op_lload_0:
526             case op_lload_1:
527             case op_lload_2:
528             case op_lload_3:
529             case op_fload_0:
530             case op_fload_1:
531             case op_fload_2:
532             case op_fload_3:
533             case op_dload_0:
534             case op_dload_1:
535             case op_dload_2:
536             case op_dload_3:
537             case op_aload_0:
538             case op_aload_1:
539             case op_aload_2:
540             case op_aload_3:
541             case op_iaload:
542             case op_laload:
543             case op_faload:
544             case op_daload:
545             case op_aaload:
546             case op_baload:
547             case op_caload:
548             case op_saload:
549             case op_istore_0:
550             case op_istore_1:
551             case op_istore_2:
552             case op_istore_3:
553             case op_lstore_0:
554             case op_lstore_1:
555             case op_lstore_2:
556             case op_lstore_3:
557             case op_fstore_0:
558             case op_fstore_1:
559             case op_fstore_2:
560             case op_fstore_3:
561             case op_dstore_0:
562             case op_dstore_1:
563             case op_dstore_2:
564             case op_dstore_3:
565             case op_astore_0:
566             case op_astore_1:
567             case op_astore_2:
568             case op_astore_3:
569             case op_iastore:
570             case op_lastore:
571             case op_fastore:
572             case op_dastore:
573             case op_aastore:
574             case op_bastore:
575             case op_castore:
576             case op_sastore:
577             case op_pop:
578             case op_pop2:
579             case op_dup:
580             case op_dup_x1:
581             case op_dup_x2:
582             case op_dup2:
583             case op_dup2_x1:
584             case op_dup2_x2:
585             case op_swap:
586             case op_iadd:
587             case op_isub:
588             case op_imul:
589             case op_idiv:
590             case op_irem:
591             case op_ishl:
592             case op_ishr:
593             case op_iushr:
594             case op_iand:
595             case op_ior:
596             case op_ixor:
597             case op_ladd:
598             case op_lsub:
599             case op_lmul:
600             case op_ldiv:
601             case op_lrem:
602             case op_lshl:
603             case op_lshr:
604             case op_lushr:
605             case op_land:
606             case op_lor:
607             case op_lxor:
608             case op_fadd:
609             case op_fsub:
610             case op_fmul:
611             case op_fdiv:
612             case op_frem:
613             case op_dadd:
614             case op_dsub:
615             case op_dmul:
616             case op_ddiv:
617             case op_drem:
618             case op_ineg:
619             case op_i2b:
620             case op_i2c:
621             case op_i2s:
622             case op_lneg:
623             case op_fneg:
624             case op_dneg:
625             case op_i2l:
626             case op_i2f:
627             case op_i2d:
628             case op_l2i:
629             case op_l2f:
630             case op_l2d:
631             case op_f2i:
632             case op_f2l:
633             case op_f2d:
634             case op_d2i:
635             case op_d2l:
636             case op_d2f:
637             case op_lcmp:
638             case op_fcmpl:
639             case op_fcmpg:
640             case op_dcmpl:
641             case op_dcmpg:
642             case op_monitorenter:
643             case op_monitorexit:
644             case op_ireturn:
645             case op_lreturn:
646             case op_freturn:
647             case op_dreturn:
648             case op_areturn:
649             case op_return:
650             case op_athrow:
651             case op_arraylength:
652               // No argument, nothing else to do.
653               break;
654
655             case op_bipush:
656               SET_INT (get1s (pc));
657               ++pc;
658               break;
659
660             case op_ldc:
661               {
662                 int index = get1u (pc);
663                 ++pc;
664                 // For an unresolved class we want to delay resolution
665                 // until execution.
666                 if (defining_class->constants.tags[index] == JV_CONSTANT_Class)
667                   {
668                     --next;
669                     SET_INSN (insn_targets[int (op_jsr_w) + 1]);
670                     SET_INT (index);
671                   }
672                 else
673                   SET_DATUM (pool_data[index].o);
674               }
675               break;
676
677             case op_ret:
678             case op_iload:
679             case op_lload:
680             case op_fload:
681             case op_dload:
682             case op_aload:
683             case op_istore:
684             case op_lstore:
685             case op_fstore:
686             case op_dstore:
687             case op_astore:
688             case op_newarray:
689               SET_INT (get1u (pc));
690               ++pc;
691               break;
692
693             case op_iinc:
694               SET_INT (get1u (pc));
695               SET_INT (get1s (pc + 1));
696               pc += 2;
697               break;
698
699             case op_ldc_w:
700               {
701                 int index = get2u (pc);
702                 pc += 2;
703                 // For an unresolved class we want to delay resolution
704                 // until execution.
705                 if (defining_class->constants.tags[index] == JV_CONSTANT_Class)
706                   {
707                     --next;
708                     SET_INSN (insn_targets[int (op_jsr_w) + 1]);
709                     SET_INT (index);
710                   }
711                 else
712                   SET_DATUM (pool_data[index].o);
713               }
714               break;
715
716             case op_ldc2_w:
717               {
718                 int index = get2u (pc);
719                 pc += 2;
720                 SET_DATUM (&pool_data[index]);
721               }
722               break;
723
724             case op_sipush:
725               SET_INT (get2s (pc));
726               pc += 2;
727               break;
728
729             case op_new:
730             case op_getstatic:
731             case op_getfield:
732             case op_putfield:
733             case op_putstatic:
734             case op_anewarray:
735             case op_instanceof:
736             case op_checkcast:
737             case op_invokespecial:
738             case op_invokestatic:
739             case op_invokevirtual:
740               SET_INT (get2u (pc));
741               pc += 2;
742               break;
743
744             case op_multianewarray:
745               SET_INT (get2u (pc));
746               SET_INT (get1u (pc + 2));
747               pc += 3;
748               break;
749
750             case op_jsr:
751             case op_ifeq:
752             case op_ifne:
753             case op_iflt:
754             case op_ifge:
755             case op_ifgt:
756             case op_ifle:
757             case op_if_icmpeq:
758             case op_if_icmpne:
759             case op_if_icmplt:
760             case op_if_icmpge:
761             case op_if_icmpgt:
762             case op_if_icmple:
763             case op_if_acmpeq:
764             case op_if_acmpne:
765             case op_ifnull:
766             case op_ifnonnull:
767             case op_goto:
768               {
769                 int offset = get2s (pc);
770                 pc += 2;
771
772                 int new_pc = base_pc_val + offset;
773
774                 bool orig_was_goto = opcode == op_goto;
775
776                 // Thread jumps.  We limit the loop count; this lets
777                 // us avoid infinite loops if the bytecode contains
778                 // such.  `10' is arbitrary.
779                 int count = 10;
780                 while (codestart[new_pc] == op_goto && count-- > 0)
781                   new_pc += get2s (&codestart[new_pc + 1]);
782
783                 // If the jump takes us to a `return' instruction and
784                 // the original branch was an unconditional goto, then
785                 // we hoist the return.
786                 opcode = (java_opcode) codestart[new_pc];
787                 if (orig_was_goto
788                     && (opcode == op_ireturn || opcode == op_lreturn
789                         || opcode == op_freturn || opcode == op_dreturn
790                         || opcode == op_areturn || opcode == op_return))
791                   {
792                     --next;
793                     SET_INSN (insn_targets[opcode]);
794                   }
795                 else
796                   SET_DATUM (&insns[pc_mapping[new_pc]]);
797               }
798               break;
799
800             case op_tableswitch:
801               {
802                 while ((pc - codestart) % 4 != 0)
803                   ++pc;
804
805                 jint def = get4 (pc);
806                 SET_DATUM (&insns[pc_mapping[base_pc_val + def]]);
807                 pc += 4;
808
809                 int low = get4 (pc);
810                 SET_INT (low);
811                 pc += 4;
812                 int high = get4 (pc);
813                 SET_INT (high);
814                 pc += 4;
815
816                 for (int i = low; i <= high; ++i)
817                   {
818                     SET_DATUM (&insns[pc_mapping[base_pc_val + get4 (pc)]]);
819                     pc += 4;
820                   }
821               }
822               break;
823
824             case op_lookupswitch:
825               {
826                 while ((pc - codestart) % 4 != 0)
827                   ++pc;
828
829                 jint def = get4 (pc);
830                 SET_DATUM (&insns[pc_mapping[base_pc_val + def]]);
831                 pc += 4;
832
833                 jint npairs = get4 (pc);
834                 pc += 4;
835                 SET_INT (npairs);
836
837                 while (npairs-- > 0)
838                   {
839                     jint match = get4 (pc);
840                     jint offset = get4 (pc + 4);
841                     SET_INT (match);
842                     SET_DATUM (&insns[pc_mapping[base_pc_val + offset]]);
843                     pc += 8;
844                   }
845               }
846               break;
847
848             case op_invokeinterface:
849               {
850                 jint index = get2u (pc);
851                 pc += 2;
852                 // We ignore the next two bytes.
853                 pc += 2;
854                 SET_INT (index);
855               }
856               break;
857
858             case op_wide:
859               {
860                 opcode = (java_opcode) get1u (pc);
861                 pc += 1;
862                 jint val = get2u (pc);
863                 pc += 2;
864
865                 // We implement narrow and wide instructions using the
866                 // same code in the interpreter.  So we rewrite the
867                 // instruction slot here.
868                 if (! first_pass)
869                   insns[next - 1].insn = (void *) insn_targets[opcode];
870                 SET_INT (val);
871
872                 if (opcode == op_iinc)
873                   {
874                     SET_INT (get2s (pc));
875                     pc += 2;
876                   }
877               }
878               break;
879
880             case op_jsr_w:
881             case op_goto_w:
882               {
883                 jint offset = get4 (pc);
884                 pc += 4;
885                 SET_DATUM (&insns[pc_mapping[base_pc_val + offset]]);
886               }
887               break;
888
889             // Some "can't happen" cases that we include for
890             // error-checking purposes.
891             case op_putfield_1:
892             case op_putfield_2:
893             case op_putfield_4:
894             case op_putfield_8:
895             case op_putfield_a:
896             case op_putstatic_1:
897             case op_putstatic_2:
898             case op_putstatic_4:
899             case op_putstatic_8:
900             case op_putstatic_a:
901             case op_getfield_1:
902             case op_getfield_2s:
903             case op_getfield_2u:
904             case op_getfield_4:
905             case op_getfield_8:
906             case op_getfield_a:
907             case op_getstatic_1:
908             case op_getstatic_2s:
909             case op_getstatic_2u:
910             case op_getstatic_4:
911             case op_getstatic_8:
912             case op_getstatic_a:
913             case op_breakpoint:
914             default:
915               // Fail somehow.
916               break;
917             }
918         }
919     }
920
921   // Now update exceptions.
922   _Jv_InterpException *exc = exceptions ();
923   for (int i = 0; i < exc_count; ++i)
924     {
925       exc[i].start_pc.p = &insns[pc_mapping[exc[i].start_pc.i]];
926       exc[i].end_pc.p = &insns[pc_mapping[exc[i].end_pc.i]];
927       exc[i].handler_pc.p = &insns[pc_mapping[exc[i].handler_pc.i]];
928       // FIXME: resolve_pool_entry can throw - we shouldn't be doing this
929       // during compilation.
930       jclass handler
931         = (_Jv_Linker::resolve_pool_entry (defining_class,
932                                              exc[i].handler_type.i)).clazz;
933       exc[i].handler_type.p = handler;
934     }
935
936   // Translate entries in the LineNumberTable from bytecode PC's to direct
937   // threaded interpreter instruction values.
938   for (int i = 0; i < line_table_len; i++)
939     {
940       int byte_pc = line_table[i].bytecode_pc;
941       // It isn't worth throwing an exception if this table is
942       // corrupted, but at the same time we don't want a crash.
943       if (byte_pc < 0 || byte_pc >= code_length)
944         byte_pc = 0;
945       line_table[i].pc = &insns[pc_mapping[byte_pc]];
946     }  
947
948   prepared = insns;
949
950   // Now remap the variable table for this method.
951   for (int i = 0; i < local_var_table_len; ++i)
952     {
953       int start_byte = local_var_table[i].bytecode_pc;
954       if (start_byte < 0 || start_byte >= code_length)
955         start_byte = 0;
956       jlocation start =  pc_mapping[start_byte];
957
958       int end_byte = start_byte + local_var_table[i].length;
959       if (end_byte < 0)
960         end_byte = 0;
961       jlocation end = ((end_byte >= code_length)
962                        ? number_insn_slots
963                        : pc_mapping[end_byte]);
964
965       local_var_table[i].pc = &insns[start];
966       local_var_table[i].length = end - start + 1;
967     }
968   
969   if (breakpoint_insn == NULL)
970     {
971       bp_insn_slot.insn = const_cast<void *> (insn_targets[op_breakpoint]);
972       breakpoint_insn = &bp_insn_slot;
973     }
974 }
975 #endif /* DIRECT_THREADED */
976
977 /* Run the given method.
978    When args is NULL, don't run anything -- just compile it. */
979 void
980 _Jv_InterpMethod::run (void *retp, ffi_raw *args, _Jv_InterpMethod *meth)
981 {
982 #undef DEBUG
983 #undef DEBUG_LOCALS_INSN
984 #define DEBUG_LOCALS_INSN(s, t) do {} while (0)
985
986 #include "interpret-run.cc"
987 }
988
989 void
990 _Jv_InterpMethod::run_debug (void *retp, ffi_raw *args, _Jv_InterpMethod *meth)
991 {
992 #define DEBUG
993 #undef DEBUG_LOCALS_INSN
994 #define DEBUG_LOCALS_INSN(s, t)  \
995   do    \
996     {   \
997       frame_desc.locals_type[s] = t;  \
998     }   \
999   while (0)
1000
1001 #include "interpret-run.cc"
1002 }
1003
1004 static void
1005 throw_internal_error (const char *msg)
1006 {
1007   jthrowable t = new java::lang::InternalError (JvNewStringLatin1 (msg));
1008   REPORT_EXCEPTION (t);
1009   throw t;
1010 }
1011
1012 static void 
1013 throw_incompatible_class_change_error (jstring msg)
1014 {
1015   jthrowable t = new java::lang::IncompatibleClassChangeError (msg);
1016   REPORT_EXCEPTION (t);
1017   throw t;
1018 }
1019
1020 static void 
1021 throw_null_pointer_exception ()
1022 {
1023   jthrowable t = new java::lang::NullPointerException;
1024   REPORT_EXCEPTION (t);
1025   throw t;
1026 }
1027
1028 /* Look up source code line number for given bytecode (or direct threaded
1029    interpreter) PC. */
1030 int
1031 _Jv_InterpMethod::get_source_line(pc_t mpc)
1032 {
1033   int line = line_table_len > 0 ? line_table[0].line : -1;
1034   for (int i = 1; i < line_table_len; i++)
1035     if (line_table[i].pc > mpc)
1036       break;
1037     else
1038       line = line_table[i].line;
1039
1040   return line;
1041 }
1042
1043 /** Do static initialization for fields with a constant initializer */
1044 void
1045 _Jv_InitField (jobject obj, jclass klass, int index)
1046 {
1047   using namespace java::lang::reflect;
1048
1049   if (obj != 0 && klass == 0)
1050     klass = obj->getClass ();
1051
1052   if (!_Jv_IsInterpretedClass (klass))
1053     return;
1054
1055   _Jv_InterpClass *iclass = (_Jv_InterpClass*)klass->aux_info;
1056
1057   _Jv_Field * field = (&klass->fields[0]) + index;
1058
1059   if (index > klass->field_count)
1060     throw_internal_error ("field out of range");
1061
1062   int init = iclass->field_initializers[index];
1063   if (init == 0)
1064     return;
1065
1066   _Jv_Constants *pool = &klass->constants;
1067   int tag = pool->tags[init];
1068
1069   if (! field->isResolved ())
1070     throw_internal_error ("initializing unresolved field");
1071
1072   if (obj==0 && ((field->flags & Modifier::STATIC) == 0))
1073     throw_internal_error ("initializing non-static field with no object");
1074
1075   void *addr = 0;
1076
1077   if ((field->flags & Modifier::STATIC) != 0)
1078     addr = (void*) field->u.addr;
1079   else
1080     addr = (void*) (((char*)obj) + field->u.boffset);
1081
1082   switch (tag)
1083     {
1084     case JV_CONSTANT_String:
1085       {
1086         jstring str;
1087         str = _Jv_NewStringUtf8Const (pool->data[init].utf8);
1088         pool->data[init].string = str;
1089         pool->tags[init] = JV_CONSTANT_ResolvedString;
1090       }
1091       /* fall through */
1092
1093     case JV_CONSTANT_ResolvedString:
1094       if (! (field->type == &java::lang::String::class$
1095              || field->type == &java::lang::Class::class$))
1096         throw_class_format_error ("string initialiser to non-string field");
1097
1098       *(jstring*)addr = pool->data[init].string;
1099       break;
1100
1101     case JV_CONSTANT_Integer:
1102       {
1103         int value = pool->data[init].i;
1104
1105         if (field->type == JvPrimClass (boolean))
1106           *(jboolean*)addr = (jboolean)value;
1107         
1108         else if (field->type == JvPrimClass (byte))
1109           *(jbyte*)addr = (jbyte)value;
1110         
1111         else if (field->type == JvPrimClass (char))
1112           *(jchar*)addr = (jchar)value;
1113
1114         else if (field->type == JvPrimClass (short))
1115           *(jshort*)addr = (jshort)value;
1116         
1117         else if (field->type == JvPrimClass (int))
1118           *(jint*)addr = (jint)value;
1119
1120         else
1121           throw_class_format_error ("erroneous field initializer");
1122       }  
1123       break;
1124
1125     case JV_CONSTANT_Long:
1126       if (field->type != JvPrimClass (long))
1127         throw_class_format_error ("erroneous field initializer");
1128
1129       *(jlong*)addr = _Jv_loadLong (&pool->data[init]);
1130       break;
1131
1132     case JV_CONSTANT_Float:
1133       if (field->type != JvPrimClass (float))
1134         throw_class_format_error ("erroneous field initializer");
1135
1136       *(jfloat*)addr = pool->data[init].f;
1137       break;
1138
1139     case JV_CONSTANT_Double:
1140       if (field->type != JvPrimClass (double))
1141         throw_class_format_error ("erroneous field initializer");
1142
1143       *(jdouble*)addr = _Jv_loadDouble (&pool->data[init]);
1144       break;
1145
1146     default:
1147       throw_class_format_error ("erroneous field initializer");
1148     }
1149 }
1150
1151 inline static unsigned char*
1152 skip_one_type (unsigned char* ptr)
1153 {
1154   int ch = *ptr++;
1155
1156   while (ch == '[')
1157     { 
1158       ch = *ptr++;
1159     }
1160   
1161   if (ch == 'L')
1162     {
1163       do { ch = *ptr++; } while (ch != ';');
1164     }
1165
1166   return ptr;
1167 }
1168
1169 static ffi_type*
1170 get_ffi_type_from_signature (unsigned char* ptr)
1171 {
1172   switch (*ptr) 
1173     {
1174     case 'L':
1175     case '[':
1176       return &ffi_type_pointer;
1177       break;
1178
1179     case 'Z':
1180       // On some platforms a bool is a byte, on others an int.
1181       if (sizeof (jboolean) == sizeof (jbyte))
1182         return &ffi_type_sint8;
1183       else
1184         {
1185           JvAssert (sizeof (jbyte) == sizeof (jint));
1186           return &ffi_type_sint32;
1187         }
1188       break;
1189
1190     case 'B':
1191       return &ffi_type_sint8;
1192       break;
1193       
1194     case 'C':
1195       return &ffi_type_uint16;
1196       break;
1197           
1198     case 'S': 
1199       return &ffi_type_sint16;
1200       break;
1201           
1202     case 'I':
1203       return &ffi_type_sint32;
1204       break;
1205           
1206     case 'J':
1207       return &ffi_type_sint64;
1208       break;
1209           
1210     case 'F':
1211       return &ffi_type_float;
1212       break;
1213           
1214     case 'D':
1215       return &ffi_type_double;
1216       break;
1217
1218     case 'V':
1219       return &ffi_type_void;
1220       break;
1221     }
1222
1223   throw_internal_error ("unknown type in signature");
1224 }
1225
1226 /* this function yields the number of actual arguments, that is, if the
1227  * function is non-static, then one is added to the number of elements
1228  * found in the signature */
1229
1230 int 
1231 _Jv_count_arguments (_Jv_Utf8Const *signature,
1232                      jboolean staticp)
1233 {
1234   unsigned char *ptr = (unsigned char*) signature->chars();
1235   int arg_count = staticp ? 0 : 1;
1236
1237   /* first, count number of arguments */
1238
1239   // skip '('
1240   ptr++;
1241
1242   // count args
1243   while (*ptr != ')')
1244     {
1245       ptr = skip_one_type (ptr);
1246       arg_count += 1;
1247     }
1248
1249   return arg_count;
1250 }
1251
1252 /* This beast will build a cif, given the signature.  Memory for
1253  * the cif itself and for the argument types must be allocated by the
1254  * caller.
1255  */
1256
1257 int 
1258 _Jv_init_cif (_Jv_Utf8Const* signature,
1259               int arg_count,
1260               jboolean staticp,
1261               ffi_cif *cif,
1262               ffi_type **arg_types,
1263               ffi_type **rtype_p)
1264 {
1265   unsigned char *ptr = (unsigned char*) signature->chars();
1266
1267   int arg_index = 0;            // arg number
1268   int item_count = 0;           // stack-item count
1269
1270   // setup receiver
1271   if (!staticp)
1272     {
1273       arg_types[arg_index++] = &ffi_type_pointer;
1274       item_count += 1;
1275     }
1276
1277   // skip '('
1278   ptr++;
1279
1280   // assign arg types
1281   while (*ptr != ')')
1282     {
1283       arg_types[arg_index++] = get_ffi_type_from_signature (ptr);
1284
1285       if (*ptr == 'J' || *ptr == 'D')
1286         item_count += 2;
1287       else
1288         item_count += 1;
1289
1290       ptr = skip_one_type (ptr);
1291     }
1292
1293   // skip ')'
1294   ptr++;
1295   ffi_type *rtype = get_ffi_type_from_signature (ptr);
1296
1297   ptr = skip_one_type (ptr);
1298   if (ptr != (unsigned char*)signature->chars() + signature->len())
1299     throw_internal_error ("did not find end of signature");
1300
1301   if (ffi_prep_cif (cif, FFI_DEFAULT_ABI,
1302                     arg_count, rtype, arg_types) != FFI_OK)
1303     throw_internal_error ("ffi_prep_cif failed");
1304
1305   if (rtype_p != NULL)
1306     *rtype_p = rtype;
1307
1308   return item_count;
1309 }
1310
1311 #if FFI_NATIVE_RAW_API
1312 #   define FFI_PREP_RAW_CLOSURE ffi_prep_raw_closure_loc
1313 #   define FFI_RAW_SIZE ffi_raw_size
1314 #else
1315 #   define FFI_PREP_RAW_CLOSURE ffi_prep_java_raw_closure_loc
1316 #   define FFI_RAW_SIZE ffi_java_raw_size
1317 #endif
1318
1319 /* we put this one here, and not in interpret.cc because it
1320  * calls the utility routines _Jv_count_arguments 
1321  * which are static to this module.  The following struct defines the
1322  * layout we use for the stubs, it's only used in the ncode method. */
1323
1324 typedef struct {
1325   ffi_raw_closure  closure;
1326   _Jv_ClosureList list;
1327   ffi_cif   cif;
1328   ffi_type *arg_types[0];
1329 } ncode_closure;
1330
1331 typedef void (*ffi_closure_fun) (ffi_cif*,void*,ffi_raw*,void*);
1332
1333 void *
1334 _Jv_InterpMethod::ncode (jclass klass)
1335 {
1336   using namespace java::lang::reflect;
1337
1338   if (self->ncode != 0)
1339     return self->ncode;
1340
1341   jboolean staticp = (self->accflags & Modifier::STATIC) != 0;
1342   int arg_count = _Jv_count_arguments (self->signature, staticp);
1343
1344   void *code;
1345   ncode_closure *closure =
1346     (ncode_closure*)ffi_closure_alloc (sizeof (ncode_closure)
1347                                        + arg_count * sizeof (ffi_type*),
1348                                        &code);
1349   closure->list.registerClosure (klass, closure);
1350
1351   _Jv_init_cif (self->signature,
1352                 arg_count,
1353                 staticp,
1354                 &closure->cif,
1355                 &closure->arg_types[0],
1356                 NULL);
1357
1358   ffi_closure_fun fun;
1359
1360   args_raw_size = FFI_RAW_SIZE (&closure->cif);
1361
1362   JvAssert ((self->accflags & Modifier::NATIVE) == 0);
1363
1364   if ((self->accflags & Modifier::SYNCHRONIZED) != 0)
1365     {
1366       if (staticp)
1367         {
1368           if (JVMTI::enabled)
1369             fun = (ffi_closure_fun)&_Jv_InterpMethod::run_synch_class_debug;
1370           else
1371             fun = (ffi_closure_fun)&_Jv_InterpMethod::run_synch_class;
1372         }
1373       else
1374         {
1375           if (JVMTI::enabled)
1376             fun = (ffi_closure_fun)&_Jv_InterpMethod::run_synch_object_debug;
1377           else
1378             fun = (ffi_closure_fun)&_Jv_InterpMethod::run_synch_object;
1379         }
1380     }
1381   else
1382     {
1383       if (staticp)
1384         {
1385           if (JVMTI::enabled)
1386             fun = (ffi_closure_fun)&_Jv_InterpMethod::run_class_debug;
1387           else
1388             fun = (ffi_closure_fun)&_Jv_InterpMethod::run_class;
1389         }
1390       else
1391         {
1392           if (JVMTI::enabled)
1393             fun = (ffi_closure_fun)&_Jv_InterpMethod::run_normal_debug;
1394           else
1395             fun = (ffi_closure_fun)&_Jv_InterpMethod::run_normal;
1396         }
1397     }
1398
1399   FFI_PREP_RAW_CLOSURE (&closure->closure,
1400                         &closure->cif, 
1401                         fun,
1402                         (void*)this,
1403                         code);
1404
1405   self->ncode = code;
1406
1407   return self->ncode;
1408 }
1409
1410 /* Find the index of the given insn in the array of insn slots
1411    for this method. Returns -1 if not found. */
1412 jlong
1413 _Jv_InterpMethod::insn_index (pc_t pc)
1414 {
1415   jlong left = 0;
1416 #ifdef DIRECT_THREADED
1417   jlong right = number_insn_slots;
1418   pc_t insns = prepared;
1419 #else
1420   jlong right = code_length;
1421   pc_t insns = bytecode ();
1422 #endif
1423
1424   while (right >= 0)
1425     {
1426       jlong mid = (left + right) / 2;
1427       if (&insns[mid] == pc)
1428         return mid;
1429
1430       if (pc < &insns[mid])
1431         right = mid - 1;
1432       else
1433         left = mid + 1;
1434     }
1435
1436   return -1;
1437 }
1438
1439 // Method to check if an exception is caught at some location in a method
1440 // (meth).  Returns true if this method (meth) contains a catch block for the
1441 // exception (ex). False otherwise.  If there is a catch block, it sets the pc
1442 // to the location of the beginning of the catch block.
1443 jboolean
1444 _Jv_InterpMethod::check_handler (pc_t *pc, _Jv_InterpMethod *meth,
1445                                 java::lang::Throwable *ex)
1446 {
1447 #ifdef DIRECT_THREADED
1448   void *logical_pc = (void *) ((insn_slot *) (*pc) - 1);
1449 #else
1450   int logical_pc = (*pc) - 1 - meth->bytecode ();
1451 #endif
1452   _Jv_InterpException *exc = meth->exceptions ();
1453   jclass exc_class = ex->getClass ();
1454
1455   for (int i = 0; i < meth->exc_count; i++)
1456     {
1457       if (PCVAL (exc[i].start_pc) <= logical_pc
1458           && logical_pc < PCVAL (exc[i].end_pc))
1459         {
1460 #ifdef DIRECT_THREADED
1461               jclass handler = (jclass) exc[i].handler_type.p;
1462 #else
1463               jclass handler = NULL;
1464               if (exc[i].handler_type.i != 0)
1465                     handler
1466                       = (_Jv_Linker::resolve_pool_entry (meth->defining_class,
1467                                                                              ex$
1468 #endif /* DIRECT_THREADED */
1469               if (handler == NULL || handler->isAssignableFrom (exc_class))
1470                 {
1471 #ifdef DIRECT_THREADED
1472                   (*pc) = (insn_slot *) exc[i].handler_pc.p;
1473 #else
1474                   (*pc) = meth->bytecode () + exc[i].handler_pc.i;
1475 #endif /* DIRECT_THREADED */
1476                   return true;
1477                 }
1478           }
1479       }
1480   return false;
1481 }
1482
1483
1484 void
1485 _Jv_InterpMethod::get_line_table (jlong& start, jlong& end,
1486                                   jintArray& line_numbers,
1487                                   jlongArray& code_indices)
1488 {
1489 #ifdef DIRECT_THREADED
1490   /* For the DIRECT_THREADED case, if the method has not yet been
1491    * compiled, the linetable will change to insn slots instead of
1492    * bytecode PCs. It is probably easiest, in this case, to simply
1493    * compile the method and guarantee that we are using insn
1494    * slots.
1495    */
1496   _Jv_CompileMethod (this);
1497
1498   if (line_table_len > 0)
1499     {
1500       start = 0;
1501       end = number_insn_slots;
1502       line_numbers = JvNewIntArray (line_table_len);
1503       code_indices = JvNewLongArray (line_table_len);
1504
1505       jint* lines = elements (line_numbers);
1506       jlong* indices = elements (code_indices);
1507       for (int i = 0; i < line_table_len; ++i)
1508         {
1509           lines[i] = line_table[i].line;
1510           indices[i] = insn_index (line_table[i].pc);
1511         }
1512     }
1513 #else // !DIRECT_THREADED
1514   if (line_table_len > 0)
1515     {
1516       start = 0;
1517       end = code_length;
1518       line_numbers = JvNewIntArray (line_table_len);
1519       code_indices = JvNewLongArray (line_table_len);
1520
1521       jint* lines = elements (line_numbers);
1522       jlong* indices = elements (code_indices);
1523       for (int i = 0; i < line_table_len; ++i)
1524         {
1525           lines[i] = line_table[i].line;
1526           indices[i] = (jlong) line_table[i].bytecode_pc;
1527         }
1528     }
1529 #endif // !DIRECT_THREADED
1530 }
1531
1532 int 
1533 _Jv_InterpMethod::get_local_var_table (char **name, char **sig, 
1534                                        char **generic_sig, jlong *startloc,
1535                                        jint *length, jint *slot, 
1536                                        int table_slot)
1537 {
1538 #ifdef DIRECT_THREADED
1539   _Jv_CompileMethod (this);
1540 #endif
1541
1542   if (local_var_table == NULL)
1543     return -2;
1544   if (table_slot >= local_var_table_len)
1545     return -1;
1546   else
1547     {
1548       *name = local_var_table[table_slot].name;
1549       *sig = local_var_table[table_slot].descriptor;
1550       *generic_sig = local_var_table[table_slot].descriptor;
1551
1552 #ifdef DIRECT_THREADED
1553       *startloc = insn_index (local_var_table[table_slot].pc);
1554 #else
1555       *startloc = static_cast<jlong> (local_var_table[table_slot].bytecode_pc);
1556 #endif
1557       *length = static_cast<jint> (local_var_table[table_slot].length);
1558       *slot = static_cast<jint> (local_var_table[table_slot].slot);
1559     }
1560   return local_var_table_len - table_slot - 1;
1561 }
1562
1563 pc_t
1564 _Jv_InterpMethod::install_break (jlong index)
1565 {
1566   return set_insn (index, breakpoint_insn);
1567 }
1568
1569 pc_t
1570 _Jv_InterpMethod::get_insn (jlong index)
1571 {
1572   pc_t code;
1573
1574 #ifdef DIRECT_THREADED
1575   if (index >= number_insn_slots || index < 0)
1576     return NULL;
1577
1578   code = prepared;
1579 #else // !DIRECT_THREADED
1580   if (index >= code_length || index < 0)
1581     return NULL;
1582
1583   code = reinterpret_cast<pc_t> (bytecode ());
1584 #endif // !DIRECT_THREADED
1585
1586   return &code[index];
1587 }
1588
1589 pc_t
1590 _Jv_InterpMethod::set_insn (jlong index, pc_t insn)
1591 {
1592 #ifdef DIRECT_THREADED
1593   if (index >= number_insn_slots || index < 0)
1594     return NULL;
1595
1596   pc_t code = prepared;
1597   code[index].insn = insn->insn;
1598 #else // !DIRECT_THREADED
1599   if (index >= code_length || index < 0)
1600     return NULL;
1601
1602   pc_t code = reinterpret_cast<pc_t> (bytecode ());
1603   code[index] = *insn;
1604 #endif // !DIRECT_THREADED
1605
1606   return &code[index];
1607 }
1608
1609 bool
1610 _Jv_InterpMethod::breakpoint_at (jlong index)
1611 {
1612   pc_t insn = get_insn (index);
1613   if (insn != NULL)
1614     {
1615 #ifdef DIRECT_THREADED
1616       return (insn->insn == breakpoint_insn->insn);
1617 #else
1618       pc_t code = reinterpret_cast<pc_t> (bytecode ());
1619       return (code[index] == breakpoint_insn);
1620 #endif
1621     }
1622
1623   return false;
1624 }
1625
1626 void *
1627 _Jv_JNIMethod::ncode (jclass klass)
1628 {
1629   using namespace java::lang::reflect;
1630
1631   if (self->ncode != 0)
1632     return self->ncode;
1633
1634   jboolean staticp = (self->accflags & Modifier::STATIC) != 0;
1635   int arg_count = _Jv_count_arguments (self->signature, staticp);
1636
1637   void *code;
1638   ncode_closure *closure =
1639     (ncode_closure*)ffi_closure_alloc (sizeof (ncode_closure)
1640                                        + arg_count * sizeof (ffi_type*),
1641                                        &code);
1642   closure->list.registerClosure (klass, closure);
1643
1644   ffi_type *rtype;
1645   _Jv_init_cif (self->signature,
1646                 arg_count,
1647                 staticp,
1648                 &closure->cif,
1649                 &closure->arg_types[0],
1650                 &rtype);
1651
1652   ffi_closure_fun fun;
1653
1654   args_raw_size = FFI_RAW_SIZE (&closure->cif);
1655
1656   // Initialize the argument types and CIF that represent the actual
1657   // underlying JNI function.
1658   int extra_args = 1;
1659   if ((self->accflags & Modifier::STATIC))
1660     ++extra_args;
1661   jni_arg_types = (ffi_type **) _Jv_AllocBytes ((extra_args + arg_count)
1662                                                 * sizeof (ffi_type *));
1663   int offset = 0;
1664   jni_arg_types[offset++] = &ffi_type_pointer;
1665   if ((self->accflags & Modifier::STATIC))
1666     jni_arg_types[offset++] = &ffi_type_pointer;
1667   memcpy (&jni_arg_types[offset], &closure->arg_types[0],
1668           arg_count * sizeof (ffi_type *));
1669
1670   if (ffi_prep_cif (&jni_cif, _Jv_platform_ffi_abi,
1671                     extra_args + arg_count, rtype,
1672                     jni_arg_types) != FFI_OK)
1673     throw_internal_error ("ffi_prep_cif failed for JNI function");
1674
1675   JvAssert ((self->accflags & Modifier::NATIVE) != 0);
1676
1677   // FIXME: for now we assume that all native methods for
1678   // interpreted code use JNI.
1679   fun = (ffi_closure_fun) &_Jv_JNIMethod::call;
1680
1681   FFI_PREP_RAW_CLOSURE (&closure->closure,
1682                         &closure->cif, 
1683                         fun,
1684                         (void*) this,
1685                         code);
1686
1687   self->ncode = code;
1688   return self->ncode;
1689 }
1690
1691 static void
1692 throw_class_format_error (jstring msg)
1693 {
1694   jthrowable t = (msg
1695          ? new java::lang::ClassFormatError (msg)
1696          : new java::lang::ClassFormatError);
1697   REPORT_EXCEPTION (t);
1698   throw t;
1699 }
1700
1701 static void
1702 throw_class_format_error (const char *msg)
1703 {
1704   throw_class_format_error (JvNewStringLatin1 (msg));
1705 }
1706
1707 /* This function finds the method and location where the exception EXC
1708    is caught in the stack frame. On return, it sets CATCH_METHOD and
1709    CATCH_LOCATION with the method and location where the catch will
1710    occur. If the exception is not caught, these are set to 0.
1711
1712    This function should only be used with the DEBUG interpreter. */
1713 static void
1714 find_catch_location (::java::lang::Throwable *exc, jthread thread,
1715                      jmethodID *catch_method, jlong *catch_loc)
1716 {
1717   *catch_method = 0;
1718   *catch_loc = 0;
1719
1720   _Jv_InterpFrame *frame
1721     = reinterpret_cast<_Jv_InterpFrame *> (thread->interp_frame);
1722   while (frame != NULL)
1723     {
1724       pc_t pc = frame->get_pc ();
1725       _Jv_InterpMethod *imeth
1726         = reinterpret_cast<_Jv_InterpMethod *> (frame->self);
1727       if (imeth->check_handler (&pc, imeth, exc))
1728         {
1729           // This method handles the exception.
1730           *catch_method = imeth->get_method ();
1731           *catch_loc = imeth->insn_index (pc);
1732           return;
1733         }
1734
1735       frame = frame->next_interp;
1736     }
1737 }
1738
1739 /* This method handles JVMTI notifications of thrown exceptions. It
1740    calls find_catch_location to figure out where the exception is
1741    caught (if it is caught).
1742    
1743    Like find_catch_location, this should only be called with the
1744    DEBUG interpreter. Since a few exceptions occur outside the
1745    interpreter proper, it is important to not call this function
1746    without checking JVMTI_REQUESTED_EVENT(Exception) first. */
1747 void
1748 _Jv_ReportJVMTIExceptionThrow (jthrowable ex)
1749 {
1750   jthread thread = ::java::lang::Thread::currentThread ();
1751   _Jv_Frame *frame = reinterpret_cast<_Jv_Frame *> (thread->frame);
1752   jmethodID throw_meth = frame->self->get_method ();
1753   jlocation throw_loc = -1;
1754   if (frame->frame_type == frame_interpreter)
1755     {
1756       _Jv_InterpFrame * iframe
1757         = reinterpret_cast<_Jv_InterpFrame *> (frame);
1758       _Jv_InterpMethod *imeth
1759         = reinterpret_cast<_Jv_InterpMethod *> (frame->self);
1760       throw_loc = imeth->insn_index (iframe->get_pc ());
1761     }
1762
1763   jlong catch_loc;
1764   jmethodID catch_method;
1765   find_catch_location (ex, thread, &catch_method, &catch_loc);
1766   _Jv_JVMTI_PostEvent (JVMTI_EVENT_EXCEPTION, thread,
1767                        _Jv_GetCurrentJNIEnv (), throw_meth, throw_loc,
1768                        ex, catch_method, catch_loc);
1769 }
1770
1771 \f
1772
1773 void
1774 _Jv_InterpreterEngine::do_verify (jclass klass)
1775 {
1776   _Jv_InterpClass *iclass = (_Jv_InterpClass *) klass->aux_info;
1777   for (int i = 0; i < klass->method_count; i++)
1778     {
1779       using namespace java::lang::reflect;
1780       _Jv_MethodBase *imeth = iclass->interpreted_methods[i];
1781       _Jv_ushort accflags = klass->methods[i].accflags;
1782       if ((accflags & (Modifier::NATIVE | Modifier::ABSTRACT)) == 0)
1783         {
1784           _Jv_InterpMethod *im = reinterpret_cast<_Jv_InterpMethod *> (imeth);
1785           _Jv_VerifyMethod (im);
1786         }
1787     }
1788 }
1789
1790 void
1791 _Jv_InterpreterEngine::do_create_ncode (jclass klass)
1792 {
1793   _Jv_InterpClass *iclass = (_Jv_InterpClass *) klass->aux_info;
1794   for (int i = 0; i < klass->method_count; i++)
1795     {
1796       // Just skip abstract methods.  This is particularly important
1797       // because we don't resize the interpreted_methods array when
1798       // miranda methods are added to it.
1799       if ((klass->methods[i].accflags
1800            & java::lang::reflect::Modifier::ABSTRACT)
1801           != 0)
1802         continue;
1803
1804       _Jv_MethodBase *imeth = iclass->interpreted_methods[i];
1805
1806       if ((klass->methods[i].accflags & java::lang::reflect::Modifier::NATIVE)
1807           != 0)
1808         {
1809           // You might think we could use a virtual `ncode' method in
1810           // the _Jv_MethodBase and unify the native and non-native
1811           // cases.  Well, we can't, because we don't allocate these
1812           // objects using `new', and thus they don't get a vtable.
1813           _Jv_JNIMethod *jnim = reinterpret_cast<_Jv_JNIMethod *> (imeth);
1814           klass->methods[i].ncode = jnim->ncode (klass);
1815         }
1816       else if (imeth != 0)              // it could be abstract
1817         {
1818           _Jv_InterpMethod *im = reinterpret_cast<_Jv_InterpMethod *> (imeth);
1819           klass->methods[i].ncode = im->ncode (klass);
1820         }
1821     }
1822 }
1823
1824 _Jv_ClosureList **
1825 _Jv_InterpreterEngine::do_get_closure_list (jclass klass)
1826 {
1827   _Jv_InterpClass *iclass = (_Jv_InterpClass *) klass->aux_info;
1828
1829   if (!iclass->closures)
1830     iclass->closures = _Jv_ClosureListFinalizer ();
1831
1832   return iclass->closures;
1833 }
1834
1835 void
1836 _Jv_InterpreterEngine::do_allocate_static_fields (jclass klass,
1837                                                   int pointer_size,
1838                                                   int other_size)
1839 {
1840   _Jv_InterpClass *iclass = (_Jv_InterpClass *) klass->aux_info;
1841
1842   // Splitting the allocations here lets us scan reference fields and
1843   // avoid scanning non-reference fields.  How reference fields are
1844   // scanned is a bit tricky: we allocate using _Jv_AllocRawObj, which
1845   // means that this memory will be scanned conservatively (same
1846   // difference, since we know all the contents here are pointers).
1847   // Then we put pointers into this memory into the 'fields'
1848   // structure.  Most of these are interior pointers, which is ok (but
1849   // even so the pointer to the first reference field will be used and
1850   // that is not an interior pointer).  The 'fields' array is also
1851   // allocated with _Jv_AllocRawObj (see defineclass.cc), so it will
1852   // be scanned.  A pointer to this array is held by Class and thus
1853   // seen by the collector.
1854   char *reference_fields = (char *) _Jv_AllocRawObj (pointer_size);
1855   char *non_reference_fields = (char *) _Jv_AllocBytes (other_size);
1856
1857   for (int i = 0; i < klass->field_count; i++)
1858     {
1859       _Jv_Field *field = &klass->fields[i];
1860
1861       if ((field->flags & java::lang::reflect::Modifier::STATIC) == 0)
1862         continue;
1863
1864       char *base = field->isRef() ? reference_fields : non_reference_fields;
1865       field->u.addr  = base + field->u.boffset;
1866
1867       if (iclass->field_initializers[i] != 0)
1868         {
1869           _Jv_Linker::resolve_field (field, klass->loader);
1870           _Jv_InitField (0, klass, i);
1871         }
1872     }
1873
1874   // Now we don't need the field_initializers anymore, so let the
1875   // collector get rid of it.
1876   iclass->field_initializers = 0;
1877 }
1878
1879 _Jv_ResolvedMethod *
1880 _Jv_InterpreterEngine::do_resolve_method (_Jv_Method *method, jclass klass,
1881                                           jboolean staticp)
1882 {
1883   int arg_count = _Jv_count_arguments (method->signature, staticp);
1884
1885   _Jv_ResolvedMethod* result = (_Jv_ResolvedMethod*)
1886     _Jv_AllocBytes (sizeof (_Jv_ResolvedMethod)
1887                     + arg_count*sizeof (ffi_type*));
1888
1889   result->stack_item_count
1890     = _Jv_init_cif (method->signature,
1891                     arg_count,
1892                     staticp,
1893                     &result->cif,
1894                     &result->arg_types[0],
1895                     NULL);
1896
1897   result->method              = method;
1898   result->klass               = klass;
1899
1900   return result;
1901 }
1902
1903 void
1904 _Jv_InterpreterEngine::do_post_miranda_hook (jclass klass)
1905 {
1906   _Jv_InterpClass *iclass = (_Jv_InterpClass *) klass->aux_info;
1907   for (int i = 0; i < klass->method_count; i++)
1908     {
1909       // Just skip abstract methods.  This is particularly important
1910       // because we don't resize the interpreted_methods array when
1911       // miranda methods are added to it.
1912       if ((klass->methods[i].accflags
1913            & java::lang::reflect::Modifier::ABSTRACT)
1914           != 0)
1915         continue;
1916       // Miranda method additions mean that the `methods' array moves.
1917       // We cache a pointer into this array, so we have to update.
1918       iclass->interpreted_methods[i]->self = &klass->methods[i];
1919     }
1920 }
1921
1922 #ifdef DIRECT_THREADED
1923 void
1924 _Jv_CompileMethod (_Jv_InterpMethod* method)
1925 {
1926   if (method->prepared == NULL)
1927     {
1928       if (JVMTI::enabled)
1929         _Jv_InterpMethod::run_debug (NULL, NULL, method);
1930       else
1931       _Jv_InterpMethod::run (NULL, NULL, method);
1932     }
1933 }
1934 #endif // DIRECT_THREADED
1935
1936 #endif // INTERPRETER