// java-interp.h - Header file for the bytecode interpreter.  -*- c++ -*-

/* 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.  */

#ifndef __JAVA_INTERP_H__
#define __JAVA_INTERP_H__

#include <jvm.h>
#include <java-cpool.h>
#include <gnu/gcj/runtime/NameFinder.h>

enum _Jv_FrameType
{
  frame_native,
  frame_interpreter,
  frame_proxy
};

#ifdef INTERPRETER

#pragma interface

#include <java/lang/Class.h>
#include <java/lang/ClassLoader.h>
#include <java/lang/reflect/Modifier.h>
#include <java/lang/Thread.h>
#include <gnu/gcj/RawData.h>

// Define this to get the direct-threaded interpreter.  If undefined,
// we revert to a basic bytecode interpreter.  The former is faster
// but uses more memory.
#define DIRECT_THREADED

#include <ffi.h>

struct _Jv_ResolvedMethod;

void _Jv_InitInterpreter ();
void _Jv_DefineClass (jclass, jbyteArray, jint, jint,
		      java::security::ProtectionDomain *,
		      _Jv_Utf8Const **);

void _Jv_InitField (jobject, jclass, int);
void * _Jv_AllocMethodInvocation (jsize size);
int  _Jv_count_arguments (_Jv_Utf8Const *signature,
			  jboolean staticp = true);
void _Jv_VerifyMethod (_Jv_InterpMethod *method);
void _Jv_CompileMethod (_Jv_InterpMethod* method);
int _Jv_init_cif (_Jv_Utf8Const* signature,
		  int arg_count,
		  jboolean staticp,
		  ffi_cif *cif,
		  ffi_type **arg_types,
		  ffi_type **rtype_p);

/* the interpreter is written in C++, primarily because it makes it easy for
 * the entire thing to be "friend" with class Class. */

class _Jv_InterpClass;
class _Jv_InterpMethod;

// Before a method is "compiled" we store values as the bytecode PC,
// an int.  Afterwards we store them as pointers into the prepared
// code itself.
union _Jv_InterpPC
{
  int i;
  void *p;
};

class _Jv_InterpException
{
  _Jv_InterpPC start_pc;
  _Jv_InterpPC end_pc;
  _Jv_InterpPC handler_pc;
  _Jv_InterpPC handler_type;

  friend class _Jv_ClassReader;
  friend class _Jv_InterpMethod;
  friend class _Jv_BytecodeVerifier;
};

// Base class for method representations.  Subclasses are interpreted
// and JNI methods.
class _Jv_MethodBase
{
protected:
  // The class which defined this method.
  jclass defining_class;

  // The method description.
  _Jv_Method *self;

  // Size of raw arguments.
  _Jv_ushort args_raw_size;

  friend class _Jv_InterpreterEngine;

public:
  _Jv_Method *get_method ()
  {
    return self;
  }
};

// The type of the PC depends on whether we're doing direct threading
// or a more ordinary bytecode interpreter.
#ifdef DIRECT_THREADED
// Slot in the "compiled" form of the bytecode.
union insn_slot
{
  // Address of code.
  void *insn;
  // An integer value used by an instruction.
  jint int_val;
  // A pointer value used by an instruction.
  void *datum;
};

typedef insn_slot *pc_t;
#else
typedef unsigned char *pc_t;
#endif


// This structure holds the bytecode pc and corresponding source code
// line number.  An array (plus length field) of this structure is put
// in each _Jv_InterpMethod and used to resolve the (internal) program
// counter of the interpreted method to an actual java source file
// line.
struct  _Jv_LineTableEntry
{
  union
  {
    pc_t pc;
    int bytecode_pc;
  };
  int line;
};

// This structure holds local variable information.
// Like _Jv_LineTableEntry above, it is remapped when the method is
// compiled for direct threading.
struct _Jv_LocalVarTableEntry
{
  // First PC value at which variable is live
  union
  {
    pc_t pc;
    int bytecode_pc;
  };

  // length of visibility of variable
  int length;

  // variable name
  char *name;

  // type description
  char *descriptor;

  // stack slot number (long and double occupy slot and slot + 1)
  int slot;
};

class _Jv_InterpMethod : public _Jv_MethodBase
{
  // Breakpoint instruction
  static pc_t breakpoint_insn;
#ifdef DIRECT_THREADED
  static insn_slot bp_insn_slot;
#else
  static unsigned char bp_insn_opcode;
#endif

  _Jv_ushort       max_stack;
  _Jv_ushort       max_locals;
  int              code_length;

  _Jv_ushort       exc_count;
  bool             is_15;

  // Length of the line_table - when this is zero then line_table is NULL.
  int line_table_len;  
  _Jv_LineTableEntry *line_table;
  
  // The local variable table length and the table itself
  int local_var_table_len;
  _Jv_LocalVarTableEntry *local_var_table;

  pc_t prepared;
  int number_insn_slots;

  unsigned char* bytecode () 
  {
    return 
      ((unsigned char*)this) 
      + ROUND((sizeof (_Jv_InterpMethod)
	       + exc_count*sizeof (_Jv_InterpException)), 4);
  }

  _Jv_InterpException * exceptions ()
  {
    return (_Jv_InterpException*) (this+1);
  }

  static size_t size (int exc_count, int code_length)
  {
    return 
      ROUND ((sizeof (_Jv_InterpMethod) 
	      + (exc_count * sizeof (_Jv_InterpException))), 4)
      + code_length;
  }

  // return the method's invocation pointer (a stub).
  void *ncode (jclass);
  void compile (const void * const *);

#if FFI_NATIVE_RAW_API
#  define INTERP_FFI_RAW_TYPE ffi_raw
#else
#  define INTERP_FFI_RAW_TYPE ffi_java_raw
#endif

  static void run_normal (ffi_cif*, void*, INTERP_FFI_RAW_TYPE*, void*);
  static void run_synch_object (ffi_cif*, void*, INTERP_FFI_RAW_TYPE*, void*);
  static void run_class (ffi_cif*, void*, INTERP_FFI_RAW_TYPE*, void*);
  static void run_synch_class (ffi_cif*, void*, INTERP_FFI_RAW_TYPE*, void*);
  
  static void run_normal_debug (ffi_cif*, void*, INTERP_FFI_RAW_TYPE*, void*);
  static void run_synch_object_debug (ffi_cif*, void*, INTERP_FFI_RAW_TYPE*,
				      void*);
  static void run_class_debug (ffi_cif*, void*, INTERP_FFI_RAW_TYPE*, void*);
  static void run_synch_class_debug (ffi_cif*, void*, INTERP_FFI_RAW_TYPE*,
				     void*);

  static void run (void *, INTERP_FFI_RAW_TYPE *, _Jv_InterpMethod *);
  static void run_debug (void *, INTERP_FFI_RAW_TYPE *, _Jv_InterpMethod *);
  

  
  // Returns source file line number for given PC value, or -1 if line
  // number info is unavailable.
  int get_source_line(pc_t mpc);

   public:

  // Convenience function for indexing bytecode PC/insn slots in
  // line tables for JDWP
  jlong insn_index (pc_t pc);
  
  // Helper function used to check if there is a handler for an exception
  // present at this code index
  jboolean check_handler (pc_t *pc, _Jv_InterpMethod *meth,
                     java::lang::Throwable *ex);
   
  /* Get the line table for this method.
   * start  is the lowest index in the method
   * end    is the  highest index in the method
   * line_numbers is an array to hold the list of source line numbers
   * code_indices is an array to hold the corresponding list of code indices
   */
  void get_line_table (jlong& start, jlong& end, jintArray& line_numbers,
		       jlongArray& code_indices);
  
  int get_max_locals ()
  {
    return static_cast<int> (max_locals);
  }
  
  /* Get info for a local variable of this method.
   * If there is no loca_var_table for this method it will return -1.
   * table_slot  indicates which slot in the local_var_table to get, if there is
   * no variable at this location it will return 0.
   * Otherwise, it will return the number of table slots after the selected
   * slot, indexed from 0.
   * 
   * Example: there are 5 slots in the table, you request slot 0 so it will
   * return 4.
   */
  int get_local_var_table (char **name, char **sig, char **generic_sig,
                           jlong *startloc, jint *length, jint *slot,
                           int table_slot);

  /* Installs a break instruction at the given code index. Returns
     the pc_t of the breakpoint or NULL if index is invalid. */
  pc_t install_break (jlong index);

  // Gets the instruction at the given index
  pc_t get_insn (jlong index);

  /* Writes the given instruction at the given code index. Returns
     the insn or NULL if index is invalid. */
  pc_t set_insn (jlong index, pc_t insn);

  // Is the given location in this method a breakpoint?
  bool breakpoint_at (jlong index);

#ifdef DIRECT_THREADED
  friend void _Jv_CompileMethod (_Jv_InterpMethod*);
#endif
  
  friend class _Jv_ClassReader;
  friend class _Jv_BytecodeVerifier;
  friend class _Jv_StackTrace;
  friend class _Jv_InterpreterEngine;

#ifdef JV_MARKOBJ_DECL
  friend JV_MARKOBJ_DECL;
#endif
};

class _Jv_InterpClass
{
  _Jv_MethodBase **interpreted_methods;
  _Jv_ushort     *field_initializers;
  jstring source_file_name;
  _Jv_ClosureList **closures;

  friend class _Jv_ClassReader;
  friend class _Jv_InterpMethod;
  friend class _Jv_StackTrace;
  friend class _Jv_InterpreterEngine;

  friend void  _Jv_InitField (jobject, jclass, int);
#ifdef JV_MARKOBJ_DECL
  friend JV_MARKOBJ_DECL;
#endif

  friend _Jv_MethodBase ** _Jv_GetFirstMethod (_Jv_InterpClass *klass);
  friend jstring _Jv_GetInterpClassSourceFile (jclass);
};

extern inline _Jv_MethodBase **
_Jv_GetFirstMethod (_Jv_InterpClass *klass)
{
  return klass->interpreted_methods;
}

struct _Jv_ResolvedMethod
{
  jint            stack_item_count;	
  jclass          klass;
  _Jv_Method*     method;

  // a resolved method holds the cif in-line, so that _Jv_MarkObj just needs
  // to mark the resolved method to hold on to the cif.  Some memory could be
  // saved by keeping a cache of cif's, since many will be the same.
  ffi_cif         cif;
  ffi_type *      arg_types[0];
};

class _Jv_JNIMethod : public _Jv_MethodBase
{
  // The underlying function.  If NULL we have to look for the
  // function.
  void *function;

  // This is the CIF used by the JNI function.
  ffi_cif jni_cif;

  // These are the argument types used by the JNI function.
  ffi_type **jni_arg_types;

  // This function is used when making a JNI call from the interpreter.
  static void call (ffi_cif *, void *, INTERP_FFI_RAW_TYPE *, void *);

  void *ncode (jclass);

  friend class _Jv_ClassReader;
  friend class _Jv_InterpreterEngine;

#ifdef JV_MARKOBJ_DECL
  friend JV_MARKOBJ_DECL;
#endif

public:
  // FIXME: this is ugly.
  void set_function (void *f)
  {
    function = f;
  }
};

//  The composite call stack as represented by a linked list of frames
class _Jv_Frame
{
public:
  java::lang::Thread *thread;

  union
  {
    _Jv_MethodBase *self;
    void *meth;
    _Jv_Method *proxyMethod;
  };
  
  //The full list of frames, JNI and interpreted
  _Jv_Frame *next;
  _Jv_FrameType frame_type;
  
  _Jv_Frame (_Jv_MethodBase *s, java::lang::Thread *thr, _Jv_FrameType type)
  {
    self = s;
    frame_type = type;
    next = (_Jv_Frame *) thr->frame;
    thr->frame = (gnu::gcj::RawData *) this;
    thread = thr;
  }

  ~_Jv_Frame ()
  {
    thread->frame = (gnu::gcj::RawData *) next;
  }

  int depth ()
  {
    int depth = 0;
    struct _Jv_Frame *f;
    for (f = this; f != NULL; f = f->next)
      ++depth;

    return depth;
  }
};

// An interpreted frame in the call stack
class _Jv_InterpFrame : public _Jv_Frame
{
public:
  
  // Keep the purely interpreted list around so as not to break backtraces
  _Jv_InterpFrame *next_interp;
  
  union
  {
    pc_t pc;
    jclass proxyClass;
  };
  
  // Pointer to the actual pc value.
  pc_t *pc_ptr;

  //Debug info for local variables.
  _Jv_word *locals;
  char *locals_type;

  // Object pointer for this frame ("this")
  jobject obj_ptr;

  _Jv_InterpFrame (void *meth, java::lang::Thread *thr, jclass proxyCls = NULL,
                   pc_t *pc = NULL)
  : _Jv_Frame (reinterpret_cast<_Jv_MethodBase *> (meth), thr,
	             frame_interpreter)
  {
    next_interp = (_Jv_InterpFrame *) thr->interp_frame;
    proxyClass = proxyCls;
    thr->interp_frame = (gnu::gcj::RawData *) this;
    obj_ptr = NULL;
    pc_ptr = pc;
  }

  ~_Jv_InterpFrame ()
  {
    thread->interp_frame = (gnu::gcj::RawData *) next_interp;
  }

  jobject get_this_ptr ()
  {
    return obj_ptr;
  }
  
  pc_t get_pc ()
  {
    pc_t pc;
    
    // If the PC_PTR is NULL, we are not debugging.
    if (pc_ptr == NULL)
      pc = 0;
    else
      pc = *pc_ptr - 1;
    
    return pc;
  }
};

// A native frame in the call stack really just a placeholder
class _Jv_NativeFrame : public _Jv_Frame
{
public:

  _Jv_NativeFrame (_Jv_JNIMethod *s, java::lang::Thread *thr)
  : _Jv_Frame (s, thr, frame_native)
  {
  }
};

#endif /* INTERPRETER */

#endif /* __JAVA_INTERP_H__ */
