// interpret.cc - Code for the interpreter

/* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation

   This file is part of libgcj.

This software is copyrighted work licensed under the terms of the
Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
details.  */

/* Author: Kresten Krab Thorup <krab@gnu.org>  */

#include <config.h>
#include <platform.h>

#pragma implementation "java-interp.h"

#include <jvm.h>
#include <java-cpool.h>
#include <java-interp.h>
#include <java/lang/System.h>
#include <java/lang/String.h>
#include <java/lang/Integer.h>
#include <java/lang/Long.h>
#include <java/lang/StringBuffer.h>
#include <java/lang/Class.h>
#include <java/lang/reflect/Modifier.h>
#include <java/lang/InternalError.h>
#include <java/lang/NullPointerException.h>
#include <java/lang/ArithmeticException.h>
#include <java/lang/IncompatibleClassChangeError.h>
#include <java/lang/InstantiationException.h>
#include <java/lang/Thread.h>
#include <java-insns.h>
#include <java-signal.h>
#include <java/lang/ClassFormatError.h>
#include <execution.h>
#include <java/lang/reflect/Modifier.h>

#include <jvmti.h>
#include "jvmti-int.h"

#include <gnu/gcj/jvmti/Breakpoint.h>
#include <gnu/gcj/jvmti/BreakpointManager.h>

// Execution engine for interpreted code.
_Jv_InterpreterEngine _Jv_soleInterpreterEngine;

#include <stdlib.h>

using namespace gcj;

static void throw_internal_error (const char *msg)
  __attribute__ ((__noreturn__));
static void throw_incompatible_class_change_error (jstring msg)
  __attribute__ ((__noreturn__));
static void throw_null_pointer_exception ()
  __attribute__ ((__noreturn__));

static void throw_class_format_error (jstring msg)
	__attribute__ ((__noreturn__));
static void throw_class_format_error (const char *msg)
	__attribute__ ((__noreturn__));

static void find_catch_location (jthrowable, jthread, jmethodID *, jlong *);

// A macro to facilitate JVMTI exception reporting
#define REPORT_EXCEPTION(Jthrowable)			\
  do {							\
    if (JVMTI_REQUESTED_EVENT (Exception))		\
      _Jv_ReportJVMTIExceptionThrow (Jthrowable);	\
  }							\
  while (0)

#ifdef DIRECT_THREADED
// Lock to ensure that methods are not compiled concurrently.
// We could use a finer-grained lock here, however it is not safe to use
// the Class monitor as user code in another thread could hold it.
static _Jv_Mutex_t compile_mutex;

// See class ThreadCountAdjuster and REWRITE_INSN for how this is
// used.
_Jv_Mutex_t _Jv_InterpMethod::rewrite_insn_mutex;

void
_Jv_InitInterpreter()
{
  _Jv_MutexInit (&compile_mutex);
  _Jv_MutexInit (&_Jv_InterpMethod::rewrite_insn_mutex);
}
#else
void _Jv_InitInterpreter() {}
#endif

// The breakpoint instruction. For the direct threaded case,
// _Jv_InterpMethod::compile will initialize breakpoint_insn
// the first time it is called.
#ifdef DIRECT_THREADED
insn_slot _Jv_InterpMethod::bp_insn_slot;
pc_t _Jv_InterpMethod::breakpoint_insn = NULL;
#else
unsigned char _Jv_InterpMethod::bp_insn_opcode
  = static_cast<unsigned char> (op_breakpoint);
pc_t _Jv_InterpMethod::breakpoint_insn = &_Jv_InterpMethod::bp_insn_opcode;
#endif

extern "C" double __ieee754_fmod (double,double);

static inline void dupx (_Jv_word *sp, int n, int x)
{
  // first "slide" n+x elements n to the right
  int top = n-1;
  for (int i = 0; i < n+x; i++)
    {
      sp[(top-i)] = sp[(top-i)-n];
    }
  
  // next, copy the n top elements, n+x down
  for (int i = 0; i < n; i++)
    {
      sp[top-(n+x)-i] = sp[top-i];
    }
}

// Used to convert from floating types to integral types.
template<typename TO, typename FROM>
static inline TO
convert (FROM val, TO min, TO max)
{
  TO ret;
  if (val >= (FROM) max)
    ret = max;
  else if (val <= (FROM) min)
    ret = min;
  else if (val != val)
    ret = 0;
  else
    ret = (TO) val;
  return ret;
}

#define PUSHA(V)  (sp++)->o = (V)
#define PUSHI(V)  (sp++)->i = (V)
#define PUSHF(V)  (sp++)->f = (V)
#if SIZEOF_VOID_P == 8
# define PUSHL(V)   (sp->l = (V), sp += 2)
# define PUSHD(V)   (sp->d = (V), sp += 2)
#else
# define PUSHL(V)  do { _Jv_word2 w2; w2.l=(V); \
                        (sp++)->ia[0] = w2.ia[0]; \
                        (sp++)->ia[0] = w2.ia[1]; } while (0)
# define PUSHD(V)  do { _Jv_word2 w2; w2.d=(V); \
                        (sp++)->ia[0] = w2.ia[0]; \
                        (sp++)->ia[0] = w2.ia[1]; } while (0)
#endif

#define POPA()    ((--sp)->o)
#define POPI()    ((jint) (--sp)->i) // cast since it may be promoted
#define POPF()    ((jfloat) (--sp)->f)
#if SIZEOF_VOID_P == 8
# define POPL()	  (sp -= 2, (jlong) sp->l)
# define POPD()	  (sp -= 2, (jdouble) sp->d)
#else
# define POPL()    ({ _Jv_word2 w2; \
                     w2.ia[1] = (--sp)->ia[0]; \
                     w2.ia[0] = (--sp)->ia[0]; w2.l; })
# define POPD()    ({ _Jv_word2 w2; \
                     w2.ia[1] = (--sp)->ia[0]; \
                     w2.ia[0] = (--sp)->ia[0]; w2.d; })
#endif

#define LOADA(I)  (sp++)->o = locals[I].o
#define LOADI(I)  (sp++)->i = locals[I].i
#define LOADF(I)  (sp++)->f = locals[I].f
#if SIZEOF_VOID_P == 8
# define LOADL(I)  (sp->l = locals[I].l, sp += 2)
# define LOADD(I)  (sp->d = locals[I].d, sp += 2)
#else
# define LOADL(I)  do { jint __idx = (I); \
    			(sp++)->ia[0] = locals[__idx].ia[0]; \
    			(sp++)->ia[0] = locals[__idx+1].ia[0]; \
 		   } while (0)
# define LOADD(I)  LOADL(I)
#endif

#define STOREA(I)			\
  do					\
    {					\
      jint __idx = (I);			\
      DEBUG_LOCALS_INSN (__idx, 'o');	\
      locals[__idx].o = (--sp)->o;	\
    }					\
  while (0)
#define STOREI(I)		       	\
  do					\
    {					\
      jint __idx = (I);			\
      DEBUG_LOCALS_INSN (__idx, 'i');	\
      locals[__idx].i = (--sp)->i;	\
  } while (0)
#define STOREF(I)			\
  do					\
    {					\
      jint __idx = (I);			\
      DEBUG_LOCALS_INSN (__idx, 'f');	\
      locals[__idx].f = (--sp)->f;	\
    }					\
  while (0)
#if SIZEOF_VOID_P == 8
# define STOREL(I) \
  do						\
    {						\
      jint __idx = (I);				\
      DEBUG_LOCALS_INSN (__idx, 'l');		\
      DEBUG_LOCALS_INSN (__idx + 1, 'x');	\
      (sp -= 2, locals[__idx].l = sp->l);	\
    }						\
  while (0)
# define STORED(I)				\
  do						\
    {						\
      jint __idx = (I);				\
      DEBUG_LOCALS_INSN (__idx, 'd');		\
      DEBUG_LOCALS_INSN (__idx + 1, 'x');	\
      (sp -= 2, locals[__idx].d = sp->d);	\
    }						\
  while (0)

#else
# define STOREL(I)				\
  do						\
    {						\
      jint __idx = (I);				\
      DEBUG_LOCALS_INSN (__idx, 'l');		\
      DEBUG_LOCALS_INSN (__idx + 1, 'x');	\
      locals[__idx + 1].ia[0] = (--sp)->ia[0];	\
      locals[__idx].ia[0] = (--sp)->ia[0];	\
    }						\
  while (0)
# define STORED(I)				\
  do {						\
    jint __idx = (I);				\
    DEBUG_LOCALS_INSN (__idx, 'd');		\
    DEBUG_LOCALS_INSN (__idx + 1, 'x');		\
    locals[__idx + 1].ia[0] = (--sp)->ia[0];	\
    locals[__idx].ia[0] = (--sp)->ia[0];	\
  } while (0)
#endif

#define PEEKI(I)  (locals+(I))->i
#define PEEKA(I)  (locals+(I))->o

#define POKEI(I,V)			\
  do					\
    {					\
      jint __idx = (I);			\
      DEBUG_LOCALS_INSN (__idx, 'i');	\
      ((locals + __idx)->i = (V));	\
    }					\
  while (0)


#define BINOPI(OP) { \
   jint value2 = POPI(); \
   jint value1 = POPI(); \
   PUSHI(value1 OP value2); \
}

#define BINOPF(OP) { \
   jfloat value2 = POPF(); \
   jfloat value1 = POPF(); \
   PUSHF(value1 OP value2); \
}

#define BINOPL(OP) { \
   jlong value2 = POPL(); \
   jlong value1 = POPL(); \
   PUSHL(value1 OP value2); \
}

#define BINOPD(OP) { \
   jdouble value2 = POPD(); \
   jdouble value1 = POPD(); \
   PUSHD(value1 OP value2); \
}

static inline jint
get1s (unsigned char* loc)
{
  return *(signed char*)loc;
}

static inline jint
get1u (unsigned char* loc)
{
  return *loc;
}

static inline jint
get2s(unsigned char* loc)
{
  return (((jint)*(signed char*)loc) << 8) | ((jint)*(loc+1));
}

static inline jint
get2u (unsigned char* loc)
{
  return (((jint)(*loc)) << 8) | ((jint)*(loc+1));
}

static jint
get4 (unsigned char* loc)
{
  return (((jint)(loc[0])) << 24) 
       | (((jint)(loc[1])) << 16) 
       | (((jint)(loc[2])) << 8) 
       | (((jint)(loc[3])) << 0);
}

#define SAVE_PC() frame_desc.pc = pc

// We used to define this conditionally, depending on HANDLE_SEGV.
// However, that runs into a problem if a chunk in low memory is
// mapped and we try to look at a field near the end of a large
// object.  See PR 26858 for details.  It is, most likely, relatively
// inexpensive to simply do this check always.
#define NULLCHECK(X) \
  do { SAVE_PC(); if ((X)==NULL) throw_null_pointer_exception (); } while (0)

// Note that we can still conditionally define NULLARRAYCHECK, since
// we know that all uses of an array will first reference the length
// field, which is first -- and thus will trigger a SEGV.
#ifdef HANDLE_SEGV
#define NULLARRAYCHECK(X) SAVE_PC()
#else
#define NULLARRAYCHECK(X)					\
  do								\
    {								\
      SAVE_PC();						\
      if ((X) == NULL) { throw_null_pointer_exception (); }	\
    } while (0)
#endif

#define ARRAYBOUNDSCHECK(array, index)				\
  do								\
    {								\
      if (((unsigned) index) >= (unsigned) (array->length))	\
	_Jv_ThrowBadArrayIndex (index);				\
    } while (0)

void
_Jv_InterpMethod::run_normal (ffi_cif *,
			      void *ret,
			      INTERP_FFI_RAW_TYPE *args,
			      void *__this)
{
  _Jv_InterpMethod *_this = (_Jv_InterpMethod *) __this;
  run (ret, args, _this);
}

void
_Jv_InterpMethod::run_normal_debug (ffi_cif *,
				    void *ret,
				    INTERP_FFI_RAW_TYPE *args,
				    void *__this)
{
  _Jv_InterpMethod *_this = (_Jv_InterpMethod *) __this;
  run_debug (ret, args, _this);
}

void
_Jv_InterpMethod::run_synch_object (ffi_cif *,
				    void *ret,
				    INTERP_FFI_RAW_TYPE *args,
				    void *__this)
{
  _Jv_InterpMethod *_this = (_Jv_InterpMethod *) __this;

  jobject rcv = (jobject) args[0].ptr;
  JvSynchronize mutex (rcv);

  run (ret, args, _this);
}

void
_Jv_InterpMethod::run_synch_object_debug (ffi_cif *,
					  void *ret,
					  INTERP_FFI_RAW_TYPE *args,
					  void *__this)
{
  _Jv_InterpMethod *_this = (_Jv_InterpMethod *) __this;

  jobject rcv = (jobject) args[0].ptr;
  JvSynchronize mutex (rcv);

  run_debug (ret, args, _this);
}

void
_Jv_InterpMethod::run_class (ffi_cif *,
			     void *ret,
			     INTERP_FFI_RAW_TYPE *args,
			     void *__this)
{
  _Jv_InterpMethod *_this = (_Jv_InterpMethod *) __this;
  _Jv_InitClass (_this->defining_class);
  run (ret, args, _this);
}

void
_Jv_InterpMethod::run_class_debug (ffi_cif *,
				   void *ret,
				   INTERP_FFI_RAW_TYPE *args,
				   void *__this)
{
  _Jv_InterpMethod *_this = (_Jv_InterpMethod *) __this;
  _Jv_InitClass (_this->defining_class);
  run_debug (ret, args, _this);
}

void
_Jv_InterpMethod::run_synch_class (ffi_cif *,
				   void *ret,
				   INTERP_FFI_RAW_TYPE *args,
				   void *__this)
{
  _Jv_InterpMethod *_this = (_Jv_InterpMethod *) __this;

  jclass sync = _this->defining_class;
  _Jv_InitClass (sync);
  JvSynchronize mutex (sync);

  run (ret, args, _this);
}

void
_Jv_InterpMethod::run_synch_class_debug (ffi_cif *,
					 void *ret,
					 INTERP_FFI_RAW_TYPE *args,
					 void *__this)
{
  _Jv_InterpMethod *_this = (_Jv_InterpMethod *) __this;

  jclass sync = _this->defining_class;
  _Jv_InitClass (sync);
  JvSynchronize mutex (sync);

  run_debug (ret, args, _this);
}

#ifdef DIRECT_THREADED
// "Compile" a method by turning it from bytecode to direct-threaded
// code.
void
_Jv_InterpMethod::compile (const void * const *insn_targets)
{
  insn_slot *insns = NULL;
  int next = 0;
  unsigned char *codestart = bytecode ();
  unsigned char *end = codestart + code_length;
  _Jv_word *pool_data = defining_class->constants.data;

#define SET_ONE(Field, Value)						      \
  do									      \
    {									      \
      if (first_pass)							      \
	++next;								      \
      else								      \
	insns[next++].Field = Value;					      \
    }									      \
  while (0)

#define SET_INSN(Value) SET_ONE (insn, (void *) Value)
#define SET_INT(Value) SET_ONE (int_val, Value)
#define SET_DATUM(Value) SET_ONE (datum, Value)

  // Map from bytecode PC to slot in INSNS.
  int *pc_mapping = (int *) __builtin_alloca (sizeof (int) * code_length);
  for (int i = 0; i < code_length; ++i)
    pc_mapping[i] = -1;

  for (int i = 0; i < 2; ++i)
    {
      jboolean first_pass = i == 0;

      if (! first_pass)
	{
	  insns = (insn_slot *) _Jv_AllocBytes (sizeof (insn_slot) * next);
	  number_insn_slots = next;
	  next = 0;
	}

      unsigned char *pc = codestart;
      while (pc < end)
	{
	  int base_pc_val = pc - codestart;
	  if (first_pass)
	    pc_mapping[base_pc_val] = next;

	  java_opcode opcode = (java_opcode) *pc++;
	  // Just elide NOPs.
	  if (opcode == op_nop)
	    continue;
	  SET_INSN (insn_targets[opcode]);

	  switch (opcode)
	    {
	    case op_nop:
	    case op_aconst_null:
	    case op_iconst_m1:
	    case op_iconst_0:
	    case op_iconst_1:
	    case op_iconst_2:
	    case op_iconst_3:
	    case op_iconst_4:
	    case op_iconst_5:
	    case op_lconst_0:
	    case op_lconst_1:
	    case op_fconst_0:
	    case op_fconst_1:
	    case op_fconst_2:
	    case op_dconst_0:
	    case op_dconst_1:
	    case op_iload_0:
	    case op_iload_1:
	    case op_iload_2:
	    case op_iload_3:
	    case op_lload_0:
	    case op_lload_1:
	    case op_lload_2:
	    case op_lload_3:
	    case op_fload_0:
	    case op_fload_1:
	    case op_fload_2:
	    case op_fload_3:
	    case op_dload_0:
	    case op_dload_1:
	    case op_dload_2:
	    case op_dload_3:
	    case op_aload_0:
	    case op_aload_1:
	    case op_aload_2:
	    case op_aload_3:
	    case op_iaload:
	    case op_laload:
	    case op_faload:
	    case op_daload:
	    case op_aaload:
	    case op_baload:
	    case op_caload:
	    case op_saload:
	    case op_istore_0:
	    case op_istore_1:
	    case op_istore_2:
	    case op_istore_3:
	    case op_lstore_0:
	    case op_lstore_1:
	    case op_lstore_2:
	    case op_lstore_3:
	    case op_fstore_0:
	    case op_fstore_1:
	    case op_fstore_2:
	    case op_fstore_3:
	    case op_dstore_0:
	    case op_dstore_1:
	    case op_dstore_2:
	    case op_dstore_3:
	    case op_astore_0:
	    case op_astore_1:
	    case op_astore_2:
	    case op_astore_3:
	    case op_iastore:
	    case op_lastore:
	    case op_fastore:
	    case op_dastore:
	    case op_aastore:
	    case op_bastore:
	    case op_castore:
	    case op_sastore:
	    case op_pop:
	    case op_pop2:
	    case op_dup:
	    case op_dup_x1:
	    case op_dup_x2:
	    case op_dup2:
	    case op_dup2_x1:
	    case op_dup2_x2:
	    case op_swap:
	    case op_iadd:
	    case op_isub:
	    case op_imul:
	    case op_idiv:
	    case op_irem:
	    case op_ishl:
	    case op_ishr:
	    case op_iushr:
	    case op_iand:
	    case op_ior:
	    case op_ixor:
	    case op_ladd:
	    case op_lsub:
	    case op_lmul:
	    case op_ldiv:
	    case op_lrem:
	    case op_lshl:
	    case op_lshr:
	    case op_lushr:
	    case op_land:
	    case op_lor:
	    case op_lxor:
	    case op_fadd:
	    case op_fsub:
	    case op_fmul:
	    case op_fdiv:
	    case op_frem:
	    case op_dadd:
	    case op_dsub:
	    case op_dmul:
	    case op_ddiv:
	    case op_drem:
	    case op_ineg:
	    case op_i2b:
	    case op_i2c:
	    case op_i2s:
	    case op_lneg:
	    case op_fneg:
	    case op_dneg:
	    case op_i2l:
	    case op_i2f:
	    case op_i2d:
	    case op_l2i:
	    case op_l2f:
	    case op_l2d:
	    case op_f2i:
	    case op_f2l:
	    case op_f2d:
	    case op_d2i:
	    case op_d2l:
	    case op_d2f:
	    case op_lcmp:
	    case op_fcmpl:
	    case op_fcmpg:
	    case op_dcmpl:
	    case op_dcmpg:
	    case op_monitorenter:
	    case op_monitorexit:
	    case op_ireturn:
	    case op_lreturn:
	    case op_freturn:
	    case op_dreturn:
	    case op_areturn:
	    case op_return:
	    case op_athrow:
	    case op_arraylength:
	      // No argument, nothing else to do.
	      break;

	    case op_bipush:
	      SET_INT (get1s (pc));
	      ++pc;
	      break;

	    case op_ldc:
	      {
		int index = get1u (pc);
		++pc;
		// For an unresolved class we want to delay resolution
		// until execution.
		if (defining_class->constants.tags[index] == JV_CONSTANT_Class)
		  {
		    --next;
		    SET_INSN (insn_targets[int (op_jsr_w) + 1]);
		    SET_INT (index);
		  }
		else
		  SET_DATUM (pool_data[index].o);
	      }
	      break;

	    case op_ret:
	    case op_iload:
	    case op_lload:
	    case op_fload:
	    case op_dload:
	    case op_aload:
	    case op_istore:
	    case op_lstore:
	    case op_fstore:
	    case op_dstore:
	    case op_astore:
	    case op_newarray:
	      SET_INT (get1u (pc));
	      ++pc;
	      break;

	    case op_iinc:
	      SET_INT (get1u (pc));
	      SET_INT (get1s (pc + 1));
	      pc += 2;
	      break;

	    case op_ldc_w:
	      {
		int index = get2u (pc);
		pc += 2;
		// For an unresolved class we want to delay resolution
		// until execution.
		if (defining_class->constants.tags[index] == JV_CONSTANT_Class)
		  {
		    --next;
		    SET_INSN (insn_targets[int (op_jsr_w) + 1]);
		    SET_INT (index);
		  }
		else
		  SET_DATUM (pool_data[index].o);
	      }
	      break;

	    case op_ldc2_w:
	      {
		int index = get2u (pc);
		pc += 2;
		SET_DATUM (&pool_data[index]);
	      }
	      break;

	    case op_sipush:
	      SET_INT (get2s (pc));
	      pc += 2;
	      break;

	    case op_new:
	    case op_getstatic:
	    case op_getfield:
	    case op_putfield:
	    case op_putstatic:
	    case op_anewarray:
	    case op_instanceof:
	    case op_checkcast:
	    case op_invokespecial:
	    case op_invokestatic:
	    case op_invokevirtual:
	      SET_INT (get2u (pc));
	      pc += 2;
	      break;

	    case op_multianewarray:
	      SET_INT (get2u (pc));
	      SET_INT (get1u (pc + 2));
	      pc += 3;
	      break;

	    case op_jsr:
	    case op_ifeq:
	    case op_ifne:
	    case op_iflt:
	    case op_ifge:
	    case op_ifgt:
	    case op_ifle:
	    case op_if_icmpeq:
	    case op_if_icmpne:
	    case op_if_icmplt:
	    case op_if_icmpge:
	    case op_if_icmpgt:
	    case op_if_icmple:
	    case op_if_acmpeq:
	    case op_if_acmpne:
	    case op_ifnull:
	    case op_ifnonnull:
	    case op_goto:
	      {
		int offset = get2s (pc);
		pc += 2;

		int new_pc = base_pc_val + offset;

		bool orig_was_goto = opcode == op_goto;

		// Thread jumps.  We limit the loop count; this lets
		// us avoid infinite loops if the bytecode contains
		// such.  `10' is arbitrary.
		int count = 10;
		while (codestart[new_pc] == op_goto && count-- > 0)
		  new_pc += get2s (&codestart[new_pc + 1]);

		// If the jump takes us to a `return' instruction and
		// the original branch was an unconditional goto, then
		// we hoist the return.
		opcode = (java_opcode) codestart[new_pc];
		if (orig_was_goto
		    && (opcode == op_ireturn || opcode == op_lreturn
			|| opcode == op_freturn || opcode == op_dreturn
			|| opcode == op_areturn || opcode == op_return))
		  {
		    --next;
		    SET_INSN (insn_targets[opcode]);
		  }
		else
		  SET_DATUM (&insns[pc_mapping[new_pc]]);
	      }
	      break;

	    case op_tableswitch:
	      {
		while ((pc - codestart) % 4 != 0)
		  ++pc;

		jint def = get4 (pc);
		SET_DATUM (&insns[pc_mapping[base_pc_val + def]]);
		pc += 4;

		int low = get4 (pc);
		SET_INT (low);
		pc += 4;
		int high = get4 (pc);
		SET_INT (high);
		pc += 4;

		for (int i = low; i <= high; ++i)
		  {
		    SET_DATUM (&insns[pc_mapping[base_pc_val + get4 (pc)]]);
		    pc += 4;
		  }
	      }
	      break;

	    case op_lookupswitch:
	      {
		while ((pc - codestart) % 4 != 0)
		  ++pc;

		jint def = get4 (pc);
		SET_DATUM (&insns[pc_mapping[base_pc_val + def]]);
		pc += 4;

		jint npairs = get4 (pc);
		pc += 4;
		SET_INT (npairs);

		while (npairs-- > 0)
		  {
		    jint match = get4 (pc);
		    jint offset = get4 (pc + 4);
		    SET_INT (match);
		    SET_DATUM (&insns[pc_mapping[base_pc_val + offset]]);
		    pc += 8;
		  }
	      }
	      break;

	    case op_invokeinterface:
	      {
		jint index = get2u (pc);
		pc += 2;
		// We ignore the next two bytes.
		pc += 2;
		SET_INT (index);
	      }
	      break;

	    case op_wide:
	      {
		opcode = (java_opcode) get1u (pc);
		pc += 1;
		jint val = get2u (pc);
		pc += 2;

		// We implement narrow and wide instructions using the
		// same code in the interpreter.  So we rewrite the
		// instruction slot here.
		if (! first_pass)
		  insns[next - 1].insn = (void *) insn_targets[opcode];
		SET_INT (val);

		if (opcode == op_iinc)
		  {
		    SET_INT (get2s (pc));
		    pc += 2;
		  }
	      }
	      break;

	    case op_jsr_w:
	    case op_goto_w:
	      {
		jint offset = get4 (pc);
		pc += 4;
		SET_DATUM (&insns[pc_mapping[base_pc_val + offset]]);
	      }
	      break;

	    // Some "can't happen" cases that we include for
	    // error-checking purposes.
	    case op_putfield_1:
	    case op_putfield_2:
	    case op_putfield_4:
	    case op_putfield_8:
	    case op_putfield_a:
	    case op_putstatic_1:
	    case op_putstatic_2:
	    case op_putstatic_4:
	    case op_putstatic_8:
	    case op_putstatic_a:
	    case op_getfield_1:
	    case op_getfield_2s:
	    case op_getfield_2u:
	    case op_getfield_4:
	    case op_getfield_8:
	    case op_getfield_a:
	    case op_getstatic_1:
	    case op_getstatic_2s:
	    case op_getstatic_2u:
	    case op_getstatic_4:
	    case op_getstatic_8:
	    case op_getstatic_a:
	    case op_breakpoint:
	    default:
	      // Fail somehow.
	      break;
	    }
	}
    }

  // Now update exceptions.
  _Jv_InterpException *exc = exceptions ();
  for (int i = 0; i < exc_count; ++i)
    {
      exc[i].start_pc.p = &insns[pc_mapping[exc[i].start_pc.i]];
      exc[i].end_pc.p = &insns[pc_mapping[exc[i].end_pc.i]];
      exc[i].handler_pc.p = &insns[pc_mapping[exc[i].handler_pc.i]];
      // FIXME: resolve_pool_entry can throw - we shouldn't be doing this
      // during compilation.
      jclass handler
	= (_Jv_Linker::resolve_pool_entry (defining_class,
					     exc[i].handler_type.i)).clazz;
      exc[i].handler_type.p = handler;
    }

  // Translate entries in the LineNumberTable from bytecode PC's to direct
  // threaded interpreter instruction values.
  for (int i = 0; i < line_table_len; i++)
    {
      int byte_pc = line_table[i].bytecode_pc;
      // It isn't worth throwing an exception if this table is
      // corrupted, but at the same time we don't want a crash.
      if (byte_pc < 0 || byte_pc >= code_length)
	byte_pc = 0;
      line_table[i].pc = &insns[pc_mapping[byte_pc]];
    }  

  prepared = insns;

  // Now remap the variable table for this method.
  for (int i = 0; i < local_var_table_len; ++i)
    {
      int start_byte = local_var_table[i].bytecode_pc;
      if (start_byte < 0 || start_byte >= code_length)
	start_byte = 0;
      jlocation start =  pc_mapping[start_byte];

      int end_byte = start_byte + local_var_table[i].length;
      if (end_byte < 0)
	end_byte = 0;
      jlocation end = ((end_byte >= code_length)
		       ? number_insn_slots
		       : pc_mapping[end_byte]);

      local_var_table[i].pc = &insns[start];
      local_var_table[i].length = end - start + 1;
    }
  
  if (breakpoint_insn == NULL)
    {
      bp_insn_slot.insn = const_cast<void *> (insn_targets[op_breakpoint]);
      breakpoint_insn = &bp_insn_slot;
    }
}
#endif /* DIRECT_THREADED */

/* Run the given method.
   When args is NULL, don't run anything -- just compile it. */
void
_Jv_InterpMethod::run (void *retp, INTERP_FFI_RAW_TYPE *args,
		       _Jv_InterpMethod *meth)
{
#undef __GCJ_DEBUG
#undef DEBUG_LOCALS_INSN
#define DEBUG_LOCALS_INSN(s, t) do {} while (0)

#include "interpret-run.cc"
}

void
_Jv_InterpMethod::run_debug (void *retp, INTERP_FFI_RAW_TYPE *args,
			     _Jv_InterpMethod *meth)
{
#define __GCJ_DEBUG
#undef DEBUG_LOCALS_INSN
#define DEBUG_LOCALS_INSN(s, t)  \
  do    \
    {   \
      frame_desc.locals_type[s] = t;  \
    }   \
  while (0)

#include "interpret-run.cc"
}

static void
throw_internal_error (const char *msg)
{
  jthrowable t = new java::lang::InternalError (JvNewStringLatin1 (msg));
  REPORT_EXCEPTION (t);
  throw t;
}

static void 
throw_incompatible_class_change_error (jstring msg)
{
  jthrowable t = new java::lang::IncompatibleClassChangeError (msg);
  REPORT_EXCEPTION (t);
  throw t;
}

static void 
throw_null_pointer_exception ()
{
  jthrowable t = new java::lang::NullPointerException;
  REPORT_EXCEPTION (t);
  throw t;
}

/* Look up source code line number for given bytecode (or direct threaded
   interpreter) PC. */
int
_Jv_InterpMethod::get_source_line(pc_t mpc)
{
  int line = line_table_len > 0 ? line_table[0].line : -1;
  for (int i = 1; i < line_table_len; i++)
    if (line_table[i].pc > mpc)
      break;
    else
      line = line_table[i].line;

  return line;
}

/** Do static initialization for fields with a constant initializer */
void
_Jv_InitField (jobject obj, jclass klass, int index)
{
  using namespace java::lang::reflect;

  if (obj != 0 && klass == 0)
    klass = obj->getClass ();

  if (!_Jv_IsInterpretedClass (klass))
    return;

  _Jv_InterpClass *iclass = (_Jv_InterpClass*)klass->aux_info;

  _Jv_Field * field = (&klass->fields[0]) + index;

  if (index > klass->field_count)
    throw_internal_error ("field out of range");

  int init = iclass->field_initializers[index];
  if (init == 0)
    return;

  _Jv_Constants *pool = &klass->constants;
  int tag = pool->tags[init];

  if (! field->isResolved ())
    throw_internal_error ("initializing unresolved field");

  if (obj==0 && ((field->flags & Modifier::STATIC) == 0))
    throw_internal_error ("initializing non-static field with no object");

  void *addr = 0;

  if ((field->flags & Modifier::STATIC) != 0)
    addr = (void*) field->u.addr;
  else
    addr = (void*) (((char*)obj) + field->u.boffset);

  switch (tag)
    {
    case JV_CONSTANT_String:
      {
	jstring str;
	str = _Jv_NewStringUtf8Const (pool->data[init].utf8);
	pool->data[init].string = str;
	pool->tags[init] = JV_CONSTANT_ResolvedString;
      }
      /* fall through */

    case JV_CONSTANT_ResolvedString:
      if (! (field->type == &java::lang::String::class$
 	     || field->type == &java::lang::Class::class$))
	throw_class_format_error ("string initialiser to non-string field");

      *(jstring*)addr = pool->data[init].string;
      break;

    case JV_CONSTANT_Integer:
      {
	int value = pool->data[init].i;

	if (field->type == JvPrimClass (boolean))
	  *(jboolean*)addr = (jboolean)value;
	
	else if (field->type == JvPrimClass (byte))
	  *(jbyte*)addr = (jbyte)value;
	
	else if (field->type == JvPrimClass (char))
	  *(jchar*)addr = (jchar)value;

	else if (field->type == JvPrimClass (short))
	  *(jshort*)addr = (jshort)value;
	
	else if (field->type == JvPrimClass (int))
	  *(jint*)addr = (jint)value;

	else
	  throw_class_format_error ("erroneous field initializer");
      }  
      break;

    case JV_CONSTANT_Long:
      if (field->type != JvPrimClass (long))
	throw_class_format_error ("erroneous field initializer");

      *(jlong*)addr = _Jv_loadLong (&pool->data[init]);
      break;

    case JV_CONSTANT_Float:
      if (field->type != JvPrimClass (float))
	throw_class_format_error ("erroneous field initializer");

      *(jfloat*)addr = pool->data[init].f;
      break;

    case JV_CONSTANT_Double:
      if (field->type != JvPrimClass (double))
	throw_class_format_error ("erroneous field initializer");

      *(jdouble*)addr = _Jv_loadDouble (&pool->data[init]);
      break;

    default:
      throw_class_format_error ("erroneous field initializer");
    }
}

inline static unsigned char*
skip_one_type (unsigned char* ptr)
{
  int ch = *ptr++;

  while (ch == '[')
    { 
      ch = *ptr++;
    }
  
  if (ch == 'L')
    {
      do { ch = *ptr++; } while (ch != ';');
    }

  return ptr;
}

static ffi_type*
get_ffi_type_from_signature (unsigned char* ptr)
{
  switch (*ptr) 
    {
    case 'L':
    case '[':
      return &ffi_type_pointer;
      break;

    case 'Z':
      // On some platforms a bool is a byte, on others an int.
      if (sizeof (jboolean) == sizeof (jbyte))
	return &ffi_type_sint8;
      else
	{
	  JvAssert (sizeof (jbyte) == sizeof (jint));
	  return &ffi_type_sint32;
	}
      break;

    case 'B':
      return &ffi_type_sint8;
      break;
      
    case 'C':
      return &ffi_type_uint16;
      break;
	  
    case 'S': 
      return &ffi_type_sint16;
      break;
	  
    case 'I':
      return &ffi_type_sint32;
      break;
	  
    case 'J':
      return &ffi_type_sint64;
      break;
	  
    case 'F':
      return &ffi_type_float;
      break;
	  
    case 'D':
      return &ffi_type_double;
      break;

    case 'V':
      return &ffi_type_void;
      break;
    }

  throw_internal_error ("unknown type in signature");
}

/* this function yields the number of actual arguments, that is, if the
 * function is non-static, then one is added to the number of elements
 * found in the signature */

int 
_Jv_count_arguments (_Jv_Utf8Const *signature,
		     jboolean staticp)
{
  unsigned char *ptr = (unsigned char*) signature->chars();
  int arg_count = staticp ? 0 : 1;

  /* first, count number of arguments */

  // skip '('
  ptr++;

  // count args
  while (*ptr != ')')
    {
      ptr = skip_one_type (ptr);
      arg_count += 1;
    }

  return arg_count;
}

/* This beast will build a cif, given the signature.  Memory for
 * the cif itself and for the argument types must be allocated by the
 * caller.
 */

int 
_Jv_init_cif (_Jv_Utf8Const* signature,
	      int arg_count,
	      jboolean staticp,
	      ffi_cif *cif,
	      ffi_type **arg_types,
	      ffi_type **rtype_p)
{
  unsigned char *ptr = (unsigned char*) signature->chars();

  int arg_index = 0;		// arg number
  int item_count = 0;		// stack-item count

  // setup receiver
  if (!staticp)
    {
      arg_types[arg_index++] = &ffi_type_pointer;
      item_count += 1;
    }

  // skip '('
  ptr++;

  // assign arg types
  while (*ptr != ')')
    {
      arg_types[arg_index++] = get_ffi_type_from_signature (ptr);

      if (*ptr == 'J' || *ptr == 'D')
	item_count += 2;
      else
	item_count += 1;

      ptr = skip_one_type (ptr);
    }

  // skip ')'
  ptr++;
  ffi_type *rtype = get_ffi_type_from_signature (ptr);

  ptr = skip_one_type (ptr);
  if (ptr != (unsigned char*)signature->chars() + signature->len())
    throw_internal_error ("did not find end of signature");

  ffi_abi cabi = FFI_DEFAULT_ABI;
#if defined (X86_WIN32) && !defined (__CYGWIN__)
  if (!staticp)
    cabi = FFI_THISCALL;
#endif
  if (ffi_prep_cif (cif, cabi,
		    arg_count, rtype, arg_types) != FFI_OK)
    throw_internal_error ("ffi_prep_cif failed");

  if (rtype_p != NULL)
    *rtype_p = rtype;

  return item_count;
}

/* we put this one here, and not in interpret.cc because it
 * calls the utility routines _Jv_count_arguments 
 * which are static to this module.  The following struct defines the
 * layout we use for the stubs, it's only used in the ncode method. */

#if FFI_NATIVE_RAW_API
#   define FFI_PREP_RAW_CLOSURE ffi_prep_raw_closure_loc
#   define FFI_RAW_SIZE ffi_raw_size
typedef struct {
  ffi_raw_closure  closure;
  _Jv_ClosureList list;
  ffi_cif   cif;
  ffi_type *arg_types[0];
} ncode_closure;
typedef void (*ffi_closure_fun) (ffi_cif*,void*,INTERP_FFI_RAW_TYPE*,void*);
#else
#   define FFI_PREP_RAW_CLOSURE ffi_prep_java_raw_closure_loc
#   define FFI_RAW_SIZE ffi_java_raw_size
typedef struct {
  ffi_java_raw_closure  closure;
  _Jv_ClosureList list;
  ffi_cif   cif;
  ffi_type *arg_types[0];
} ncode_closure;
typedef void (*ffi_closure_fun) (ffi_cif*,void*,ffi_java_raw*,void*);
#endif

void *
_Jv_InterpMethod::ncode (jclass klass)
{
  using namespace java::lang::reflect;

  if (self->ncode != 0)
    return self->ncode;

  jboolean staticp = (self->accflags & Modifier::STATIC) != 0;
  int arg_count = _Jv_count_arguments (self->signature, staticp);

  void *code;
  ncode_closure *closure =
    (ncode_closure*)ffi_closure_alloc (sizeof (ncode_closure)
				       + arg_count * sizeof (ffi_type*),
				       &code);
  closure->list.registerClosure (klass, closure);

  _Jv_init_cif (self->signature,
		arg_count,
		staticp,
		&closure->cif,
		&closure->arg_types[0],
		NULL);

  ffi_closure_fun fun;

  args_raw_size = FFI_RAW_SIZE (&closure->cif);

  JvAssert ((self->accflags & Modifier::NATIVE) == 0);

  if ((self->accflags & Modifier::SYNCHRONIZED) != 0)
    {
      if (staticp)
        {
	  if (JVMTI::enabled)
	    fun = (ffi_closure_fun)&_Jv_InterpMethod::run_synch_class_debug;
	  else
	    fun = (ffi_closure_fun)&_Jv_InterpMethod::run_synch_class;
        }
      else
        {
	  if (JVMTI::enabled)
	    fun = (ffi_closure_fun)&_Jv_InterpMethod::run_synch_object_debug;
	  else
	    fun = (ffi_closure_fun)&_Jv_InterpMethod::run_synch_object;
        }
    }
  else
    {
      if (staticp)
        {
	  if (JVMTI::enabled)
	    fun = (ffi_closure_fun)&_Jv_InterpMethod::run_class_debug;
	  else
	    fun = (ffi_closure_fun)&_Jv_InterpMethod::run_class;
        }
      else
        {
	  if (JVMTI::enabled)
	    fun = (ffi_closure_fun)&_Jv_InterpMethod::run_normal_debug;
	  else
	    fun = (ffi_closure_fun)&_Jv_InterpMethod::run_normal;
        }
    }

  FFI_PREP_RAW_CLOSURE (&closure->closure,
		        &closure->cif, 
		        fun,
		        (void*)this,
			code);

  self->ncode = code;

  return self->ncode;
}

/* Find the index of the given insn in the array of insn slots
   for this method. Returns -1 if not found. */
jlong
_Jv_InterpMethod::insn_index (pc_t pc)
{
  jlong left = 0;
#ifdef DIRECT_THREADED
  jlong right = number_insn_slots;
  pc_t insns = prepared;
#else
  jlong right = code_length;
  pc_t insns = bytecode ();
#endif

  while (right >= 0)
    {
      jlong mid = (left + right) / 2;
      if (&insns[mid] == pc)
	return mid;

      if (pc < &insns[mid])
	right = mid - 1;
      else
        left = mid + 1;
    }

  return -1;
}

// Method to check if an exception is caught at some location in a method
// (meth).  Returns true if this method (meth) contains a catch block for the
// exception (ex). False otherwise.  If there is a catch block, it sets the pc
// to the location of the beginning of the catch block.
jboolean
_Jv_InterpMethod::check_handler (pc_t *pc, _Jv_InterpMethod *meth,
                                java::lang::Throwable *ex)
{
#ifdef DIRECT_THREADED
  void *logical_pc = (void *) ((insn_slot *) (*pc) - 1);
#else
  int logical_pc = (*pc) - 1 - meth->bytecode ();
#endif
  _Jv_InterpException *exc = meth->exceptions ();
  jclass exc_class = ex->getClass ();

  for (int i = 0; i < meth->exc_count; i++)
    {
      if (PCVAL (exc[i].start_pc) <= logical_pc
          && logical_pc < PCVAL (exc[i].end_pc))
        {
#ifdef DIRECT_THREADED
              jclass handler = (jclass) exc[i].handler_type.p;
#else
              jclass handler = NULL;
              if (exc[i].handler_type.i != 0)
                    handler
                      = (_Jv_Linker::resolve_pool_entry (meth->defining_class,
					     exc[i].handler_type.i)).clazz;
#endif /* DIRECT_THREADED */
              if (handler == NULL || handler->isAssignableFrom (exc_class))
                {
#ifdef DIRECT_THREADED
                  (*pc) = (insn_slot *) exc[i].handler_pc.p;
#else
                  (*pc) = meth->bytecode () + exc[i].handler_pc.i;
#endif /* DIRECT_THREADED */
                  return true;
                }
          }
      }
  return false;
}


void
_Jv_InterpMethod::get_line_table (jlong& start, jlong& end,
				  jintArray& line_numbers,
				  jlongArray& code_indices)
{
#ifdef DIRECT_THREADED
  /* For the DIRECT_THREADED case, if the method has not yet been
   * compiled, the linetable will change to insn slots instead of
   * bytecode PCs. It is probably easiest, in this case, to simply
   * compile the method and guarantee that we are using insn
   * slots.
   */
  _Jv_CompileMethod (this);

  if (line_table_len > 0)
    {
      start = 0;
      end = number_insn_slots;
      line_numbers = JvNewIntArray (line_table_len);
      code_indices = JvNewLongArray (line_table_len);

      jint* lines = elements (line_numbers);
      jlong* indices = elements (code_indices);
      for (int i = 0; i < line_table_len; ++i)
	{
	  lines[i] = line_table[i].line;
	  indices[i] = insn_index (line_table[i].pc);
	}
    }
#else // !DIRECT_THREADED
  if (line_table_len > 0)
    {
      start = 0;
      end = code_length;
      line_numbers = JvNewIntArray (line_table_len);
      code_indices = JvNewLongArray (line_table_len);

      jint* lines = elements (line_numbers);
      jlong* indices = elements (code_indices);
      for (int i = 0; i < line_table_len; ++i)
	{
	  lines[i] = line_table[i].line;
	  indices[i] = (jlong) line_table[i].bytecode_pc;
	}
    }
#endif // !DIRECT_THREADED
}

int 
_Jv_InterpMethod::get_local_var_table (char **name, char **sig, 
                                       char **generic_sig, jlong *startloc,
                                       jint *length, jint *slot, 
                                       int table_slot)
{
#ifdef DIRECT_THREADED
  _Jv_CompileMethod (this);
#endif

  if (local_var_table == NULL)
    return -2;
  if (table_slot >= local_var_table_len)
    return -1;
  else
    {
      *name = local_var_table[table_slot].name;
      *sig = local_var_table[table_slot].descriptor;
      *generic_sig = local_var_table[table_slot].descriptor;

#ifdef DIRECT_THREADED
      *startloc = insn_index (local_var_table[table_slot].pc);
#else
      *startloc = static_cast<jlong> (local_var_table[table_slot].bytecode_pc);
#endif
      *length = static_cast<jint> (local_var_table[table_slot].length);
      *slot = static_cast<jint> (local_var_table[table_slot].slot);
    }
  return local_var_table_len - table_slot - 1;
}

pc_t
_Jv_InterpMethod::install_break (jlong index)
{
  return set_insn (index, breakpoint_insn);
}

pc_t
_Jv_InterpMethod::get_insn (jlong index)
{
  pc_t code;

#ifdef DIRECT_THREADED
  if (index >= number_insn_slots || index < 0)
    return NULL;

  code = prepared;
#else // !DIRECT_THREADED
  if (index >= code_length || index < 0)
    return NULL;

  code = reinterpret_cast<pc_t> (bytecode ());
#endif // !DIRECT_THREADED

  return &code[index];
}

pc_t
_Jv_InterpMethod::set_insn (jlong index, pc_t insn)
{
#ifdef DIRECT_THREADED
  if (index >= number_insn_slots || index < 0)
    return NULL;

  pc_t code = prepared;
  code[index].insn = insn->insn;
#else // !DIRECT_THREADED
  if (index >= code_length || index < 0)
    return NULL;

  pc_t code = reinterpret_cast<pc_t> (bytecode ());
  code[index] = *insn;
#endif // !DIRECT_THREADED

  return &code[index];
}

bool
_Jv_InterpMethod::breakpoint_at (jlong index)
{
  pc_t insn = get_insn (index);
  if (insn != NULL)
    {
#ifdef DIRECT_THREADED
      return (insn->insn == breakpoint_insn->insn);
#else
      pc_t code = reinterpret_cast<pc_t> (bytecode ());
      return (code[index] == bp_insn_opcode);
#endif
    }

  return false;
}

void *
_Jv_JNIMethod::ncode (jclass klass)
{
  using namespace java::lang::reflect;

  if (self->ncode != 0)
    return self->ncode;

  jboolean staticp = (self->accflags & Modifier::STATIC) != 0;
  int arg_count = _Jv_count_arguments (self->signature, staticp);

  void *code;
  ncode_closure *closure =
    (ncode_closure*)ffi_closure_alloc (sizeof (ncode_closure)
				       + arg_count * sizeof (ffi_type*),
				       &code);
  closure->list.registerClosure (klass, closure);

  ffi_type *rtype;
  _Jv_init_cif (self->signature,
		arg_count,
		staticp,
		&closure->cif,
		&closure->arg_types[0],
		&rtype);

  ffi_closure_fun fun;

  args_raw_size = FFI_RAW_SIZE (&closure->cif);

  // Initialize the argument types and CIF that represent the actual
  // underlying JNI function.
  int extra_args = 1;
  if ((self->accflags & Modifier::STATIC))
    ++extra_args;
  jni_arg_types = (ffi_type **) _Jv_AllocBytes ((extra_args + arg_count)
						* sizeof (ffi_type *));
  int offset = 0;
  jni_arg_types[offset++] = &ffi_type_pointer;
  if ((self->accflags & Modifier::STATIC))
    jni_arg_types[offset++] = &ffi_type_pointer;
  memcpy (&jni_arg_types[offset], &closure->arg_types[0],
	  arg_count * sizeof (ffi_type *));

  if (ffi_prep_cif (&jni_cif, _Jv_platform_ffi_abi,
		    extra_args + arg_count, rtype,
		    jni_arg_types) != FFI_OK)
    throw_internal_error ("ffi_prep_cif failed for JNI function");

  JvAssert ((self->accflags & Modifier::NATIVE) != 0);

  // FIXME: for now we assume that all native methods for
  // interpreted code use JNI.
  fun = (ffi_closure_fun) &_Jv_JNIMethod::call;

  FFI_PREP_RAW_CLOSURE (&closure->closure,
			&closure->cif, 
			fun,
			(void*) this,
			code);

  self->ncode = code;
  return self->ncode;
}

static void
throw_class_format_error (jstring msg)
{
  jthrowable t = (msg
	 ? new java::lang::ClassFormatError (msg)
	 : new java::lang::ClassFormatError);
  REPORT_EXCEPTION (t);
  throw t;
}

static void
throw_class_format_error (const char *msg)
{
  throw_class_format_error (JvNewStringLatin1 (msg));
}

/* This function finds the method and location where the exception EXC
   is caught in the stack frame. On return, it sets CATCH_METHOD and
   CATCH_LOCATION with the method and location where the catch will
   occur. If the exception is not caught, these are set to 0.

   This function should only be used with the __GCJ_DEBUG interpreter. */
static void
find_catch_location (::java::lang::Throwable *exc, jthread thread,
		     jmethodID *catch_method, jlong *catch_loc)
{
  *catch_method = 0;
  *catch_loc = 0;

  _Jv_InterpFrame *frame
    = reinterpret_cast<_Jv_InterpFrame *> (thread->interp_frame);
  while (frame != NULL)
    {
      pc_t pc = frame->get_pc ();
      _Jv_InterpMethod *imeth
	= reinterpret_cast<_Jv_InterpMethod *> (frame->self);
      if (imeth->check_handler (&pc, imeth, exc))
	{
	  // This method handles the exception.
	  *catch_method = imeth->get_method ();
	  *catch_loc = imeth->insn_index (pc);
	  return;
	}

      frame = frame->next_interp;
    }
}

/* This method handles JVMTI notifications of thrown exceptions. It
   calls find_catch_location to figure out where the exception is
   caught (if it is caught).
   
   Like find_catch_location, this should only be called with the
   __GCJ_DEBUG interpreter. Since a few exceptions occur outside the
   interpreter proper, it is important to not call this function
   without checking JVMTI_REQUESTED_EVENT(Exception) first. */
void
_Jv_ReportJVMTIExceptionThrow (jthrowable ex)
{
  jthread thread = ::java::lang::Thread::currentThread ();
  _Jv_Frame *frame = reinterpret_cast<_Jv_Frame *> (thread->frame);
  jmethodID throw_meth = frame->self->get_method ();
  jlocation throw_loc = -1;
  if (frame->frame_type == frame_interpreter)
    {
      _Jv_InterpFrame * iframe
	= reinterpret_cast<_Jv_InterpFrame *> (frame);
      _Jv_InterpMethod *imeth
	= reinterpret_cast<_Jv_InterpMethod *> (frame->self);
      throw_loc = imeth->insn_index (iframe->get_pc ());
    }

  jlong catch_loc;
  jmethodID catch_method;
  find_catch_location (ex, thread, &catch_method, &catch_loc);
  _Jv_JVMTI_PostEvent (JVMTI_EVENT_EXCEPTION, thread,
		       _Jv_GetCurrentJNIEnv (), throw_meth, throw_loc,
		       ex, catch_method, catch_loc);
}



void
_Jv_InterpreterEngine::do_verify (jclass klass)
{
  _Jv_InterpClass *iclass = (_Jv_InterpClass *) klass->aux_info;
  for (int i = 0; i < klass->method_count; i++)
    {
      using namespace java::lang::reflect;
      _Jv_MethodBase *imeth = iclass->interpreted_methods[i];
      _Jv_ushort accflags = klass->methods[i].accflags;
      if ((accflags & (Modifier::NATIVE | Modifier::ABSTRACT)) == 0)
	{
	  _Jv_InterpMethod *im = reinterpret_cast<_Jv_InterpMethod *> (imeth);
	  _Jv_VerifyMethod (im);
	}
    }
}

void
_Jv_InterpreterEngine::do_create_ncode (jclass klass)
{
  _Jv_InterpClass *iclass = (_Jv_InterpClass *) klass->aux_info;
  for (int i = 0; i < klass->method_count; i++)
    {
      // Just skip abstract methods.  This is particularly important
      // because we don't resize the interpreted_methods array when
      // miranda methods are added to it.
      if ((klass->methods[i].accflags
	   & java::lang::reflect::Modifier::ABSTRACT)
	  != 0)
	continue;

      _Jv_MethodBase *imeth = iclass->interpreted_methods[i];

      if ((klass->methods[i].accflags & java::lang::reflect::Modifier::NATIVE)
	  != 0)
	{
	  // You might think we could use a virtual `ncode' method in
	  // the _Jv_MethodBase and unify the native and non-native
	  // cases.  Well, we can't, because we don't allocate these
	  // objects using `new', and thus they don't get a vtable.
	  _Jv_JNIMethod *jnim = reinterpret_cast<_Jv_JNIMethod *> (imeth);
	  klass->methods[i].ncode = jnim->ncode (klass);
	}
      else if (imeth != 0)		// it could be abstract
	{
	  _Jv_InterpMethod *im = reinterpret_cast<_Jv_InterpMethod *> (imeth);
	  klass->methods[i].ncode = im->ncode (klass);
	}
    }
}

_Jv_ClosureList **
_Jv_InterpreterEngine::do_get_closure_list (jclass klass)
{
  _Jv_InterpClass *iclass = (_Jv_InterpClass *) klass->aux_info;

  if (!iclass->closures)
    iclass->closures = _Jv_ClosureListFinalizer ();

  return iclass->closures;
}

void
_Jv_InterpreterEngine::do_allocate_static_fields (jclass klass,
						  int pointer_size,
						  int other_size)
{
  _Jv_InterpClass *iclass = (_Jv_InterpClass *) klass->aux_info;

  // Splitting the allocations here lets us scan reference fields and
  // avoid scanning non-reference fields.  How reference fields are
  // scanned is a bit tricky: we allocate using _Jv_AllocRawObj, which
  // means that this memory will be scanned conservatively (same
  // difference, since we know all the contents here are pointers).
  // Then we put pointers into this memory into the 'fields'
  // structure.  Most of these are interior pointers, which is ok (but
  // even so the pointer to the first reference field will be used and
  // that is not an interior pointer).  The 'fields' array is also
  // allocated with _Jv_AllocRawObj (see defineclass.cc), so it will
  // be scanned.  A pointer to this array is held by Class and thus
  // seen by the collector.
  char *reference_fields = (char *) _Jv_AllocRawObj (pointer_size);
  char *non_reference_fields = (char *) _Jv_AllocBytes (other_size);

  for (int i = 0; i < klass->field_count; i++)
    {
      _Jv_Field *field = &klass->fields[i];

      if ((field->flags & java::lang::reflect::Modifier::STATIC) == 0)
	continue;

      char *base = field->isRef() ? reference_fields : non_reference_fields;
      field->u.addr  = base + field->u.boffset;

      if (iclass->field_initializers[i] != 0)
	{
	  _Jv_Linker::resolve_field (field, klass->loader);
	  _Jv_InitField (0, klass, i);
	}
    }

  // Now we don't need the field_initializers anymore, so let the
  // collector get rid of it.
  iclass->field_initializers = 0;
}

_Jv_ResolvedMethod *
_Jv_InterpreterEngine::do_resolve_method (_Jv_Method *method, jclass klass,
					  jboolean staticp)
{
  int arg_count = _Jv_count_arguments (method->signature, staticp);

  _Jv_ResolvedMethod* result = (_Jv_ResolvedMethod*)
    _Jv_AllocBytes (sizeof (_Jv_ResolvedMethod)
		    + arg_count*sizeof (ffi_type*));

  result->stack_item_count
    = _Jv_init_cif (method->signature,
		    arg_count,
		    staticp,
		    &result->cif,
		    &result->arg_types[0],
		    NULL);

  result->method              = method;
  result->klass               = klass;

  return result;
}

void
_Jv_InterpreterEngine::do_post_miranda_hook (jclass klass)
{
  _Jv_InterpClass *iclass = (_Jv_InterpClass *) klass->aux_info;
  for (int i = 0; i < klass->method_count; i++)
    {
      // Just skip abstract methods.  This is particularly important
      // because we don't resize the interpreted_methods array when
      // miranda methods are added to it.
      if ((klass->methods[i].accflags
	   & java::lang::reflect::Modifier::ABSTRACT)
	  != 0)
	continue;
      // Miranda method additions mean that the `methods' array moves.
      // We cache a pointer into this array, so we have to update.
      iclass->interpreted_methods[i]->self = &klass->methods[i];
    }
}

#ifdef DIRECT_THREADED
void
_Jv_CompileMethod (_Jv_InterpMethod* method)
{
  if (method->prepared == NULL)
    {
      if (JVMTI::enabled)
	_Jv_InterpMethod::run_debug (NULL, NULL, method);
      else
      _Jv_InterpMethod::run (NULL, NULL, method);
    }
}
#endif // DIRECT_THREADED
