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

/* Copyright (C) 1999, 2000, 2001  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>

#ifdef INTERPRETER

#pragma interface

#include <java/lang/Class.h>
#include <java/lang/ClassLoader.h>

extern "C" {
#include <ffi.h>
}

extern inline jboolean
_Jv_IsInterpretedClass (jclass c)
{
  return (c->loader != 0);
}

struct _Jv_ResolvedMethod;

bool _Jv_VerifyFieldSignature (_Jv_Utf8Const*sig);
bool _Jv_VerifyMethodSignature (_Jv_Utf8Const*sig);
bool _Jv_VerifyClassName (unsigned char* ptr, _Jv_ushort length);
bool _Jv_VerifyClassName (_Jv_Utf8Const *name);
bool _Jv_VerifyIdentifier (_Jv_Utf8Const *);
bool _Jv_ClassNameSamePackage (_Jv_Utf8Const *name1, _Jv_Utf8Const *name2);
void _Jv_DefineClass (jclass, jbyteArray, jint, jint);

void _Jv_InitField (jobject, jclass, int);
void * _Jv_AllocMethodInvocation (jsize size);

/* FIXME: this should really be defined in some more generic place */
#define ROUND(V, A) (((((unsigned) (V))-1) | ((A)-1))+1)

/* 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;
class _Jv_InterpMethodInvocation;

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

  friend class _Jv_ClassReader;
  friend class _Jv_InterpMethod;
};

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

  // The method description.
  _Jv_Method *self;

  // Size of raw arguments.
  _Jv_ushort args_raw_size;

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

class _Jv_InterpMethod : public _Jv_MethodBase
{
  _Jv_ushort       max_stack;
  _Jv_ushort       max_locals;
  int              code_length;

  _Jv_ushort       exc_count;

  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 ();
  void continue1 (_Jv_InterpMethodInvocation *inv);

  static void run_normal (ffi_cif*, void*, ffi_raw*, void*);
  static void run_synch_object (ffi_cif*, void*, ffi_raw*, void*);
  static void run_synch_class (ffi_cif*, void*, ffi_raw*, void*);

  inline jobject run (ffi_cif*, void*, ffi_raw*, 
		      _Jv_InterpMethodInvocation*);

  bool find_exception (jobject ex,
		       _Jv_InterpMethodInvocation *inv);

 public:
  static void dump_object(jobject o);

  friend class _Jv_ClassReader;
  friend class _Jv_InterpMethodInvocation;

  friend void _Jv_PrepareClass(jclass);
};

class _Jv_InterpMethodInvocation {
  _Jv_InterpMethod *running;
  _Jv_word         *sp;
  unsigned char    *pc;
  _Jv_word          state[0];

  _Jv_word*         stack_base () { return &state[0]; }
  _Jv_word*         local_base () { return &state[running->max_stack]; }

  friend class _Jv_InterpMethod;
};
  
class _Jv_InterpClass : public java::lang::Class
{
  _Jv_MethodBase **interpreted_methods;
  _Jv_ushort        *field_initializers;

  friend class _Jv_ClassReader;
  friend class _Jv_InterpMethod;
  friend void  _Jv_PrepareClass(jclass);
  friend void  _Jv_InitField (jobject, jclass, int);
  friend void* _Jv_MarkObj (void *, void *, void *, void *);

  friend _Jv_MethodBase ** _Jv_GetFirstMethod (_Jv_InterpClass *klass);
};

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

struct _Jv_ResolvedMethod {
  jint            stack_item_count;	
  jint            vtable_index;	
  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 *, ffi_raw *, void *);

  void *ncode ();

  friend class _Jv_ClassReader;
  friend void _Jv_PrepareClass(jclass);

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

#endif /* INTERPRETER */

#endif /* __JAVA_INTERP_H__ */
