// jni.cc - JNI implementation, including the jump table.

/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
   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.  */

#include <config.h>

#include <stdio.h>
#include <stddef.h>
#include <string.h>

#include <gcj/cni.h>
#include <jvm.h>
#include <java-assert.h>
#include <jni.h>
#ifdef ENABLE_JVMPI
#include <jvmpi.h>
#endif
#include <jvmti.h>

#include <java/lang/Class.h>
#include <java/lang/ClassLoader.h>
#include <java/lang/Throwable.h>
#include <java/lang/ArrayIndexOutOfBoundsException.h>
#include <java/lang/StringIndexOutOfBoundsException.h>
#include <java/lang/StringBuffer.h>
#include <java/lang/UnsatisfiedLinkError.h>
#include <java/lang/InstantiationException.h>
#include <java/lang/NoSuchFieldError.h>
#include <java/lang/NoSuchMethodError.h>
#include <java/lang/reflect/Constructor.h>
#include <java/lang/reflect/Method.h>
#include <java/lang/reflect/Modifier.h>
#include <java/lang/OutOfMemoryError.h>
#include <java/lang/Integer.h>
#include <java/lang/ThreadGroup.h>
#include <java/lang/Thread.h>
#include <java/lang/IllegalAccessError.h>
#include <java/nio/Buffer.h>
#include <java/nio/DirectByteBufferImpl.h>
#include <java/nio/DirectByteBufferImpl$ReadWrite.h>
#include <java/util/IdentityHashMap.h>
#include <gnu/gcj/RawData.h>
#include <java/lang/ClassNotFoundException.h>

#include <gcj/method.h>
#include <gcj/field.h>

#include <java-interp.h>
#include <java-threads.h>

using namespace gcj;

// This enum is used to select different template instantiations in
// the invocation code.
enum invocation_type
{
  normal,
  nonvirtual,
  static_type,
  constructor
};

// Forward declarations.
extern struct JNINativeInterface _Jv_JNIFunctions;
extern struct JNIInvokeInterface _Jv_JNI_InvokeFunctions;

// Number of slots in the default frame.  The VM must allow at least
// 16.
#define FRAME_SIZE 16

// Mark value indicating this is an overflow frame.
#define MARK_NONE    0
// Mark value indicating this is a user frame.
#define MARK_USER    1
// Mark value indicating this is a system frame.
#define MARK_SYSTEM  2

// This structure is used to keep track of local references.
struct _Jv_JNI_LocalFrame
{
  // This is one of the MARK_ constants.
  unsigned char marker;

  // Flag to indicate some locals were allocated.
  bool allocated_p;

  // Number of elements in frame.
  int size;

  // The class loader of the JNI method that allocated this frame.
  ::java::lang::ClassLoader *loader;

  // Next frame in chain.
  _Jv_JNI_LocalFrame *next;

  // The elements.  These are allocated using the C "struct hack".
  jobject vec[0];
};

// This holds a reference count for all local references.
static java::util::IdentityHashMap *local_ref_table;
// This holds a reference count for all global references.
static java::util::IdentityHashMap *global_ref_table;

// The only VM.
JavaVM *_Jv_the_vm;

#ifdef ENABLE_JVMPI
// The only JVMPI interface description.
static JVMPI_Interface _Jv_JVMPI_Interface;

static jint
jvmpiEnableEvent (jint event_type, void *)
{
  switch (event_type)
    {
    case JVMPI_EVENT_OBJECT_ALLOC:
      _Jv_JVMPI_Notify_OBJECT_ALLOC = _Jv_JVMPI_Interface.NotifyEvent;
      break;

    case JVMPI_EVENT_THREAD_START:
      _Jv_JVMPI_Notify_THREAD_START = _Jv_JVMPI_Interface.NotifyEvent;
      break;

    case JVMPI_EVENT_THREAD_END:
      _Jv_JVMPI_Notify_THREAD_END = _Jv_JVMPI_Interface.NotifyEvent;
      break;

    default:
      return JVMPI_NOT_AVAILABLE;
    }

  return JVMPI_SUCCESS;
}

static jint
jvmpiDisableEvent (jint event_type, void *)
{
  switch (event_type)
    {
    case JVMPI_EVENT_OBJECT_ALLOC:
      _Jv_JVMPI_Notify_OBJECT_ALLOC = NULL;
      break;

    default:
      return JVMPI_NOT_AVAILABLE;
    }

  return JVMPI_SUCCESS;
}
#endif



void
_Jv_JNI_Init (void)
{
  local_ref_table = new java::util::IdentityHashMap;
  global_ref_table = new java::util::IdentityHashMap;

#ifdef ENABLE_JVMPI
  _Jv_JVMPI_Interface.version = 1;
  _Jv_JVMPI_Interface.EnableEvent = &jvmpiEnableEvent;
  _Jv_JVMPI_Interface.DisableEvent = &jvmpiDisableEvent;
  _Jv_JVMPI_Interface.EnableGC = &_Jv_EnableGC;
  _Jv_JVMPI_Interface.DisableGC = &_Jv_DisableGC;
  _Jv_JVMPI_Interface.RunGC = &_Jv_RunGC;
#endif
}

// Tell the GC that a certain pointer is live.
static void
mark_for_gc (jobject obj, java::util::IdentityHashMap *ref_table)
{
  JvSynchronize sync (ref_table);

  using namespace java::lang;
  Integer *refcount = (Integer *) ref_table->get (obj);
  jint val = (refcount == NULL) ? 0 : refcount->intValue ();
  // FIXME: what about out of memory error?
  ref_table->put (obj, new Integer (val + 1));
}

// Unmark a pointer.
static void
unmark_for_gc (jobject obj, java::util::IdentityHashMap *ref_table)
{
  JvSynchronize sync (ref_table);

  using namespace java::lang;
  Integer *refcount = (Integer *) ref_table->get (obj);
  JvAssert (refcount);
  jint val = refcount->intValue () - 1;
  JvAssert (val >= 0);
  if (val == 0)
    ref_table->remove (obj);
  else
    // FIXME: what about out of memory error?
    ref_table->put (obj, new Integer (val));
}

// "Unwrap" some random non-reference type.  This exists to simplify
// other template functions.
template<typename T>
static T
unwrap (T val)
{
  return val;
}

// Unwrap a weak reference, if required.
template<typename T>
static T *
unwrap (T *obj)
{
  using namespace gnu::gcj::runtime;
  // We can compare the class directly because JNIWeakRef is `final'.
  // Doing it this way is much faster.
  if (obj == NULL || obj->getClass () != &JNIWeakRef::class$)
    return obj;
  JNIWeakRef *wr = reinterpret_cast<JNIWeakRef *> (obj);
  return reinterpret_cast<T *> (wr->get ());
}

jobject
_Jv_UnwrapJNIweakReference (jobject obj)
{
  return unwrap (obj);
}



static jobject JNICALL
_Jv_JNI_NewGlobalRef (JNIEnv *, jobject obj)
{
  // This seems weird but I think it is correct.
  obj = unwrap (obj);
  mark_for_gc (obj, global_ref_table);
  return obj;
}

static void JNICALL
_Jv_JNI_DeleteGlobalRef (JNIEnv *, jobject obj)
{
  // This seems weird but I think it is correct.
  obj = unwrap (obj);
  
  // NULL is ok here -- the JNI specification doesn't say so, but this
  // is a no-op.
  if (! obj)
    return;

  unmark_for_gc (obj, global_ref_table);
}

static void JNICALL
_Jv_JNI_DeleteLocalRef (JNIEnv *env, jobject obj)
{
  _Jv_JNI_LocalFrame *frame;

  // This seems weird but I think it is correct.
  obj = unwrap (obj);

  // NULL is ok here -- the JNI specification doesn't say so, but this
  // is a no-op.
  if (! obj)
    return;

  for (frame = env->locals; frame != NULL; frame = frame->next)
    {
      for (int i = 0; i < frame->size; ++i)
	{
	  if (frame->vec[i] == obj)
	    {
	      frame->vec[i] = NULL;
	      unmark_for_gc (obj, local_ref_table);
	      return;
	    }
	}

      // Don't go past a marked frame.
      JvAssert (frame->marker == MARK_NONE);
    }

  JvAssert (0);
}

static jint JNICALL
_Jv_JNI_EnsureLocalCapacity (JNIEnv *env, jint size)
{
  // It is easier to just always allocate a new frame of the requested
  // size.  This isn't the most efficient thing, but for now we don't
  // care.  Note that _Jv_JNI_PushLocalFrame relies on this right now.

  _Jv_JNI_LocalFrame *frame;
  try
    {
      frame = (_Jv_JNI_LocalFrame *) _Jv_Malloc (sizeof (_Jv_JNI_LocalFrame)
						 + size * sizeof (jobject));
    }
  catch (jthrowable t)
    {
      env->ex = t;
      return JNI_ERR;
    }

  frame->marker = MARK_NONE;
  frame->size = size;
  frame->allocated_p = false;
  memset (&frame->vec[0], 0, size * sizeof (jobject));
  frame->loader = env->locals->loader;
  frame->next = env->locals;
  env->locals = frame;

  return 0;
}

static jint JNICALL
_Jv_JNI_PushLocalFrame (JNIEnv *env, jint size)
{
  jint r = _Jv_JNI_EnsureLocalCapacity (env, size);
  if (r < 0)
    return r;

  // The new frame is on top.
  env->locals->marker = MARK_USER;

  return 0;
}

static jobject JNICALL
_Jv_JNI_NewLocalRef (JNIEnv *env, jobject obj)
{
  // This seems weird but I think it is correct.
  obj = unwrap (obj);

  // Try to find an open slot somewhere in the topmost frame.
  _Jv_JNI_LocalFrame *frame = env->locals;
  bool done = false, set = false;
  for (; frame != NULL && ! done; frame = frame->next)
    {
      for (int i = 0; i < frame->size; ++i)
	{
	  if (frame->vec[i] == NULL)
	    {
	      set = true;
	      done = true;
	      frame->vec[i] = obj;
	      frame->allocated_p = true;
	      break;
	    }
	}

      // If we found a slot, or if the frame we just searched is the
      // mark frame, then we are done.
      if (done || frame == NULL || frame->marker != MARK_NONE)
	break;
    }

  if (! set)
    {
      // No slots, so we allocate a new frame.  According to the spec
      // we could just die here.  FIXME: return value.
      _Jv_JNI_EnsureLocalCapacity (env, 16);
      // We know the first element of the new frame will be ok.
      env->locals->vec[0] = obj;
      env->locals->allocated_p = true;
    }

  mark_for_gc (obj, local_ref_table);
  return obj;
}

static jobject JNICALL
_Jv_JNI_PopLocalFrame (JNIEnv *env, jobject result, int stop)
{
  _Jv_JNI_LocalFrame *rf = env->locals;

  bool done = false;
  while (rf != NULL && ! done)
    {
      for (int i = 0; i < rf->size; ++i)
	if (rf->vec[i] != NULL)
	  unmark_for_gc (rf->vec[i], local_ref_table);

      // If the frame we just freed is the marker frame, we are done.
      done = (rf->marker == stop);

      _Jv_JNI_LocalFrame *n = rf->next;
      // When N==NULL, we've reached the reusable bottom_locals, and we must
      // not free it.  However, we must be sure to clear all its elements.
      if (n == NULL)
	{
	  if (rf->allocated_p)
	    memset (&rf->vec[0], 0, rf->size * sizeof (jobject));
	  rf->allocated_p = false;
	  rf = NULL;
	  break;
	}

      _Jv_Free (rf);
      rf = n;
    }

  // Update the local frame information.
  env->locals = rf;

  return result == NULL ? NULL : _Jv_JNI_NewLocalRef (env, result);
}

static jobject JNICALL
_Jv_JNI_PopLocalFrame (JNIEnv *env, jobject result)
{
  return _Jv_JNI_PopLocalFrame (env, result, MARK_USER);
}

// Make sure an array's type is compatible with the type of the
// destination.
template<typename T>
static bool
_Jv_JNI_check_types (JNIEnv *env, JArray<T> *array, jclass K)
{
  jclass klass = array->getClass()->getComponentType();
  if (__builtin_expect (klass != K, false))
    {
      env->ex = new java::lang::IllegalAccessError ();
      return false;
    }
  else
    return true;
}

// Pop a `system' frame from the stack.  This is `extern "C"' as it is
// used by the compiler.
extern "C" void
_Jv_JNI_PopSystemFrame (JNIEnv *env)
{
  // Only enter slow path when we're not at the bottom, or there have been
  // allocations. Usually this is false and we can just null out the locals
  // field.

  if (__builtin_expect ((env->locals->next 
			 || env->locals->allocated_p), false))
    _Jv_JNI_PopLocalFrame (env, NULL, MARK_SYSTEM);
  else
    env->locals = NULL;
  
  if (__builtin_expect (env->ex != NULL, false))
    {
      jthrowable t = env->ex;
      env->ex = NULL;
      throw t;
    }
}

template<typename T> T extract_from_jvalue(jvalue const & t);
template<> jboolean extract_from_jvalue(jvalue const & jv) { return jv.z; }
template<> jbyte    extract_from_jvalue(jvalue const & jv) { return jv.b; }
template<> jchar    extract_from_jvalue(jvalue const & jv) { return jv.c; }
template<> jshort   extract_from_jvalue(jvalue const & jv) { return jv.s; }
template<> jint     extract_from_jvalue(jvalue const & jv) { return jv.i; }
template<> jlong    extract_from_jvalue(jvalue const & jv) { return jv.j; }
template<> jfloat   extract_from_jvalue(jvalue const & jv) { return jv.f; }
template<> jdouble  extract_from_jvalue(jvalue const & jv) { return jv.d; }
template<> jobject  extract_from_jvalue(jvalue const & jv) { return jv.l; }


// This function is used from other template functions.  It wraps the
// return value appropriately; we specialize it so that object returns
// are turned into local references.
template<typename T>
static T
wrap_value (JNIEnv *, T value)
{
  return value;
}

// This specialization is used for jobject, jclass, jstring, jarray,
// etc.
template<typename R, typename T>
static T *
wrap_value (JNIEnv *env, T *value)
{
  return (value == NULL
	  ? value
	  : (T *) _Jv_JNI_NewLocalRef (env, (jobject) value));
}



static jint JNICALL
_Jv_JNI_GetVersion (JNIEnv *)
{
  return JNI_VERSION_1_4;
}

static jclass JNICALL
_Jv_JNI_DefineClass (JNIEnv *env, const char *name, jobject loader,
		     const jbyte *buf, jsize bufLen)
{
  try
    {
      loader = unwrap (loader);

      jstring sname = JvNewStringUTF (name);
      jbyteArray bytes = JvNewByteArray (bufLen);

      jbyte *elts = elements (bytes);
      memcpy (elts, buf, bufLen * sizeof (jbyte));

      java::lang::ClassLoader *l
	= reinterpret_cast<java::lang::ClassLoader *> (loader);

      jclass result = l->defineClass (sname, bytes, 0, bufLen);
      return (jclass) wrap_value (env, result);
    }
  catch (jthrowable t)
    {
      env->ex = t;
      return NULL;
    }
}

static jclass JNICALL
_Jv_JNI_FindClass (JNIEnv *env, const char *name)
{
  // FIXME: assume that NAME isn't too long.
  int len = strlen (name);
  char s[len + 1];
  for (int i = 0; i <= len; ++i)
    s[i] = (name[i] == '/') ? '.' : name[i];

  jclass r = NULL;
  try
    {
      // This might throw an out of memory exception.
      jstring n = JvNewStringUTF (s);

      java::lang::ClassLoader *loader = NULL;
      if (env->locals->loader != NULL)
	loader = env->locals->loader;

      if (loader == NULL)
	{
	  // FIXME: should use getBaseClassLoader, but we don't have that
	  // yet.
	  loader = java::lang::ClassLoader::getSystemClassLoader ();
	}

      r = loader->loadClass (n);
    }
  catch (jthrowable t)
    {
      env->ex = t;
    }

  return (jclass) wrap_value (env, r);
}

static jclass JNICALL
_Jv_JNI_GetSuperclass (JNIEnv *env, jclass clazz)
{
  return (jclass) wrap_value (env, unwrap (clazz)->getSuperclass ());
}

static jboolean JNICALL
_Jv_JNI_IsAssignableFrom (JNIEnv *, jclass clazz1, jclass clazz2)
{
  return unwrap (clazz2)->isAssignableFrom (unwrap (clazz1));
}

static jint JNICALL
_Jv_JNI_Throw (JNIEnv *env, jthrowable obj)
{
  // We check in case the user did some funky cast.
  obj = unwrap (obj);
  JvAssert (obj != NULL && java::lang::Throwable::class$.isInstance (obj));
  env->ex = obj;
  return 0;
}

static jint JNICALL
_Jv_JNI_ThrowNew (JNIEnv *env, jclass clazz, const char *message)
{
  using namespace java::lang::reflect;

  clazz = unwrap (clazz);
  JvAssert (java::lang::Throwable::class$.isAssignableFrom (clazz));

  int r = JNI_OK;
  try
    {
      JArray<jclass> *argtypes
	= (JArray<jclass> *) JvNewObjectArray (1, &java::lang::Class::class$,
					       NULL);

      jclass *elts = elements (argtypes);
      elts[0] = &java::lang::String::class$;

      Constructor *cons = clazz->getConstructor (argtypes);

      jobjectArray values = JvNewObjectArray (1, &java::lang::String::class$,
					      NULL);
      jobject *velts = elements (values);
      velts[0] = JvNewStringUTF (message);

      jobject obj = cons->newInstance (values);

      env->ex = reinterpret_cast<jthrowable> (obj);
    }
  catch (jthrowable t)
    {
      env->ex = t;
      r = JNI_ERR;
    }

  return r;
}

static jthrowable JNICALL
_Jv_JNI_ExceptionOccurred (JNIEnv *env)
{
  return (jthrowable) wrap_value (env, env->ex);
}

static void JNICALL
_Jv_JNI_ExceptionDescribe (JNIEnv *env)
{
  if (env->ex != NULL)
    env->ex->printStackTrace();
}

static void JNICALL
_Jv_JNI_ExceptionClear (JNIEnv *env)
{
  env->ex = NULL;
}

static jboolean JNICALL
_Jv_JNI_ExceptionCheck (JNIEnv *env)
{
  return env->ex != NULL;
}

static void JNICALL
_Jv_JNI_FatalError (JNIEnv *, const char *message)
{
  JvFail (message);
}



static jboolean JNICALL
_Jv_JNI_IsSameObject (JNIEnv *, jobject obj1, jobject obj2)
{
  return unwrap (obj1) == unwrap (obj2);
}

static jobject JNICALL
_Jv_JNI_AllocObject (JNIEnv *env, jclass clazz)
{
  jobject obj = NULL;
  using namespace java::lang::reflect;

  try
    {
      clazz = unwrap (clazz);
      JvAssert (clazz && ! clazz->isArray ());
      if (clazz->isInterface() || Modifier::isAbstract(clazz->getModifiers()))
	env->ex = new java::lang::InstantiationException ();
      else
	obj = _Jv_AllocObject (clazz);
    }
  catch (jthrowable t)
    {
      env->ex = t;
    }

  return wrap_value (env, obj);
}

static jclass JNICALL
_Jv_JNI_GetObjectClass (JNIEnv *env, jobject obj)
{
  obj = unwrap (obj);
  JvAssert (obj);
  return (jclass) wrap_value (env, obj->getClass());
}

static jboolean JNICALL
_Jv_JNI_IsInstanceOf (JNIEnv *, jobject obj, jclass clazz)
{
  return unwrap (clazz)->isInstance(unwrap (obj));
}



//
// This section concerns method invocation.
//

template<jboolean is_static>
static jmethodID JNICALL
_Jv_JNI_GetAnyMethodID (JNIEnv *env, jclass clazz,
			const char *name, const char *sig)
{
  try
    {
      clazz = unwrap (clazz);
      _Jv_InitClass (clazz);

      _Jv_Utf8Const *name_u = _Jv_makeUtf8Const ((char *) name, -1);

      // FIXME: assume that SIG isn't too long.
      int len = strlen (sig);
      char s[len + 1];
      for (int i = 0; i <= len; ++i)
	s[i] = (sig[i] == '/') ? '.' : sig[i];
      _Jv_Utf8Const *sig_u = _Jv_makeUtf8Const ((char *) s, -1);

      JvAssert (! clazz->isPrimitive());

      using namespace java::lang::reflect;

      while (clazz != NULL)
	{
	  jint count = JvNumMethods (clazz);
	  jmethodID meth = JvGetFirstMethod (clazz);

	  for (jint i = 0; i < count; ++i)
	    {
	      if (((is_static && Modifier::isStatic (meth->accflags))
		   || (! is_static && ! Modifier::isStatic (meth->accflags)))
		  && _Jv_equalUtf8Consts (meth->name, name_u)
		  && _Jv_equalUtf8Consts (meth->signature, sig_u))
		return meth;

	      meth = meth->getNextMethod();
	    }

	  clazz = clazz->getSuperclass ();
	}

      java::lang::StringBuffer *name_sig =
        new java::lang::StringBuffer (JvNewStringUTF (name));
      name_sig->append ((jchar) ' ')->append (JvNewStringUTF (s));
      env->ex = new java::lang::NoSuchMethodError (name_sig->toString ());
    }
  catch (jthrowable t)
    {
      env->ex = t;
    }

  return NULL;
}

// This is a helper function which turns a va_list into an array of
// `jvalue's.  It needs signature information in order to do its work.
// The array of values must already be allocated.
static void
array_from_valist (jvalue *values, JArray<jclass> *arg_types, va_list vargs)
{
  jclass *arg_elts = elements (arg_types);
  for (int i = 0; i < arg_types->length; ++i)
    {
      // Here we assume that sizeof(int) >= sizeof(jint), because we
      // use `int' when decoding the varargs.  Likewise for
      // float, and double.  Also we assume that sizeof(jlong) >=
      // sizeof(int), i.e. that jlong values are not further
      // promoted.
      JvAssert (sizeof (int) >= sizeof (jint));
      JvAssert (sizeof (jlong) >= sizeof (int));
      JvAssert (sizeof (double) >= sizeof (jfloat));
      JvAssert (sizeof (double) >= sizeof (jdouble));
      if (arg_elts[i] == JvPrimClass (byte))
	values[i].b = (jbyte) va_arg (vargs, int);
      else if (arg_elts[i] == JvPrimClass (short))
	values[i].s = (jshort) va_arg (vargs, int);
      else if (arg_elts[i] == JvPrimClass (int))
	values[i].i = (jint) va_arg (vargs, int);
      else if (arg_elts[i] == JvPrimClass (long))
	values[i].j = (jlong) va_arg (vargs, jlong);
      else if (arg_elts[i] == JvPrimClass (float))
	values[i].f = (jfloat) va_arg (vargs, double);
      else if (arg_elts[i] == JvPrimClass (double))
	values[i].d = (jdouble) va_arg (vargs, double);
      else if (arg_elts[i] == JvPrimClass (boolean))
	values[i].z = (jboolean) va_arg (vargs, int);
      else if (arg_elts[i] == JvPrimClass (char))
	values[i].c = (jchar) va_arg (vargs, int);
      else
	{
	  // An object.
	  values[i].l = unwrap (va_arg (vargs, jobject));
	}
    }
}

// This can call any sort of method: virtual, "nonvirtual", static, or
// constructor.
template<typename T, invocation_type style>
static T JNICALL
_Jv_JNI_CallAnyMethodV (JNIEnv *env, jobject obj, jclass klass,
			jmethodID id, va_list vargs)
{
  obj = unwrap (obj);
  klass = unwrap (klass);

  jclass decl_class = klass ? klass : obj->getClass ();
  JvAssert (decl_class != NULL);

  jclass return_type;
  JArray<jclass> *arg_types;

  try
    {
      _Jv_GetTypesFromSignature (id, decl_class,
				 &arg_types, &return_type);

      jvalue args[arg_types->length];
      array_from_valist (args, arg_types, vargs);

      // For constructors we need to pass the Class we are instantiating.
      if (style == constructor)
	return_type = klass;

      jvalue result;
      _Jv_CallAnyMethodA (obj, return_type, id,
			  style == constructor,
			  style == normal,
			  arg_types, args, &result);

      return wrap_value (env, extract_from_jvalue<T>(result));
    }
  catch (jthrowable t)
    {
      env->ex = t;
    }

  return wrap_value (env, (T) 0);
}

template<typename T, invocation_type style>
static T JNICALL
_Jv_JNI_CallAnyMethod (JNIEnv *env, jobject obj, jclass klass,
		       jmethodID method, ...)
{
  va_list args;
  T result;

  va_start (args, method);
  result = _Jv_JNI_CallAnyMethodV<T, style> (env, obj, klass, method, args);
  va_end (args);

  return result;
}

template<typename T, invocation_type style>
static T JNICALL
_Jv_JNI_CallAnyMethodA (JNIEnv *env, jobject obj, jclass klass,
			jmethodID id, jvalue *args)
{
  obj = unwrap (obj);
  klass = unwrap (klass);

  jclass decl_class = klass ? klass : obj->getClass ();
  JvAssert (decl_class != NULL);

  jclass return_type;
  JArray<jclass> *arg_types;
  try
    {
      _Jv_GetTypesFromSignature (id, decl_class,
				 &arg_types, &return_type);

      // For constructors we need to pass the Class we are instantiating.
      if (style == constructor)
	return_type = klass;

      // Unwrap arguments as required.  Eww.
      jclass *type_elts = elements (arg_types);
      jvalue arg_copy[arg_types->length];
      for (int i = 0; i < arg_types->length; ++i)
	{
	  if (type_elts[i]->isPrimitive ())
	    arg_copy[i] = args[i];
	  else
	    arg_copy[i].l = unwrap (args[i].l);
	}

      jvalue result;
      _Jv_CallAnyMethodA (obj, return_type, id,
			  style == constructor,
			  style == normal,
			  arg_types, arg_copy, &result);

      return wrap_value (env, extract_from_jvalue<T>(result));
    }
  catch (jthrowable t)
    {
      env->ex = t;
    }

  return wrap_value (env, (T) 0);
}

template<invocation_type style>
static void JNICALL
_Jv_JNI_CallAnyVoidMethodV (JNIEnv *env, jobject obj, jclass klass,
			    jmethodID id, va_list vargs)
{
  obj = unwrap (obj);
  klass = unwrap (klass);

  jclass decl_class = klass ? klass : obj->getClass ();
  JvAssert (decl_class != NULL);

  jclass return_type;
  JArray<jclass> *arg_types;
  try
    {
      _Jv_GetTypesFromSignature (id, decl_class,
				 &arg_types, &return_type);

      jvalue args[arg_types->length];
      array_from_valist (args, arg_types, vargs);

      // For constructors we need to pass the Class we are instantiating.
      if (style == constructor)
	return_type = klass;

      _Jv_CallAnyMethodA (obj, return_type, id,
			  style == constructor,
			  style == normal,
			  arg_types, args, NULL);
    }
  catch (jthrowable t)
    {
      env->ex = t;
    }
}

template<invocation_type style>
static void JNICALL
_Jv_JNI_CallAnyVoidMethod (JNIEnv *env, jobject obj, jclass klass,
			   jmethodID method, ...)
{
  va_list args;

  va_start (args, method);
  _Jv_JNI_CallAnyVoidMethodV<style> (env, obj, klass, method, args);
  va_end (args);
}

template<invocation_type style>
static void JNICALL
_Jv_JNI_CallAnyVoidMethodA (JNIEnv *env, jobject obj, jclass klass,
			    jmethodID id, jvalue *args)
{
  jclass decl_class = klass ? klass : obj->getClass ();
  JvAssert (decl_class != NULL);

  jclass return_type;
  JArray<jclass> *arg_types;
  try
    {
      _Jv_GetTypesFromSignature (id, decl_class,
				 &arg_types, &return_type);

      // Unwrap arguments as required.  Eww.
      jclass *type_elts = elements (arg_types);
      jvalue arg_copy[arg_types->length];
      for (int i = 0; i < arg_types->length; ++i)
	{
	  if (type_elts[i]->isPrimitive ())
	    arg_copy[i] = args[i];
	  else
	    arg_copy[i].l = unwrap (args[i].l);
	}

      _Jv_CallAnyMethodA (obj, return_type, id,
			  style == constructor,
			  style == normal,
			  arg_types, args, NULL);
    }
  catch (jthrowable t)
    {
      env->ex = t;
    }
}

// Functions with this signature are used to implement functions in
// the CallMethod family.
template<typename T>
static T JNICALL
_Jv_JNI_CallMethodV (JNIEnv *env, jobject obj, 
		     jmethodID id, va_list args)
{
  return _Jv_JNI_CallAnyMethodV<T, normal> (env, obj, NULL, id, args);
}

// Functions with this signature are used to implement functions in
// the CallMethod family.
template<typename T>
static T JNICALL
_Jv_JNI_CallMethod (JNIEnv *env, jobject obj, jmethodID id, ...)
{
  va_list args;
  T result;

  va_start (args, id);
  result = _Jv_JNI_CallAnyMethodV<T, normal> (env, obj, NULL, id, args);
  va_end (args);

  return result;
}

// Functions with this signature are used to implement functions in
// the CallMethod family.
template<typename T>
static T JNICALL
_Jv_JNI_CallMethodA (JNIEnv *env, jobject obj, 
		     jmethodID id, jvalue *args)
{
  return _Jv_JNI_CallAnyMethodA<T, normal> (env, obj, NULL, id, args);
}

static void JNICALL
_Jv_JNI_CallVoidMethodV (JNIEnv *env, jobject obj, 
			 jmethodID id, va_list args)
{
  _Jv_JNI_CallAnyVoidMethodV<normal> (env, obj, NULL, id, args);
}

static void JNICALL
_Jv_JNI_CallVoidMethod (JNIEnv *env, jobject obj, jmethodID id, ...)
{
  va_list args;

  va_start (args, id);
  _Jv_JNI_CallAnyVoidMethodV<normal> (env, obj, NULL, id, args);
  va_end (args);
}

static void JNICALL
_Jv_JNI_CallVoidMethodA (JNIEnv *env, jobject obj, 
			 jmethodID id, jvalue *args)
{
  _Jv_JNI_CallAnyVoidMethodA<normal> (env, obj, NULL, id, args);
}

// Functions with this signature are used to implement functions in
// the CallStaticMethod family.
template<typename T>
static T JNICALL
_Jv_JNI_CallStaticMethodV (JNIEnv *env, jclass klass,
			   jmethodID id, va_list args)
{
  JvAssert (((id->accflags) & java::lang::reflect::Modifier::STATIC));
  JvAssert (java::lang::Class::class$.isInstance (unwrap (klass)));

  return _Jv_JNI_CallAnyMethodV<T, static_type> (env, NULL, klass, id, args);
}

// Functions with this signature are used to implement functions in
// the CallStaticMethod family.
template<typename T>
static T JNICALL
_Jv_JNI_CallStaticMethod (JNIEnv *env, jclass klass, 
			  jmethodID id, ...)
{
  va_list args;
  T result;

  JvAssert (((id->accflags) & java::lang::reflect::Modifier::STATIC));
  JvAssert (java::lang::Class::class$.isInstance (unwrap (klass)));

  va_start (args, id);
  result = _Jv_JNI_CallAnyMethodV<T, static_type> (env, NULL, klass,
						   id, args);
  va_end (args);

  return result;
}

// Functions with this signature are used to implement functions in
// the CallStaticMethod family.
template<typename T>
static T JNICALL
_Jv_JNI_CallStaticMethodA (JNIEnv *env, jclass klass, jmethodID id,
			   jvalue *args)
{
  JvAssert (((id->accflags) & java::lang::reflect::Modifier::STATIC));
  JvAssert (java::lang::Class::class$.isInstance (unwrap (klass)));

  return _Jv_JNI_CallAnyMethodA<T, static_type> (env, NULL, klass, id, args);
}

static void JNICALL
_Jv_JNI_CallStaticVoidMethodV (JNIEnv *env, jclass klass, 
			       jmethodID id, va_list args)
{
  _Jv_JNI_CallAnyVoidMethodV<static_type> (env, NULL, klass, id, args);
}

static void JNICALL
_Jv_JNI_CallStaticVoidMethod (JNIEnv *env, jclass klass, 
			      jmethodID id, ...)
{
  va_list args;

  va_start (args, id);
  _Jv_JNI_CallAnyVoidMethodV<static_type> (env, NULL, klass, id, args);
  va_end (args);
}

static void JNICALL
_Jv_JNI_CallStaticVoidMethodA (JNIEnv *env, jclass klass, 
			       jmethodID id, jvalue *args)
{
  _Jv_JNI_CallAnyVoidMethodA<static_type> (env, NULL, klass, id, args);
}

static jobject JNICALL
_Jv_JNI_NewObjectV (JNIEnv *env, jclass klass,
		    jmethodID id, va_list args)
{
  JvAssert (klass && ! klass->isArray ());
  JvAssert (! strcmp (id->name->chars(), "<init>")
	    && id->signature->len() > 2
	    && id->signature->chars()[0] == '('
	    && ! strcmp (&id->signature->chars()[id->signature->len() - 2],
			 ")V"));

  return _Jv_JNI_CallAnyMethodV<jobject, constructor> (env, NULL, klass,
						       id, args);
}

static jobject JNICALL
_Jv_JNI_NewObject (JNIEnv *env, jclass klass, jmethodID id, ...)
{
  JvAssert (klass && ! klass->isArray ());
  JvAssert (! strcmp (id->name->chars(), "<init>")
	    && id->signature->len() > 2
	    && id->signature->chars()[0] == '('
	    && ! strcmp (&id->signature->chars()[id->signature->len() - 2],
			 ")V"));

  va_list args;
  jobject result;

  va_start (args, id);
  result = _Jv_JNI_CallAnyMethodV<jobject, constructor> (env, NULL, klass,
							 id, args);
  va_end (args);

  return result;
}

static jobject JNICALL
_Jv_JNI_NewObjectA (JNIEnv *env, jclass klass, jmethodID id,
		    jvalue *args)
{
  JvAssert (klass && ! klass->isArray ());
  JvAssert (! strcmp (id->name->chars(), "<init>")
	    && id->signature->len() > 2
	    && id->signature->chars()[0] == '('
	    && ! strcmp (&id->signature->chars()[id->signature->len() - 2],
			 ")V"));

  return _Jv_JNI_CallAnyMethodA<jobject, constructor> (env, NULL, klass,
						       id, args);
}



template<typename T>
static T JNICALL
_Jv_JNI_GetField (JNIEnv *env, jobject obj, jfieldID field)
{
  obj = unwrap (obj);
  JvAssert (obj);
  T *ptr = (T *) ((char *) obj + field->getOffset ());
  return wrap_value (env, *ptr);
}

template<typename T>
static void JNICALL
_Jv_JNI_SetField (JNIEnv *, jobject obj, jfieldID field, T value)
{
  obj = unwrap (obj);
  value = unwrap (value);

  JvAssert (obj);
  T *ptr = (T *) ((char *) obj + field->getOffset ());
  *ptr = value;
}

template<jboolean is_static>
static jfieldID JNICALL
_Jv_JNI_GetAnyFieldID (JNIEnv *env, jclass clazz,
		       const char *name, const char *sig)
{
  try
    {
      clazz = unwrap (clazz);

      _Jv_InitClass (clazz);

      _Jv_Utf8Const *a_name = _Jv_makeUtf8Const ((char *) name, -1);

      // FIXME: assume that SIG isn't too long.
      int len = strlen (sig);
      char s[len + 1];
      for (int i = 0; i <= len; ++i)
	s[i] = (sig[i] == '/') ? '.' : sig[i];
      java::lang::ClassLoader *loader = clazz->getClassLoaderInternal ();
      jclass field_class = _Jv_FindClassFromSignature ((char *) s, loader);
      if (! field_class)
	throw new java::lang::ClassNotFoundException(JvNewStringUTF(s));

      while (clazz != NULL)
	{
	  // We acquire the class lock so that fields aren't resolved
	  // while we are running.
	  JvSynchronize sync (clazz);

	  jint count = (is_static
			? JvNumStaticFields (clazz)
			: JvNumInstanceFields (clazz));
	  jfieldID field = (is_static
			    ? JvGetFirstStaticField (clazz)
			    : JvGetFirstInstanceField (clazz));
	  for (jint i = 0; i < count; ++i)
	    {
	      _Jv_Utf8Const *f_name = field->getNameUtf8Const(clazz);

	      // The field might be resolved or it might not be.  It
	      // is much simpler to always resolve it.
	      _Jv_Linker::resolve_field (field, loader);
	      if (_Jv_equalUtf8Consts (f_name, a_name)
		  && field->getClass() == field_class)
		return field;

	      field = field->getNextField ();
	    }

	  clazz = clazz->getSuperclass ();
	}

      env->ex = new java::lang::NoSuchFieldError ();
    }
  catch (jthrowable t)
    {
      env->ex = t;
    }
  return NULL;
}

template<typename T>
static T JNICALL
_Jv_JNI_GetStaticField (JNIEnv *env, jclass, jfieldID field)
{
  T *ptr = (T *) field->u.addr;
  return wrap_value (env, *ptr);
}

template<typename T>
static void JNICALL
_Jv_JNI_SetStaticField (JNIEnv *, jclass, jfieldID field, T value)
{
  value = unwrap (value);
  T *ptr = (T *) field->u.addr;
  *ptr = value;
}

static jstring JNICALL
_Jv_JNI_NewString (JNIEnv *env, const jchar *unichars, jsize len)
{
  try
    {
      jstring r = _Jv_NewString (unichars, len);
      return (jstring) wrap_value (env, r);
    }
  catch (jthrowable t)
    {
      env->ex = t;
      return NULL;
    }
}

static jsize JNICALL
_Jv_JNI_GetStringLength (JNIEnv *, jstring string)
{
  return unwrap (string)->length();
}

static const jchar * JNICALL
_Jv_JNI_GetStringChars (JNIEnv *, jstring string, jboolean *isCopy)
{
  string = unwrap (string);
  jchar *result = _Jv_GetStringChars (string);
  mark_for_gc (string, global_ref_table);
  if (isCopy)
    *isCopy = false;
  return (const jchar *) result;
}

static void JNICALL
_Jv_JNI_ReleaseStringChars (JNIEnv *, jstring string, const jchar *)
{
  unmark_for_gc (unwrap (string), global_ref_table);
}

static jstring JNICALL
_Jv_JNI_NewStringUTF (JNIEnv *env, const char *bytes)
{
  try
    {
      jstring result = JvNewStringUTF (bytes);
      return (jstring) wrap_value (env, result);
    }
  catch (jthrowable t)
    {
      env->ex = t;
      return NULL;
    }
}

static jsize JNICALL
_Jv_JNI_GetStringUTFLength (JNIEnv *, jstring string)
{
  return JvGetStringUTFLength (unwrap (string));
}

static const char * JNICALL
_Jv_JNI_GetStringUTFChars (JNIEnv *env, jstring string, 
			   jboolean *isCopy)
{
  try
    {
      string = unwrap (string);
      if (string == NULL)
	return NULL;
      jsize len = JvGetStringUTFLength (string);
      char *r = (char *) _Jv_Malloc (len + 1);
      JvGetStringUTFRegion (string, 0, string->length(), r);
      r[len] = '\0';

      if (isCopy)
	*isCopy = true;

      return (const char *) r;
    }
  catch (jthrowable t)
    {
      env->ex = t;
      return NULL;
    }
}

static void JNICALL
_Jv_JNI_ReleaseStringUTFChars (JNIEnv *, jstring, const char *utf)
{
  _Jv_Free ((void *) utf);
}

static void JNICALL
_Jv_JNI_GetStringRegion (JNIEnv *env, jstring string, jsize start, 
			 jsize len, jchar *buf)
{
  string = unwrap (string);
  jchar *result = _Jv_GetStringChars (string);
  if (start < 0 || start > string->length ()
      || len < 0 || start + len > string->length ())
    {
      try
	{
	  env->ex = new java::lang::StringIndexOutOfBoundsException ();
	}
      catch (jthrowable t)
	{
	  env->ex = t;
	}
    }
  else
    memcpy (buf, &result[start], len * sizeof (jchar));
}

static void JNICALL
_Jv_JNI_GetStringUTFRegion (JNIEnv *env, jstring str, jsize start,
			    jsize len, char *buf)
{
  str = unwrap (str);
    
  if (start < 0 || start > str->length ()
      || len < 0 || start + len > str->length ())
    {
      try
	{
	  env->ex = new java::lang::StringIndexOutOfBoundsException ();
	}
      catch (jthrowable t)
	{
	  env->ex = t;
	}
    }
  else
    _Jv_GetStringUTFRegion (str, start, len, buf);
}

static const jchar * JNICALL
_Jv_JNI_GetStringCritical (JNIEnv *, jstring str, jboolean *isCopy)
{
  jchar *result = _Jv_GetStringChars (unwrap (str));
  if (isCopy)
    *isCopy = false;
  return result;
}

static void JNICALL
_Jv_JNI_ReleaseStringCritical (JNIEnv *, jstring, const jchar *)
{
  // Nothing.
}

static jsize JNICALL
_Jv_JNI_GetArrayLength (JNIEnv *, jarray array)
{
  return unwrap (array)->length;
}

static jobjectArray JNICALL
_Jv_JNI_NewObjectArray (JNIEnv *env, jsize length, 
			jclass elementClass, jobject init)
{
  try
    {
      elementClass = unwrap (elementClass);
      init = unwrap (init);

      _Jv_CheckCast (elementClass, init);
      jarray result = JvNewObjectArray (length, elementClass, init);
      return (jobjectArray) wrap_value (env, result);
    }
  catch (jthrowable t)
    {
      env->ex = t;
      return NULL;
    }
}

static jobject JNICALL
_Jv_JNI_GetObjectArrayElement (JNIEnv *env, jobjectArray array, 
			       jsize index)
{
  if ((unsigned) index >= (unsigned) array->length)
    _Jv_ThrowBadArrayIndex (index);
  jobject *elts = elements (unwrap (array));
  return wrap_value (env, elts[index]);
}

static void JNICALL
_Jv_JNI_SetObjectArrayElement (JNIEnv *env, jobjectArray array, 
			       jsize index, jobject value)
{
  try
    {
      array = unwrap (array);
      value = unwrap (value);

      _Jv_CheckArrayStore (array, value);
      if ((unsigned) index >= (unsigned) array->length)
	_Jv_ThrowBadArrayIndex (index);
      jobject *elts = elements (array);
      elts[index] = value;
    }
  catch (jthrowable t)
    {
      env->ex = t;
    }
}

template<typename T, jclass K>
static JArray<T> * JNICALL
_Jv_JNI_NewPrimitiveArray (JNIEnv *env, jsize length)
{
  try
    {
      return (JArray<T> *) wrap_value (env, _Jv_NewPrimArray (K, length));
    }
  catch (jthrowable t)
    {
      env->ex = t;
      return NULL;
    }
}

template<typename T, jclass K>
static T * JNICALL
_Jv_JNI_GetPrimitiveArrayElements (JNIEnv *env, JArray<T> *array,
				   jboolean *isCopy)
{
  array = unwrap (array);
  if (! _Jv_JNI_check_types (env, array, K))
    return NULL;
  T *elts = elements (array);
  if (isCopy)
    {
      // We elect never to copy.
      *isCopy = false;
    }
  mark_for_gc (array, global_ref_table);
  return elts;
}

template<typename T, jclass K>
static void JNICALL
_Jv_JNI_ReleasePrimitiveArrayElements (JNIEnv *env, JArray<T> *array,
				       T *, jint /* mode */)
{
  array = unwrap (array);
  _Jv_JNI_check_types (env, array, K);
  // Note that we ignore MODE.  We can do this because we never copy
  // the array elements.  My reading of the JNI documentation is that
  // this is an option for the implementor.
  unmark_for_gc (array, global_ref_table);
}

template<typename T, jclass K>
static void JNICALL
_Jv_JNI_GetPrimitiveArrayRegion (JNIEnv *env, JArray<T> *array,
				 jsize start, jsize len,
				 T *buf)
{
  array = unwrap (array);
  if (! _Jv_JNI_check_types (env, array, K))
    return;

  // The cast to unsigned lets us save a comparison.
  if (start < 0 || len < 0
      || (unsigned long) (start + len) > (unsigned long) array->length)
    {
      try
	{
	  // FIXME: index.
	  env->ex = new java::lang::ArrayIndexOutOfBoundsException ();
	}
      catch (jthrowable t)
	{
	  // Could have thown out of memory error.
	  env->ex = t;
	}
    }
  else
    {
      T *elts = elements (array) + start;
      memcpy (buf, elts, len * sizeof (T));
    }
}

template<typename T, jclass K>
static void JNICALL
_Jv_JNI_SetPrimitiveArrayRegion (JNIEnv *env, JArray<T> *array,
				 jsize start, jsize len, T *buf)
{
  array = unwrap (array);
  if (! _Jv_JNI_check_types (env, array, K))
    return;

  // The cast to unsigned lets us save a comparison.
  if (start < 0 || len < 0
      || (unsigned long) (start + len) > (unsigned long) array->length)
    {
      try
	{
	  // FIXME: index.
	  env->ex = new java::lang::ArrayIndexOutOfBoundsException ();
	}
      catch (jthrowable t)
	{
	  env->ex = t;
	}
    }
  else
    {
      T *elts = elements (array) + start;
      memcpy (elts, buf, len * sizeof (T));
    }
}

static void * JNICALL
_Jv_JNI_GetPrimitiveArrayCritical (JNIEnv *, jarray array,
				   jboolean *isCopy)
{
  array = unwrap (array);
  // FIXME: does this work?
  jclass klass = array->getClass()->getComponentType();
  JvAssert (klass->isPrimitive ());
  char *r = _Jv_GetArrayElementFromElementType (array, klass);
  if (isCopy)
    *isCopy = false;
  return r;
}

static void JNICALL
_Jv_JNI_ReleasePrimitiveArrayCritical (JNIEnv *, jarray, void *, jint)
{
  // Nothing.
}

static jint JNICALL
_Jv_JNI_MonitorEnter (JNIEnv *env, jobject obj)
{
  try
    {
      _Jv_MonitorEnter (unwrap (obj));
      return 0;
    }
  catch (jthrowable t)
    {
      env->ex = t;
    }
  return JNI_ERR;
}

static jint JNICALL
_Jv_JNI_MonitorExit (JNIEnv *env, jobject obj)
{
  try
    {
      _Jv_MonitorExit (unwrap (obj));
      return 0;
    }
  catch (jthrowable t)
    {
      env->ex = t;
    }
  return JNI_ERR;
}

// JDK 1.2
jobject JNICALL
_Jv_JNI_ToReflectedField (JNIEnv *env, jclass cls, jfieldID fieldID,
			  jboolean)
{
  try
    {
      cls = unwrap (cls);
      java::lang::reflect::Field *field = new java::lang::reflect::Field();
      field->declaringClass = cls;
      field->offset = (char*) fieldID - (char *) cls->fields;
      field->name = _Jv_NewStringUtf8Const (fieldID->getNameUtf8Const (cls));
      return wrap_value (env, field);
    }
  catch (jthrowable t)
    {
      env->ex = t;
    }
  return NULL;
}

// JDK 1.2
static jfieldID JNICALL
_Jv_JNI_FromReflectedField (JNIEnv *, jobject f)
{
  using namespace java::lang::reflect;

  f = unwrap (f);
  Field *field = reinterpret_cast<Field *> (f);
  return _Jv_FromReflectedField (field);
}

jobject JNICALL
_Jv_JNI_ToReflectedMethod (JNIEnv *env, jclass klass, jmethodID id,
			   jboolean)
{
  using namespace java::lang::reflect;

  jobject result = NULL;
  klass = unwrap (klass);

  try
    {
      if (_Jv_equalUtf8Consts (id->name, init_name))
	{
	  // A constructor.
	  Constructor *cons = new Constructor ();
	  cons->offset = (char *) id - (char *) &klass->methods;
	  cons->declaringClass = klass;
	  result = cons;
	}
      else
	{
	  Method *meth = new Method ();
	  meth->offset = (char *) id - (char *) &klass->methods;
	  meth->declaringClass = klass;
	  result = meth;
	}
    }
  catch (jthrowable t)
    {
      env->ex = t;
    }

  return wrap_value (env, result);
}

static jmethodID JNICALL
_Jv_JNI_FromReflectedMethod (JNIEnv *, jobject method)
{
  using namespace java::lang::reflect;
  method = unwrap (method);
  if (Method::class$.isInstance (method))
    return _Jv_FromReflectedMethod (reinterpret_cast<Method *> (method));
  return
    _Jv_FromReflectedConstructor (reinterpret_cast<Constructor *> (method));
}

// JDK 1.2.
jweak JNICALL
_Jv_JNI_NewWeakGlobalRef (JNIEnv *env, jobject obj)
{
  using namespace gnu::gcj::runtime;
  JNIWeakRef *ref = NULL;

  try
    {
      // This seems weird but I think it is correct.
      obj = unwrap (obj);
      ref = new JNIWeakRef (obj);
      mark_for_gc (ref, global_ref_table);
    }
  catch (jthrowable t)
    {
      env->ex = t;
    }

  return reinterpret_cast<jweak> (ref);
}

void JNICALL
_Jv_JNI_DeleteWeakGlobalRef (JNIEnv *, jweak obj)
{
  using namespace gnu::gcj::runtime;
  JNIWeakRef *ref = reinterpret_cast<JNIWeakRef *> (obj);
  unmark_for_gc (ref, global_ref_table);
  ref->clear ();
}



// Direct byte buffers.

static jobject JNICALL
_Jv_JNI_NewDirectByteBuffer (JNIEnv *, void *address, jlong length)
{
  using namespace gnu::gcj;
  using namespace java::nio;
  return new DirectByteBufferImpl$ReadWrite
    (reinterpret_cast<RawData *> (address), length);
}

static void * JNICALL
_Jv_JNI_GetDirectBufferAddress (JNIEnv *, jobject buffer)
{
  using namespace java::nio;
  if (! _Jv_IsInstanceOf (buffer, &Buffer::class$))
    return NULL;
  Buffer *tmp = static_cast<Buffer *> (buffer);
  return reinterpret_cast<void *> (tmp->address);
}

static jlong JNICALL
_Jv_JNI_GetDirectBufferCapacity (JNIEnv *, jobject buffer)
{
  using namespace java::nio;
  if (! _Jv_IsInstanceOf (buffer, &Buffer::class$))
    return -1;
  Buffer *tmp = static_cast<Buffer *> (buffer);
  if (tmp->address == NULL)
    return -1;
  return tmp->capacity();
}



struct NativeMethodCacheEntry : public JNINativeMethod
{
  char *className;
};

// Hash table of native methods.
static NativeMethodCacheEntry *nathash;
// Number of slots used.
static int nathash_count = 0;
// Number of slots available.  Must be power of 2.
static int nathash_size = 0;

#define DELETED_ENTRY ((char *) (~0))

// Compute a hash value for a native method descriptor.
static int
hash (const NativeMethodCacheEntry *method)
{
  char *ptr;
  int hash = 0;

  ptr = method->className;
  while (*ptr)
    hash = (31 * hash) + *ptr++;

  ptr = method->name;
  while (*ptr)
    hash = (31 * hash) + *ptr++;

  ptr = method->signature;
  while (*ptr)
    hash = (31 * hash) + *ptr++;

  return hash;
}

// Find the slot where a native method goes.
static NativeMethodCacheEntry *
nathash_find_slot (const NativeMethodCacheEntry *method)
{
  jint h = hash (method);
  int step = (h ^ (h >> 16)) | 1;
  int w = h & (nathash_size - 1);
  int del = -1;

  for (;;)
    {
      NativeMethodCacheEntry *slotp = &nathash[w];
      if (slotp->name == NULL)
	{
	  if (del >= 0)
	    return &nathash[del];
	  else
	    return slotp;
	}
      else if (slotp->name == DELETED_ENTRY)
	del = w;
      else if (! strcmp (slotp->name, method->name)
	       && ! strcmp (slotp->signature, method->signature)
	       && ! strcmp (slotp->className, method->className))
	return slotp;
      w = (w + step) & (nathash_size - 1);
    }
}

// Find a method.  Return NULL if it isn't in the hash table.
static void *
nathash_find (NativeMethodCacheEntry *method)
{
  if (nathash == NULL)
    return NULL;
  NativeMethodCacheEntry *slot = nathash_find_slot (method);
  if (slot->name == NULL || slot->name == DELETED_ENTRY)
    return NULL;
  return slot->fnPtr;
}

static void
natrehash ()
{
  if (nathash == NULL)
    {
      nathash_size = 1024;
      nathash =
	(NativeMethodCacheEntry *) _Jv_AllocBytes (nathash_size
						   * sizeof (NativeMethodCacheEntry));
    }
  else
    {
      int savesize = nathash_size;
      NativeMethodCacheEntry *savehash = nathash;
      nathash_size *= 2;
      nathash =
	(NativeMethodCacheEntry *) _Jv_AllocBytes (nathash_size
						   * sizeof (NativeMethodCacheEntry));

      for (int i = 0; i < savesize; ++i)
	{
	  if (savehash[i].name != NULL && savehash[i].name != DELETED_ENTRY)
	    {
	      NativeMethodCacheEntry *slot = nathash_find_slot (&savehash[i]);
	      *slot = savehash[i];
	    }
	}
    }
}

static void
nathash_add (const NativeMethodCacheEntry *method)
{
  if (3 * nathash_count >= 2 * nathash_size)
    natrehash ();
  NativeMethodCacheEntry *slot = nathash_find_slot (method);
  // If the slot has a real entry in it, then there is no work to do.
  if (slot->name != NULL && slot->name != DELETED_ENTRY)
    return;
  // FIXME: memory leak?
  slot->name = strdup (method->name);
  slot->className = strdup (method->className);
  // This was already strduped in _Jv_JNI_RegisterNatives.
  slot->signature = method->signature;
  slot->fnPtr = method->fnPtr;
}

static jint JNICALL
_Jv_JNI_RegisterNatives (JNIEnv *env, jclass klass,
			 const JNINativeMethod *methods,
			 jint nMethods)
{
  // Synchronize while we do the work.  This must match
  // synchronization in some other functions that manipulate or use
  // the nathash table.
  JvSynchronize sync (global_ref_table);

  NativeMethodCacheEntry dottedMethod;

  // Look at each descriptor given us, and find the corresponding
  // method in the class.
  for (int j = 0; j < nMethods; ++j)
    {
      bool found = false;

      _Jv_Method *imeths = JvGetFirstMethod (klass);
      for (int i = 0; i < JvNumMethods (klass); ++i)
	{
	  _Jv_Method *self = &imeths[i];

	  // Copy this JNINativeMethod and do a slash to dot
	  // conversion on the signature.
	  dottedMethod.name = methods[j].name;
	  // FIXME: we leak a little memory here if the method
	  // is not found.
	  dottedMethod.signature = strdup (methods[j].signature);
	  dottedMethod.fnPtr = methods[j].fnPtr;
	  dottedMethod.className = _Jv_GetClassNameUtf8 (klass)->chars();
	  char *c = dottedMethod.signature;
	  while (*c)
	    {
	      if (*c == '/')
		*c = '.';
	      c++;
	    }

	  if (! strcmp (self->name->chars (), dottedMethod.name)
	      && ! strcmp (self->signature->chars (), dottedMethod.signature))
	    {
	      if (! (self->accflags & java::lang::reflect::Modifier::NATIVE))
		break;

	      // Found a match that is native.
	      found = true;
	      nathash_add (&dottedMethod);

	      break;
	    }
	}

      if (! found)
	{
	  jstring m = JvNewStringUTF (methods[j].name);
	  try
	    {
	      env->ex = new java::lang::NoSuchMethodError (m);
	    }
	  catch (jthrowable t)
	    {
	      env->ex = t;
	    }
	  return JNI_ERR;
	}
    }

  return JNI_OK;
}

static jint JNICALL
_Jv_JNI_UnregisterNatives (JNIEnv *, jclass)
{
  // FIXME -- we could implement this.
  return JNI_ERR;
}



// Add a character to the buffer, encoding properly.
static void
add_char (char *buf, jchar c, int *here)
{
  if (c == '_')
    {
      buf[(*here)++] = '_';
      buf[(*here)++] = '1';
    }
  else if (c == ';')
    {
      buf[(*here)++] = '_';
      buf[(*here)++] = '2';
    }
  else if (c == '[')
    {
      buf[(*here)++] = '_';
      buf[(*here)++] = '3';
    }

  // Also check for `.' here because we might be passed an internal
  // qualified class name like `foo.bar'.
  else if (c == '/' || c == '.')
    buf[(*here)++] = '_';
  else if ((c >= '0' && c <= '9')
	   || (c >= 'a' && c <= 'z')
	   || (c >= 'A' && c <= 'Z'))
    buf[(*here)++] = (char) c;
  else
    {
      // "Unicode" character.
      buf[(*here)++] = '_';
      buf[(*here)++] = '0';
      for (int i = 0; i < 4; ++i)
	{
	  int val = c & 0x0f;
	  buf[(*here) + 3 - i] = (val > 10) ? ('a' + val - 10) : ('0' + val);
	  c >>= 4;
	}
      *here += 4;
    }
}

// Compute a mangled name for a native function.  This computes the
// long name, and also returns an index which indicates where a NUL
// can be placed to create the short name.  This function assumes that
// the buffer is large enough for its results.
static void
mangled_name (jclass klass, _Jv_Utf8Const *func_name,
	      _Jv_Utf8Const *signature, char *buf, int *long_start)
{
  strcpy (buf, "Java_");
  int here = 5;

  // Add fully qualified class name.
  jchar *chars = _Jv_GetStringChars (klass->getName ());
  jint len = klass->getName ()->length ();
  for (int i = 0; i < len; ++i)
    add_char (buf, chars[i], &here);

  // Don't use add_char because we need a literal `_'.
  buf[here++] = '_';

  const unsigned char *fn = (const unsigned char *) func_name->chars ();
  const unsigned char *limit = fn + func_name->len ();
  for (int i = 0; ; ++i)
    {
      int ch = UTF8_GET (fn, limit);
      if (ch < 0)
	break;
      add_char (buf, ch, &here);
    }

  // This is where the long signature begins.
  *long_start = here;
  buf[here++] = '_';
  buf[here++] = '_';

  const unsigned char *sig = (const unsigned char *) signature->chars ();
  limit = sig + signature->len ();
  JvAssert (sig[0] == '(');
  ++sig;
  while (1)
    {
      int ch = UTF8_GET (sig, limit);
      if (ch == ')' || ch < 0)
	break;
      add_char (buf, ch, &here);
    }

  buf[here] = '\0';
}

JNIEnv *
_Jv_GetJNIEnvNewFrameWithLoader (::java::lang::ClassLoader *loader)
{
  JNIEnv *env = _Jv_GetCurrentJNIEnv ();
  if (__builtin_expect (env == NULL, false))
    {
      env = (JNIEnv *) _Jv_MallocUnchecked (sizeof (JNIEnv));
      env->p = &_Jv_JNIFunctions;
      env->locals = NULL;
      // We set env->ex below.

      // Set up the bottom, reusable frame.
      env->bottom_locals = (_Jv_JNI_LocalFrame *) 
	_Jv_MallocUnchecked (sizeof (_Jv_JNI_LocalFrame)
			     + (FRAME_SIZE
				* sizeof (jobject)));

      env->bottom_locals->marker = MARK_SYSTEM;
      env->bottom_locals->size = FRAME_SIZE;
      env->bottom_locals->next = NULL;
      env->bottom_locals->allocated_p = false;
      // We set the klass field below.
      memset (&env->bottom_locals->vec[0], 0, 
	      env->bottom_locals->size * sizeof (jobject));

      _Jv_SetCurrentJNIEnv (env);
    }

  // If we're in a simple JNI call (non-nested), we can just reuse the
  // locals frame we allocated many calls ago, back when the env was first
  // built, above.

  if (__builtin_expect (env->locals == NULL, true))
    {
      env->locals = env->bottom_locals;
      env->locals->loader = loader;
    }
  else
    {
      // Alternatively, we might be re-entering JNI, in which case we can't
      // reuse the bottom_locals frame, because it is already underneath
      // us. So we need to make a new one.
      _Jv_JNI_LocalFrame *frame
	= (_Jv_JNI_LocalFrame *) _Jv_MallocUnchecked (sizeof (_Jv_JNI_LocalFrame)
						      + (FRAME_SIZE
							 * sizeof (jobject)));

      frame->marker = MARK_SYSTEM;
      frame->size = FRAME_SIZE;
      frame->allocated_p = false;
      frame->next = env->locals;
      frame->loader = loader;

      memset (&frame->vec[0], 0, 
	      frame->size * sizeof (jobject));

      env->locals = frame;
    }

  env->ex = NULL;

  return env;
}

// Return the current thread's JNIEnv; if one does not exist, create
// it.  Also create a new system frame for use.  This is `extern "C"'
// because the compiler calls it.
extern "C" JNIEnv *
_Jv_GetJNIEnvNewFrame (jclass klass)
{
  return _Jv_GetJNIEnvNewFrameWithLoader (klass->getClassLoaderInternal());
}

// Destroy the env's reusable resources. This is called from the thread
// destructor "finalize_native" in natThread.cc
void 
_Jv_FreeJNIEnv (_Jv_JNIEnv *env)
{
  if (env == NULL)
    return;

  if (env->bottom_locals != NULL)
    _Jv_Free (env->bottom_locals);

  _Jv_Free (env);
}

// Return the function which implements a particular JNI method.  If
// we can't find the function, we throw the appropriate exception.
// This is `extern "C"' because the compiler uses it.
extern "C" void *
_Jv_LookupJNIMethod (jclass klass, _Jv_Utf8Const *name,
		     _Jv_Utf8Const *signature, MAYBE_UNUSED int args_size)
{
  int name_length = name->len();
  int sig_length = signature->len();
  char buf[10 + 6 * (name_length + sig_length) + 12];
  int long_start;
  void *function;

  // Synchronize on something convenient.  Right now we use the hash.
  JvSynchronize sync (global_ref_table);

  // First see if we have an override in the hash table.
  strncpy (buf, name->chars (), name_length);
  buf[name_length] = '\0';
  strncpy (buf + name_length + 1, signature->chars (), sig_length);
  buf[name_length + sig_length + 1] = '\0';
  NativeMethodCacheEntry meth;
  meth.name = buf;
  meth.signature = buf + name_length + 1;
  meth.className = _Jv_GetClassNameUtf8(klass)->chars();
  function = nathash_find (&meth);
  if (function != NULL)
    return function;

  // If there was no override, then look in the symbol table.
  buf[0] = '_';
  mangled_name (klass, name, signature, buf + 1, &long_start);
  char c = buf[long_start + 1];
  buf[long_start + 1] = '\0';

  function = _Jv_FindSymbolInExecutable (buf + 1);
#ifdef WIN32
  // On Win32, we use the "stdcall" calling convention (see JNICALL
  // in jni.h).
  // 
  // For a function named 'fooBar' that takes 'nn' bytes as arguments,
  // by default, MinGW GCC exports it as 'fooBar@nn', MSVC exports it
  // as '_fooBar@nn' and Borland C exports it as 'fooBar'. We try to
  // take care of all these variations here.

  char asz_buf[12];    /* '@' + '2147483647' (32-bit INT_MAX) + '\0' */
  char long_nm_sv[11]; /* Ditto, except for the '\0'. */

  if (function == NULL)
    {
      // We have tried searching for the 'fooBar' form (BCC) - now
      // try the others.

      // First, save the part of the long name that will be damaged
      // by appending '@nn'.
      memcpy (long_nm_sv, (buf + long_start + 1 + 1), sizeof (long_nm_sv));

      sprintf (asz_buf, "@%d", args_size);
      strcat (buf, asz_buf);

      // Search for the '_fooBar@nn' form (MSVC).
      function = _Jv_FindSymbolInExecutable (buf);

      if (function == NULL)
        {
          // Search for the 'fooBar@nn' form (MinGW GCC).
          function = _Jv_FindSymbolInExecutable (buf + 1);
        }
    }
#endif /* WIN32 */

  if (function == NULL)
    {
      buf[long_start + 1] = c;
#ifdef WIN32
      // Restore the part of the long name that was damaged by 
      // appending the '@nn'.
      memcpy ((buf + long_start + 1 + 1), long_nm_sv, sizeof (long_nm_sv));
#endif /* WIN32 */
      function = _Jv_FindSymbolInExecutable (buf + 1);
      if (function == NULL)
	{
#ifdef WIN32
          strcat (buf, asz_buf);
          function = _Jv_FindSymbolInExecutable (buf);
          if (function == NULL)
            function = _Jv_FindSymbolInExecutable (buf + 1);

          if (function == NULL)
#endif /* WIN32 */
            {
              jstring str = JvNewStringUTF (name->chars ());
              throw new java::lang::UnsatisfiedLinkError (str);
            }
	}
    }

  return function;
}

#ifdef INTERPRETER

// This function is the stub which is used to turn an ordinary (CNI)
// method call into a JNI call.
void
_Jv_JNIMethod::call (ffi_cif *, void *ret, ffi_raw *args, void *__this)
{
  _Jv_JNIMethod* _this = (_Jv_JNIMethod *) __this;

  JNIEnv *env = _Jv_GetJNIEnvNewFrame (_this->defining_class);

  // FIXME: we should mark every reference parameter as a local.  For
  // now we assume a conservative GC, and we assume that the
  // references are on the stack somewhere.

  // We cache the value that we find, of course, but if we don't find
  // a value we don't cache that fact -- we might subsequently load a
  // library which finds the function in question.
  {
    // Synchronize on a convenient object to ensure sanity in case two
    // threads reach this point for the same function at the same
    // time.
    JvSynchronize sync (global_ref_table);
    if (_this->function == NULL)
      {
        int args_size = sizeof (JNIEnv *) + _this->args_raw_size;

        if (_this->self->accflags & java::lang::reflect::Modifier::STATIC)
          args_size += sizeof (_this->defining_class);

        _this->function = _Jv_LookupJNIMethod (_this->defining_class,
                                               _this->self->name,
                                               _this->self->signature,
                                               args_size);
      }
  }

  JvAssert (_this->args_raw_size % sizeof (ffi_raw) == 0);
  ffi_raw real_args[2 + _this->args_raw_size / sizeof (ffi_raw)];
  int offset = 0;

  // First argument is always the environment pointer.
  real_args[offset++].ptr = env;

  // For a static method, we pass in the Class.  For non-static
  // methods, the `this' argument is already handled.
  if ((_this->self->accflags & java::lang::reflect::Modifier::STATIC))
    real_args[offset++].ptr = _this->defining_class;

  // In libgcj, the callee synchronizes.
  jobject sync = NULL;
  if ((_this->self->accflags & java::lang::reflect::Modifier::SYNCHRONIZED))
    {
      if ((_this->self->accflags & java::lang::reflect::Modifier::STATIC))
	sync = _this->defining_class;
      else
	sync = (jobject) args[0].ptr;
      _Jv_MonitorEnter (sync);
    }

  // Copy over passed-in arguments.
  memcpy (&real_args[offset], args, _this->args_raw_size);

  // The actual call to the JNI function.
#if FFI_NATIVE_RAW_API
  ffi_raw_call (&_this->jni_cif, (void (*)()) _this->function,
		ret, real_args);
#else
  ffi_java_raw_call (&_this->jni_cif, (void (*)()) _this->function,
		     ret, real_args);
#endif

  // We might need to unwrap a JNI weak reference here.
  if (_this->jni_cif.rtype == &ffi_type_pointer)
    {
      _Jv_value *val = (_Jv_value *) ret;
      val->object_value = unwrap (val->object_value);
    }

  if (sync != NULL)
    _Jv_MonitorExit (sync);

  _Jv_JNI_PopSystemFrame (env);
}

#endif /* INTERPRETER */



//
// Invocation API.
//

// An internal helper function.
static jint
_Jv_JNI_AttachCurrentThread (JavaVM *, jstring name, void **penv,
			     void *args, jboolean is_daemon)
{
  JavaVMAttachArgs *attach = reinterpret_cast<JavaVMAttachArgs *> (args);
  java::lang::ThreadGroup *group = NULL;

  if (attach)
    {
      // FIXME: do we really want to support 1.1?
      if (attach->version != JNI_VERSION_1_4
	  && attach->version != JNI_VERSION_1_2
	  && attach->version != JNI_VERSION_1_1)
	return JNI_EVERSION;

      JvAssert (java::lang::ThreadGroup::class$.isInstance (attach->group));
      group = reinterpret_cast<java::lang::ThreadGroup *> (attach->group);
    }

  // Attaching an already-attached thread is a no-op.
  JNIEnv *env = _Jv_GetCurrentJNIEnv ();
  if (env != NULL)
    {
      *penv = reinterpret_cast<void *> (env);
      return 0;
    }

  env = (JNIEnv *) _Jv_MallocUnchecked (sizeof (JNIEnv));
  if (env == NULL)
    return JNI_ERR;
  env->p = &_Jv_JNIFunctions;
  env->ex = NULL;
  env->bottom_locals
    = (_Jv_JNI_LocalFrame *) _Jv_MallocUnchecked (sizeof (_Jv_JNI_LocalFrame)
						  + (FRAME_SIZE
						     * sizeof (jobject)));
  env->locals = env->bottom_locals;
  if (env->locals == NULL)
    {
      _Jv_Free (env);
      return JNI_ERR;
    }

  env->locals->allocated_p = false;
  env->locals->marker = MARK_SYSTEM;
  env->locals->size = FRAME_SIZE;
  env->locals->loader = NULL;
  env->locals->next = NULL;

  for (int i = 0; i < env->locals->size; ++i)
    env->locals->vec[i] = NULL;

  *penv = reinterpret_cast<void *> (env);

  // This thread might already be a Java thread -- this function might
  // have been called simply to set the new JNIEnv.
  if (_Jv_ThreadCurrent () == NULL)
    {
      try
	{
	  if (is_daemon)
	    _Jv_AttachCurrentThreadAsDaemon (name, group);
	  else
	    _Jv_AttachCurrentThread (name, group);
	}
      catch (jthrowable t)
	{
	  return JNI_ERR;
	}
    }
  _Jv_SetCurrentJNIEnv (env);

  return 0;
}

// This is the one actually used by JNI.
jint JNICALL
_Jv_JNI_AttachCurrentThread (JavaVM *vm, void **penv, void *args)
{
  return _Jv_JNI_AttachCurrentThread (vm, NULL, penv, args, false);
}

static jint JNICALL
_Jv_JNI_AttachCurrentThreadAsDaemon (JavaVM *vm, void **penv, 
				     void *args)
{
  return _Jv_JNI_AttachCurrentThread (vm, NULL, penv, args, true);
}

static jint JNICALL
_Jv_JNI_DestroyJavaVM (JavaVM *vm)
{
  JvAssert (_Jv_the_vm && vm == _Jv_the_vm);

  union
  {
    JNIEnv *env;
    void *env_p;
  };

  if (_Jv_ThreadCurrent () != NULL)
    {
      jstring main_name;
      // This sucks.
      try
	{
	  main_name = JvNewStringLatin1 ("main");
	}
      catch (jthrowable t)
	{
	  return JNI_ERR;
	}

      jint r = _Jv_JNI_AttachCurrentThread (vm, main_name, &env_p,
					    NULL, false);
      if (r < 0)
	return r;
    }
  else
    env = _Jv_GetCurrentJNIEnv ();

  _Jv_ThreadWait ();

  // Docs say that this always returns an error code.
  return JNI_ERR;
}

jint JNICALL
_Jv_JNI_DetachCurrentThread (JavaVM *)
{
  jint code = _Jv_DetachCurrentThread ();
  return code  ? JNI_EDETACHED : 0;
}

static jint JNICALL
_Jv_JNI_GetEnv (JavaVM *, void **penv, jint version)
{
  if (_Jv_ThreadCurrent () == NULL)
    {
      *penv = NULL;
      return JNI_EDETACHED;
    }

#ifdef ENABLE_JVMPI
  // Handle JVMPI requests.
  if (version == JVMPI_VERSION_1)
    {
      *penv = (void *) &_Jv_JVMPI_Interface;
      return 0;
    }
#endif

  // Handle JVMTI requests
  if (version == JVMTI_VERSION_1_0)
    {
      *penv = (void *) _Jv_GetJVMTIEnv ();
      return 0;
    }

  // FIXME: do we really want to support 1.1?
  if (version != JNI_VERSION_1_4 && version != JNI_VERSION_1_2
      && version != JNI_VERSION_1_1)
    {
      *penv = NULL;
      return JNI_EVERSION;
    }

  *penv = (void *) _Jv_GetCurrentJNIEnv ();
  return 0;
}

JavaVM *
_Jv_GetJavaVM ()
{
  // FIXME: synchronize
  if (! _Jv_the_vm)
    {
      JavaVM *nvm = (JavaVM *) _Jv_MallocUnchecked (sizeof (JavaVM));
      if (nvm != NULL)
	nvm->functions = &_Jv_JNI_InvokeFunctions;
      _Jv_the_vm = nvm;
    }

  // If this is a Java thread, we want to make sure it has an
  // associated JNIEnv.
  if (_Jv_ThreadCurrent () != NULL)
    {
      void *ignore;
      _Jv_JNI_AttachCurrentThread (_Jv_the_vm, &ignore, NULL);
    }

  return _Jv_the_vm;
}

static jint JNICALL
_Jv_JNI_GetJavaVM (JNIEnv *, JavaVM **vm)
{
  *vm = _Jv_GetJavaVM ();
  return *vm == NULL ? JNI_ERR : JNI_OK;
}



#define RESERVED NULL

struct JNINativeInterface _Jv_JNIFunctions =
{
  RESERVED,
  RESERVED,
  RESERVED,
  RESERVED,
  _Jv_JNI_GetVersion,		// GetVersion
  _Jv_JNI_DefineClass,		// DefineClass
  _Jv_JNI_FindClass,		// FindClass
  _Jv_JNI_FromReflectedMethod,	// FromReflectedMethod
  _Jv_JNI_FromReflectedField,	// FromReflectedField
  _Jv_JNI_ToReflectedMethod,	// ToReflectedMethod
  _Jv_JNI_GetSuperclass,	// GetSuperclass
  _Jv_JNI_IsAssignableFrom,	// IsAssignableFrom
  _Jv_JNI_ToReflectedField,	// ToReflectedField
  _Jv_JNI_Throw,		// Throw
  _Jv_JNI_ThrowNew,		// ThrowNew
  _Jv_JNI_ExceptionOccurred,	// ExceptionOccurred
  _Jv_JNI_ExceptionDescribe,	// ExceptionDescribe
  _Jv_JNI_ExceptionClear,	// ExceptionClear
  _Jv_JNI_FatalError,		// FatalError

  _Jv_JNI_PushLocalFrame,	// PushLocalFrame
  _Jv_JNI_PopLocalFrame,	// PopLocalFrame
  _Jv_JNI_NewGlobalRef,		// NewGlobalRef
  _Jv_JNI_DeleteGlobalRef,	// DeleteGlobalRef
  _Jv_JNI_DeleteLocalRef,	// DeleteLocalRef

  _Jv_JNI_IsSameObject,		// IsSameObject

  _Jv_JNI_NewLocalRef,		// NewLocalRef
  _Jv_JNI_EnsureLocalCapacity,	// EnsureLocalCapacity

  _Jv_JNI_AllocObject,		    // AllocObject
  _Jv_JNI_NewObject,		    // NewObject
  _Jv_JNI_NewObjectV,		    // NewObjectV
  _Jv_JNI_NewObjectA,		    // NewObjectA
  _Jv_JNI_GetObjectClass,	    // GetObjectClass
  _Jv_JNI_IsInstanceOf,		    // IsInstanceOf
  _Jv_JNI_GetAnyMethodID<false>,    // GetMethodID

  _Jv_JNI_CallMethod<jobject>,		// CallObjectMethod
  _Jv_JNI_CallMethodV<jobject>,		// CallObjectMethodV
  _Jv_JNI_CallMethodA<jobject>,		// CallObjectMethodA
  _Jv_JNI_CallMethod<jboolean>,		// CallBooleanMethod
  _Jv_JNI_CallMethodV<jboolean>,	// CallBooleanMethodV
  _Jv_JNI_CallMethodA<jboolean>,	// CallBooleanMethodA
  _Jv_JNI_CallMethod<jbyte>,		// CallByteMethod
  _Jv_JNI_CallMethodV<jbyte>,		// CallByteMethodV
  _Jv_JNI_CallMethodA<jbyte>,		// CallByteMethodA
  _Jv_JNI_CallMethod<jchar>,		// CallCharMethod
  _Jv_JNI_CallMethodV<jchar>,		// CallCharMethodV
  _Jv_JNI_CallMethodA<jchar>,		// CallCharMethodA
  _Jv_JNI_CallMethod<jshort>,		// CallShortMethod
  _Jv_JNI_CallMethodV<jshort>,		// CallShortMethodV
  _Jv_JNI_CallMethodA<jshort>,		// CallShortMethodA
  _Jv_JNI_CallMethod<jint>,		// CallIntMethod
  _Jv_JNI_CallMethodV<jint>,		// CallIntMethodV
  _Jv_JNI_CallMethodA<jint>,		// CallIntMethodA
  _Jv_JNI_CallMethod<jlong>,		// CallLongMethod
  _Jv_JNI_CallMethodV<jlong>,		// CallLongMethodV
  _Jv_JNI_CallMethodA<jlong>,		// CallLongMethodA
  _Jv_JNI_CallMethod<jfloat>,		// CallFloatMethod
  _Jv_JNI_CallMethodV<jfloat>,		// CallFloatMethodV
  _Jv_JNI_CallMethodA<jfloat>,		// CallFloatMethodA
  _Jv_JNI_CallMethod<jdouble>,		// CallDoubleMethod
  _Jv_JNI_CallMethodV<jdouble>,		// CallDoubleMethodV
  _Jv_JNI_CallMethodA<jdouble>,		// CallDoubleMethodA
  _Jv_JNI_CallVoidMethod,		// CallVoidMethod
  _Jv_JNI_CallVoidMethodV,		// CallVoidMethodV
  _Jv_JNI_CallVoidMethodA,		// CallVoidMethodA

  // Nonvirtual method invocation functions follow.
  _Jv_JNI_CallAnyMethod<jobject, nonvirtual>,	// CallNonvirtualObjectMethod
  _Jv_JNI_CallAnyMethodV<jobject, nonvirtual>,	// CallNonvirtualObjectMethodV
  _Jv_JNI_CallAnyMethodA<jobject, nonvirtual>,	// CallNonvirtualObjectMethodA
  _Jv_JNI_CallAnyMethod<jboolean, nonvirtual>,	// CallNonvirtualBooleanMethod
  _Jv_JNI_CallAnyMethodV<jboolean, nonvirtual>,	// CallNonvirtualBooleanMethodV
  _Jv_JNI_CallAnyMethodA<jboolean, nonvirtual>,	// CallNonvirtualBooleanMethodA
  _Jv_JNI_CallAnyMethod<jbyte, nonvirtual>,	// CallNonvirtualByteMethod
  _Jv_JNI_CallAnyMethodV<jbyte, nonvirtual>,	// CallNonvirtualByteMethodV
  _Jv_JNI_CallAnyMethodA<jbyte, nonvirtual>,	// CallNonvirtualByteMethodA
  _Jv_JNI_CallAnyMethod<jchar, nonvirtual>,	// CallNonvirtualCharMethod
  _Jv_JNI_CallAnyMethodV<jchar, nonvirtual>,	// CallNonvirtualCharMethodV
  _Jv_JNI_CallAnyMethodA<jchar, nonvirtual>,	// CallNonvirtualCharMethodA
  _Jv_JNI_CallAnyMethod<jshort, nonvirtual>,	// CallNonvirtualShortMethod
  _Jv_JNI_CallAnyMethodV<jshort, nonvirtual>,	// CallNonvirtualShortMethodV
  _Jv_JNI_CallAnyMethodA<jshort, nonvirtual>,	// CallNonvirtualShortMethodA
  _Jv_JNI_CallAnyMethod<jint, nonvirtual>,	// CallNonvirtualIntMethod
  _Jv_JNI_CallAnyMethodV<jint, nonvirtual>,	// CallNonvirtualIntMethodV
  _Jv_JNI_CallAnyMethodA<jint, nonvirtual>,	// CallNonvirtualIntMethodA
  _Jv_JNI_CallAnyMethod<jlong, nonvirtual>,	// CallNonvirtualLongMethod
  _Jv_JNI_CallAnyMethodV<jlong, nonvirtual>,	// CallNonvirtualLongMethodV
  _Jv_JNI_CallAnyMethodA<jlong, nonvirtual>,	// CallNonvirtualLongMethodA
  _Jv_JNI_CallAnyMethod<jfloat, nonvirtual>,	// CallNonvirtualFloatMethod
  _Jv_JNI_CallAnyMethodV<jfloat, nonvirtual>,	// CallNonvirtualFloatMethodV
  _Jv_JNI_CallAnyMethodA<jfloat, nonvirtual>,	// CallNonvirtualFloatMethodA
  _Jv_JNI_CallAnyMethod<jdouble, nonvirtual>,	// CallNonvirtualDoubleMethod
  _Jv_JNI_CallAnyMethodV<jdouble, nonvirtual>,	// CallNonvirtualDoubleMethodV
  _Jv_JNI_CallAnyMethodA<jdouble, nonvirtual>,	// CallNonvirtualDoubleMethodA
  _Jv_JNI_CallAnyVoidMethod<nonvirtual>,	// CallNonvirtualVoidMethod
  _Jv_JNI_CallAnyVoidMethodV<nonvirtual>,	// CallNonvirtualVoidMethodV
  _Jv_JNI_CallAnyVoidMethodA<nonvirtual>,	// CallNonvirtualVoidMethodA

  _Jv_JNI_GetAnyFieldID<false>,	// GetFieldID
  _Jv_JNI_GetField<jobject>,	// GetObjectField
  _Jv_JNI_GetField<jboolean>,	// GetBooleanField
  _Jv_JNI_GetField<jbyte>,	// GetByteField
  _Jv_JNI_GetField<jchar>,	// GetCharField
  _Jv_JNI_GetField<jshort>,	// GetShortField
  _Jv_JNI_GetField<jint>,	// GetIntField
  _Jv_JNI_GetField<jlong>,	// GetLongField
  _Jv_JNI_GetField<jfloat>,	// GetFloatField
  _Jv_JNI_GetField<jdouble>,	// GetDoubleField
  _Jv_JNI_SetField,		// SetObjectField
  _Jv_JNI_SetField,		// SetBooleanField
  _Jv_JNI_SetField,		// SetByteField
  _Jv_JNI_SetField,		// SetCharField
  _Jv_JNI_SetField,		// SetShortField
  _Jv_JNI_SetField,		// SetIntField
  _Jv_JNI_SetField,		// SetLongField
  _Jv_JNI_SetField,		// SetFloatField
  _Jv_JNI_SetField,		// SetDoubleField
  _Jv_JNI_GetAnyMethodID<true>,	// GetStaticMethodID

  _Jv_JNI_CallStaticMethod<jobject>,	  // CallStaticObjectMethod
  _Jv_JNI_CallStaticMethodV<jobject>,	  // CallStaticObjectMethodV
  _Jv_JNI_CallStaticMethodA<jobject>,	  // CallStaticObjectMethodA
  _Jv_JNI_CallStaticMethod<jboolean>,	  // CallStaticBooleanMethod
  _Jv_JNI_CallStaticMethodV<jboolean>,	  // CallStaticBooleanMethodV
  _Jv_JNI_CallStaticMethodA<jboolean>,	  // CallStaticBooleanMethodA
  _Jv_JNI_CallStaticMethod<jbyte>,	  // CallStaticByteMethod
  _Jv_JNI_CallStaticMethodV<jbyte>,	  // CallStaticByteMethodV
  _Jv_JNI_CallStaticMethodA<jbyte>,	  // CallStaticByteMethodA
  _Jv_JNI_CallStaticMethod<jchar>,	  // CallStaticCharMethod
  _Jv_JNI_CallStaticMethodV<jchar>,	  // CallStaticCharMethodV
  _Jv_JNI_CallStaticMethodA<jchar>,	  // CallStaticCharMethodA
  _Jv_JNI_CallStaticMethod<jshort>,	  // CallStaticShortMethod
  _Jv_JNI_CallStaticMethodV<jshort>,	  // CallStaticShortMethodV
  _Jv_JNI_CallStaticMethodA<jshort>,	  // CallStaticShortMethodA
  _Jv_JNI_CallStaticMethod<jint>,	  // CallStaticIntMethod
  _Jv_JNI_CallStaticMethodV<jint>,	  // CallStaticIntMethodV
  _Jv_JNI_CallStaticMethodA<jint>,	  // CallStaticIntMethodA
  _Jv_JNI_CallStaticMethod<jlong>,	  // CallStaticLongMethod
  _Jv_JNI_CallStaticMethodV<jlong>,	  // CallStaticLongMethodV
  _Jv_JNI_CallStaticMethodA<jlong>,	  // CallStaticLongMethodA
  _Jv_JNI_CallStaticMethod<jfloat>,	  // CallStaticFloatMethod
  _Jv_JNI_CallStaticMethodV<jfloat>,	  // CallStaticFloatMethodV
  _Jv_JNI_CallStaticMethodA<jfloat>,	  // CallStaticFloatMethodA
  _Jv_JNI_CallStaticMethod<jdouble>,	  // CallStaticDoubleMethod
  _Jv_JNI_CallStaticMethodV<jdouble>,	  // CallStaticDoubleMethodV
  _Jv_JNI_CallStaticMethodA<jdouble>,	  // CallStaticDoubleMethodA
  _Jv_JNI_CallStaticVoidMethod,		  // CallStaticVoidMethod
  _Jv_JNI_CallStaticVoidMethodV,	  // CallStaticVoidMethodV
  _Jv_JNI_CallStaticVoidMethodA,	  // CallStaticVoidMethodA

  _Jv_JNI_GetAnyFieldID<true>,	       // GetStaticFieldID
  _Jv_JNI_GetStaticField<jobject>,     // GetStaticObjectField
  _Jv_JNI_GetStaticField<jboolean>,    // GetStaticBooleanField
  _Jv_JNI_GetStaticField<jbyte>,       // GetStaticByteField
  _Jv_JNI_GetStaticField<jchar>,       // GetStaticCharField
  _Jv_JNI_GetStaticField<jshort>,      // GetStaticShortField
  _Jv_JNI_GetStaticField<jint>,	       // GetStaticIntField
  _Jv_JNI_GetStaticField<jlong>,       // GetStaticLongField
  _Jv_JNI_GetStaticField<jfloat>,      // GetStaticFloatField
  _Jv_JNI_GetStaticField<jdouble>,     // GetStaticDoubleField
  _Jv_JNI_SetStaticField,	       // SetStaticObjectField
  _Jv_JNI_SetStaticField,	       // SetStaticBooleanField
  _Jv_JNI_SetStaticField,	       // SetStaticByteField
  _Jv_JNI_SetStaticField,	       // SetStaticCharField
  _Jv_JNI_SetStaticField,	       // SetStaticShortField
  _Jv_JNI_SetStaticField,	       // SetStaticIntField
  _Jv_JNI_SetStaticField,	       // SetStaticLongField
  _Jv_JNI_SetStaticField,	       // SetStaticFloatField
  _Jv_JNI_SetStaticField,	       // SetStaticDoubleField
  _Jv_JNI_NewString,		       // NewString
  _Jv_JNI_GetStringLength,	       // GetStringLength
  _Jv_JNI_GetStringChars,	       // GetStringChars
  _Jv_JNI_ReleaseStringChars,	       // ReleaseStringChars
  _Jv_JNI_NewStringUTF,		       // NewStringUTF
  _Jv_JNI_GetStringUTFLength,	       // GetStringUTFLength
  _Jv_JNI_GetStringUTFChars,	       // GetStringUTFChars
  _Jv_JNI_ReleaseStringUTFChars,       // ReleaseStringUTFChars
  _Jv_JNI_GetArrayLength,	       // GetArrayLength
  _Jv_JNI_NewObjectArray,	       // NewObjectArray
  _Jv_JNI_GetObjectArrayElement,       // GetObjectArrayElement
  _Jv_JNI_SetObjectArrayElement,       // SetObjectArrayElement
  _Jv_JNI_NewPrimitiveArray<jboolean, JvPrimClass (boolean)>,
							    // NewBooleanArray
  _Jv_JNI_NewPrimitiveArray<jbyte, JvPrimClass (byte)>,	    // NewByteArray
  _Jv_JNI_NewPrimitiveArray<jchar, JvPrimClass (char)>,	    // NewCharArray
  _Jv_JNI_NewPrimitiveArray<jshort, JvPrimClass (short)>,   // NewShortArray
  _Jv_JNI_NewPrimitiveArray<jint, JvPrimClass (int)>,	    // NewIntArray
  _Jv_JNI_NewPrimitiveArray<jlong, JvPrimClass (long)>,	    // NewLongArray
  _Jv_JNI_NewPrimitiveArray<jfloat, JvPrimClass (float)>,   // NewFloatArray
  _Jv_JNI_NewPrimitiveArray<jdouble, JvPrimClass (double)>, // NewDoubleArray
  _Jv_JNI_GetPrimitiveArrayElements<jboolean, JvPrimClass (boolean)>,	    
					    // GetBooleanArrayElements
  _Jv_JNI_GetPrimitiveArrayElements<jbyte, JvPrimClass (byte)>,	 
					    // GetByteArrayElements
  _Jv_JNI_GetPrimitiveArrayElements<jchar, JvPrimClass (char)>,
					    // GetCharArrayElements
  _Jv_JNI_GetPrimitiveArrayElements<jshort, JvPrimClass (short)>,	    
					    // GetShortArrayElements
  _Jv_JNI_GetPrimitiveArrayElements<jint, JvPrimClass (int)>,		    
					    // GetIntArrayElements
  _Jv_JNI_GetPrimitiveArrayElements<jlong, JvPrimClass (long)>,		    
					    // GetLongArrayElements
  _Jv_JNI_GetPrimitiveArrayElements<jfloat, JvPrimClass (float)>,	    
					    // GetFloatArrayElements
  _Jv_JNI_GetPrimitiveArrayElements<jdouble, JvPrimClass (double)>,	    
					    // GetDoubleArrayElements
  _Jv_JNI_ReleasePrimitiveArrayElements<jboolean, JvPrimClass (boolean)>,    
					    // ReleaseBooleanArrayElements
  _Jv_JNI_ReleasePrimitiveArrayElements<jbyte, JvPrimClass (byte)>,    
					    // ReleaseByteArrayElements
  _Jv_JNI_ReleasePrimitiveArrayElements<jchar, JvPrimClass (char)>,    
					    // ReleaseCharArrayElements
  _Jv_JNI_ReleasePrimitiveArrayElements<jshort, JvPrimClass (short)>,	 
					    // ReleaseShortArrayElements
  _Jv_JNI_ReleasePrimitiveArrayElements<jint, JvPrimClass (int)>,    
					    // ReleaseIntArrayElements
  _Jv_JNI_ReleasePrimitiveArrayElements<jlong, JvPrimClass (long)>,    
					    // ReleaseLongArrayElements
  _Jv_JNI_ReleasePrimitiveArrayElements<jfloat, JvPrimClass (float)>,	 
					    // ReleaseFloatArrayElements
  _Jv_JNI_ReleasePrimitiveArrayElements<jdouble, JvPrimClass (double)>,	   
					    // ReleaseDoubleArrayElements
  _Jv_JNI_GetPrimitiveArrayRegion<jboolean, JvPrimClass (boolean)>,	    
					    // GetBooleanArrayRegion
  _Jv_JNI_GetPrimitiveArrayRegion<jbyte, JvPrimClass (byte)>,	    
					    // GetByteArrayRegion
  _Jv_JNI_GetPrimitiveArrayRegion<jchar, JvPrimClass (char)>,	    
					    // GetCharArrayRegion
  _Jv_JNI_GetPrimitiveArrayRegion<jshort, JvPrimClass (short)>,	    
					    // GetShortArrayRegion
  _Jv_JNI_GetPrimitiveArrayRegion<jint, JvPrimClass (int)>,	    
					    // GetIntArrayRegion
  _Jv_JNI_GetPrimitiveArrayRegion<jlong, JvPrimClass (long)>,	    
					    // GetLongArrayRegion
  _Jv_JNI_GetPrimitiveArrayRegion<jfloat, JvPrimClass (float)>,	    
					    // GetFloatArrayRegion
  _Jv_JNI_GetPrimitiveArrayRegion<jdouble, JvPrimClass (double)>,	    
					    // GetDoubleArrayRegion
  _Jv_JNI_SetPrimitiveArrayRegion<jboolean, JvPrimClass (boolean)>,	    
					    // SetBooleanArrayRegion
  _Jv_JNI_SetPrimitiveArrayRegion<jbyte, JvPrimClass (byte)>,	    
					    // SetByteArrayRegion
  _Jv_JNI_SetPrimitiveArrayRegion<jchar, JvPrimClass (char)>,	    
					    // SetCharArrayRegion
  _Jv_JNI_SetPrimitiveArrayRegion<jshort, JvPrimClass (short)>,	    
					    // SetShortArrayRegion
  _Jv_JNI_SetPrimitiveArrayRegion<jint, JvPrimClass (int)>,	    
					    // SetIntArrayRegion
  _Jv_JNI_SetPrimitiveArrayRegion<jlong, JvPrimClass (long)>,	    
					    // SetLongArrayRegion
  _Jv_JNI_SetPrimitiveArrayRegion<jfloat, JvPrimClass (float)>,	    
					    // SetFloatArrayRegion
  _Jv_JNI_SetPrimitiveArrayRegion<jdouble, JvPrimClass (double)>,	    
					    // SetDoubleArrayRegion
  _Jv_JNI_RegisterNatives,		    // RegisterNatives
  _Jv_JNI_UnregisterNatives,		    // UnregisterNatives
  _Jv_JNI_MonitorEnter,			    // MonitorEnter
  _Jv_JNI_MonitorExit,			    // MonitorExit
  _Jv_JNI_GetJavaVM,			    // GetJavaVM

  _Jv_JNI_GetStringRegion,		    // GetStringRegion
  _Jv_JNI_GetStringUTFRegion,		    // GetStringUTFRegion
  _Jv_JNI_GetPrimitiveArrayCritical,	    // GetPrimitiveArrayCritical
  _Jv_JNI_ReleasePrimitiveArrayCritical,    // ReleasePrimitiveArrayCritical
  _Jv_JNI_GetStringCritical,		    // GetStringCritical
  _Jv_JNI_ReleaseStringCritical,	    // ReleaseStringCritical

  _Jv_JNI_NewWeakGlobalRef,		    // NewWeakGlobalRef
  _Jv_JNI_DeleteWeakGlobalRef,		    // DeleteWeakGlobalRef

  _Jv_JNI_ExceptionCheck,		    // ExceptionCheck

  _Jv_JNI_NewDirectByteBuffer,		    // NewDirectByteBuffer
  _Jv_JNI_GetDirectBufferAddress,	    // GetDirectBufferAddress
  _Jv_JNI_GetDirectBufferCapacity	    // GetDirectBufferCapacity
};

struct JNIInvokeInterface _Jv_JNI_InvokeFunctions =
{
  RESERVED,
  RESERVED,
  RESERVED,

  _Jv_JNI_DestroyJavaVM,
  _Jv_JNI_AttachCurrentThread,
  _Jv_JNI_DetachCurrentThread,
  _Jv_JNI_GetEnv,
  _Jv_JNI_AttachCurrentThreadAsDaemon
};
