OSDN Git Service

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