OSDN Git Service

* genrecog.c (write_switch): Avoid outputting of switch for
[pf3gnuchains/gcc-fork.git] / libjava / jni.cc
index f06e580..3f5703a 100644 (file)
@@ -1,6 +1,6 @@
 // jni.cc - JNI implementation, including the jump table.
 
-/* Copyright (C) 1998, 1999, 2000  Red Hat, Inc.
+/* Copyright (C) 1998, 1999, 2000, 2001  Free Software Foundation
 
    This file is part of libgcj.
 
@@ -20,6 +20,9 @@ details.  */
 #include <jvm.h>
 #include <java-assert.h>
 #include <jni.h>
+#ifdef ENABLE_JVMPI
+#include <jvmpi.h>
+#endif
 
 #include <java/lang/Class.h>
 #include <java/lang/ClassLoader.h>
@@ -36,6 +39,7 @@ details.  */
 #include <java/lang/OutOfMemoryError.h>
 #include <java/util/Hashtable.h>
 #include <java/lang/Integer.h>
+#include <java/lang/ThreadGroup.h>
 #include <gnu/gcj/jni/NativeThread.h>
 
 #include <gcj/method.h>
@@ -43,19 +47,13 @@ details.  */
 
 #include <java-interp.h>
 
-#define ClassClass _CL_Q34java4lang5Class
-extern java::lang::Class ClassClass;
-#define ObjectClass _CL_Q34java4lang6Object
-extern java::lang::Class ObjectClass;
-
-#define ThrowableClass _CL_Q34java4lang9Throwable
-extern java::lang::Class ThrowableClass;
-#define MethodClass _CL_Q44java4lang7reflect6Method
-extern java::lang::Class MethodClass;
-#define ThreadGroupClass _CL_Q34java4lang11ThreadGroup
-extern java::lang::Class ThreadGroupClass;
-#define NativeThreadClass _CL_Q43gnu3gcj3jni12NativeThread
-extern java::lang::Class ThreadGroupClass;
+// FIXME: remove these defines.
+#define ClassClass java::lang::Class::class$
+#define ObjectClass java::lang::Object::class$
+#define ThrowableClass java::lang::Throwable::class$
+#define MethodClass java::lang::reflect::Method::class$
+#define ThreadGroupClass java::lang::ThreadGroup::class$
+#define NativeThreadClass gnu::gcj::jni::NativeThread::class$
 
 // This enum is used to select different template instantiations in
 // the invocation code.
@@ -75,15 +73,22 @@ extern struct JNIInvokeInterface _Jv_JNI_InvokeFunctions;
 // 16.
 #define FRAME_SIZE 32
 
+// 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 true if this frame object represents a pushed frame (eg
   // from PushLocalFrame).
-  int marker :  1;
+  int marker :  2;
 
   // Number of elements in frame.
-  int size   : 31;
+  int size   : 30;
 
   // Next frame in chain.
   _Jv_JNI_LocalFrame *next;
@@ -98,12 +103,66 @@ static java::util::Hashtable *ref_table;
 // The only VM.
 static JavaVM *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
+
 \f
 
 void
 _Jv_JNI_Init (void)
 {
   ref_table = new java::util::Hashtable;
+  
+#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.
@@ -169,7 +228,7 @@ _Jv_JNI_DeleteLocalRef (JNIEnv *env, jobject obj)
        }
 
       // Don't go past a marked frame.
-      JvAssert (! frame->marker);
+      JvAssert (frame->marker == MARK_NONE);
     }
 
   JvAssert (0);
@@ -194,7 +253,7 @@ _Jv_JNI_EnsureLocalCapacity (JNIEnv *env, jint size)
       return JNI_ERR;
     }
 
-  frame->marker = true;
+  frame->marker = MARK_NONE;
   frame->size = size;
   memset (&frame->vec[0], 0, size * sizeof (jobject));
   frame->next = env->locals;
@@ -211,7 +270,7 @@ _Jv_JNI_PushLocalFrame (JNIEnv *env, jint size)
     return r;
 
   // The new frame is on top.
-  env->locals->marker = true;
+  env->locals->marker = MARK_USER;
 
   return 0;
 }
@@ -248,7 +307,7 @@ _Jv_JNI_NewLocalRef (JNIEnv *env, jobject obj)
 }
 
 static jobject
-_Jv_JNI_PopLocalFrame (JNIEnv *env, jobject result)
+_Jv_JNI_PopLocalFrame (JNIEnv *env, jobject result, int stop)
 {
   _Jv_JNI_LocalFrame *rf = env->locals;
 
@@ -260,7 +319,7 @@ _Jv_JNI_PopLocalFrame (JNIEnv *env, jobject result)
          unmark_for_gc (rf->vec[i]);
 
       // If the frame we just freed is the marker frame, we are done.
-      done = rf->marker;
+      done = (rf->marker == stop);
 
       _Jv_JNI_LocalFrame *n = rf->next;
       // When N==NULL, we've reached the stack-allocated frame, and we
@@ -276,9 +335,33 @@ _Jv_JNI_PopLocalFrame (JNIEnv *env, jobject result)
       rf = n;
     }
 
+  // Update the local frame information.
+  env->locals = rf;
+
   return result == NULL ? NULL : _Jv_JNI_NewLocalRef (env, result);
 }
 
+static jobject
+_Jv_JNI_PopLocalFrame (JNIEnv *env, jobject result)
+{
+  return _Jv_JNI_PopLocalFrame (env, result, MARK_USER);
+}
+
+// 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)
+{
+  _Jv_JNI_PopLocalFrame (env, NULL, MARK_SYSTEM);
+
+  if (env->ex)
+    {
+      jthrowable t = env->ex;
+      env->ex = NULL;
+      throw t;
+    }
+}
+
 // 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.
@@ -289,11 +372,15 @@ wrap_value (JNIEnv *, T value)
   return value;
 }
 
-template<>
-static jobject
-wrap_value (JNIEnv *env, jobject value)
+// This specialization is used for jobject, jclass, jstring, jarray,
+// etc.
+template<typename T>
+static T *
+wrap_value (JNIEnv *env, T *value)
 {
-  return value == NULL ? value : _Jv_JNI_NewLocalRef (env, value);
+  return (value == NULL
+         ? value
+         : (T *) _Jv_JNI_NewLocalRef (env, (jobject) value));
 }
 
 \f
@@ -343,15 +430,16 @@ _Jv_JNI_FindClass (JNIEnv *env, const char *name)
       // This might throw an out of memory exception.
       jstring n = JvNewStringUTF (s);
 
-      java::lang::ClassLoader *loader;
-      if (env->klass == NULL)
+      java::lang::ClassLoader *loader = NULL;
+      if (env->klass != NULL)
+       loader = env->klass->getClassLoader ();
+
+      if (loader == NULL)
        {
          // FIXME: should use getBaseClassLoader, but we don't have that
          // yet.
          loader = java::lang::ClassLoader::getSystemClassLoader ();
        }
-      else
-       loader = env->klass->getClassLoader ();
 
       r = loader->loadClass (n);
     }
@@ -512,7 +600,13 @@ _Jv_JNI_GetAnyMethodID (JNIEnv *env, jclass clazz,
       _Jv_InitClass (clazz);
 
       _Jv_Utf8Const *name_u = _Jv_makeUtf8Const ((char *) name, -1);
-      _Jv_Utf8Const *sig_u = _Jv_makeUtf8Const ((char *) sig, -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());
 
@@ -972,19 +1066,22 @@ _Jv_JNI_GetAnyFieldID (JNIEnv *env, jclass clazz,
 
       _Jv_Utf8Const *a_name = _Jv_makeUtf8Const ((char *) name, -1);
 
-      jclass field_class = NULL;
-      if (sig[0] == '[')
-       field_class = _Jv_FindClassFromSignature ((char *) sig, NULL);
-      else
-       {
-         _Jv_Utf8Const *sig_u = _Jv_makeUtf8Const ((char *) sig, -1);
-         field_class = _Jv_FindClass (sig_u, NULL);
-       }
+      // 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];
+      jclass field_class = _Jv_FindClassFromSignature ((char *) s, NULL);
 
       // FIXME: what if field_class == NULL?
 
+      java::lang::ClassLoader *loader = clazz->getClassLoader ();
       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));
@@ -993,12 +1090,11 @@ _Jv_JNI_GetAnyFieldID (JNIEnv *env, jclass clazz,
                            : JvGetFirstInstanceField (clazz));
          for (jint i = 0; i < count; ++i)
            {
-             // The field is resolved as a side effect of class
-             // initialization.
-             JvAssert (field->isResolved ());
-
              _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_ResolveField (field, loader);
              if (_Jv_equalUtf8Consts (f_name, a_name)
                  && field->getClass() == field_class)
                return field;
@@ -1268,7 +1364,9 @@ _Jv_JNI_GetPrimitiveArrayRegion (JNIEnv *env, JArray<T> *array,
                                 jsize start, jsize len,
                                 T *buf)
 {
-  if (start < 0 || len >= array->length || start + len >= array->length)
+  // The cast to unsigned lets us save a comparison.
+  if (start < 0 || len < 0
+      || (unsigned long) (start + len) > (unsigned long) array->length)
     {
       try
        {
@@ -1293,7 +1391,9 @@ static void
 _Jv_JNI_SetPrimitiveArrayRegion (JNIEnv *env, JArray<T> *array, 
                                 jsize start, jsize len, T *buf)
 {
-  if (start < 0 || len >= array->length || start + len >= array->length)
+  // The cast to unsigned lets us save a comparison.
+  if (start < 0 || len < 0
+      || (unsigned long) (start + len) > (unsigned long) array->length)
     {
       try
        {
@@ -1336,7 +1436,8 @@ _Jv_JNI_MonitorEnter (JNIEnv *env, jobject obj)
 {
   try
     {
-      return _Jv_MonitorEnter (obj);
+      _Jv_MonitorEnter (obj);
+      return 0;
     }
   catch (jthrowable t)
     {
@@ -1350,7 +1451,8 @@ _Jv_JNI_MonitorExit (JNIEnv *env, jobject obj)
 {
   try
     {
-      return _Jv_MonitorExit (obj);
+      _Jv_MonitorExit (obj);
+      return 0;
     }
   catch (jthrowable t)
     {
@@ -1506,8 +1608,6 @@ _Jv_JNI_UnregisterNatives (JNIEnv *, jclass)
 
 \f
 
-#ifdef INTERPRETER
-
 // Add a character to the buffer, encoding properly.
 static void
 add_char (char *buf, jchar c, int *here)
@@ -1527,11 +1627,14 @@ add_char (char *buf, jchar c, int *here)
       buf[(*here)++] = '_';
       buf[(*here)++] = '3';
     }
-  else if (c == '/')
+
+  // 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'))
+          || (c >= 'a' && c <= 'z')
+          || (c >= 'A' && c <= 'Z'))
     buf[(*here)++] = (char) c;
   else
     {
@@ -1541,7 +1644,7 @@ add_char (char *buf, jchar c, int *here)
       for (int i = 0; i < 4; ++i)
        {
          int val = c & 0x0f;
-         buf[(*here) + 4 - i] = (val > 10) ? ('a' + val - 10) : ('0' + val);
+         buf[(*here) + 3 - i] = (val > 10) ? ('a' + val - 10) : ('0' + val);
          c >>= 4;
        }
       *here += 4;
@@ -1585,7 +1688,7 @@ mangled_name (jclass klass, _Jv_Utf8Const *func_name,
 
   const unsigned char *sig = (const unsigned char *) signature->data;
   limit = sig + signature->length;
-  JvAssert (signature[0] == '(');
+  JvAssert (sig[0] == '(');
   ++sig;
   while (1)
     {
@@ -1598,29 +1701,80 @@ mangled_name (jclass klass, _Jv_Utf8Const *func_name,
   buf[here] = '\0';
 }
 
-// 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)
+// 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)
 {
-  _Jv_JNIMethod* _this = (_Jv_JNIMethod *) __this;
+  JNIEnv *env = _Jv_GetCurrentJNIEnv ();
+  if (env == NULL)
+    {
+      env = (JNIEnv *) _Jv_MallocUnchecked (sizeof (JNIEnv));
+      env->p = &_Jv_JNIFunctions;
+      env->ex = NULL;
+      env->klass = klass;
+      env->locals = NULL;
 
-  JNIEnv env;
-  _Jv_JNI_LocalFrame *frame
-    = (_Jv_JNI_LocalFrame *) alloca (sizeof (_Jv_JNI_LocalFrame)
-                                    + FRAME_SIZE * sizeof (jobject));
+      _Jv_SetCurrentJNIEnv (env);
+    }
 
-  env.p = &_Jv_JNIFunctions;
-  env.ex = NULL;
-  env.klass = _this->defining_class;
-  env.locals = frame;
+  _Jv_JNI_LocalFrame *frame
+    = (_Jv_JNI_LocalFrame *) _Jv_MallocUnchecked (sizeof (_Jv_JNI_LocalFrame)
+                                                 + (FRAME_SIZE
+                                                    * sizeof (jobject)));
 
-  frame->marker = true;
-  frame->next = NULL;
+  frame->marker = MARK_SYSTEM;
   frame->size = FRAME_SIZE;
+  frame->next = env->locals;
+  env->locals = frame;
+
   for (int i = 0; i < frame->size; ++i)
     frame->vec[i] = NULL;
 
+  return 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)
+{
+  char buf[10 + 6 * (name->length + signature->length)];
+  int long_start;
+  void *function;
+
+  mangled_name (klass, name, signature, buf, &long_start);
+  char c = buf[long_start];
+  buf[long_start] = '\0';
+  function = _Jv_FindSymbolInExecutable (buf);
+  if (function == NULL)
+    {
+      buf[long_start] = c;
+      function = _Jv_FindSymbolInExecutable (buf);
+      if (function == NULL)
+       {
+         jstring str = JvNewStringUTF (name->data);
+         throw new java::lang::AbstractMethodError (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.
@@ -1629,33 +1783,16 @@ _Jv_JNIMethod::call (ffi_cif *, void *ret, ffi_raw *args, void *__this)
   // a value we don't cache that fact -- we might subsequently load a
   // library which finds the function in question.
   if (_this->function == NULL)
-    {
-      char buf[10 + 6 * (_this->self->name->length
-                        + _this->self->signature->length)];
-      int long_start;
-      mangled_name (_this->defining_class, _this->self->name,
-                   _this->self->signature, buf, &long_start);
-      char c = buf[long_start];
-      buf[long_start] = '\0';
-      _this->function = _Jv_FindSymbolInExecutable (buf);
-      if (_this->function == NULL)
-       {
-         buf[long_start] = c;
-         _this->function = _Jv_FindSymbolInExecutable (buf);
-         if (_this->function == NULL)
-           {
-             jstring str = JvNewStringUTF (_this->self->name->data);
-             JvThrow (new java::lang::AbstractMethodError (str));
-           }
-       }
-    }
+    _this->function = _Jv_LookupJNIMethod (_this->defining_class,
+                                          _this->self->name,
+                                          _this->self->signature);
 
   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;
+  real_args[offset++].ptr = env;
 
   // For a static method, we pass in the Class.  For non-static
   // methods, the `this' argument is already handled.
@@ -1666,17 +1803,10 @@ _Jv_JNIMethod::call (ffi_cif *, void *ret, ffi_raw *args, void *__this)
   memcpy (&real_args[offset], args, _this->args_raw_size);
 
   // The actual call to the JNI function.
-  ffi_raw_call (&_this->jni_cif, (void (*) (...)) _this->function,
+  ffi_raw_call (&_this->jni_cif, (void (*)()) _this->function,
                ret, real_args);
 
-  do
-    {
-      _Jv_JNI_PopLocalFrame (&env, NULL);
-    }
-  while (env.locals != frame);
-
-  if (env.ex)
-    JvThrow (env.ex);
+  _Jv_JNI_PopSystemFrame (env);
 }
 
 #endif /* INTERPRETER */
@@ -1819,6 +1949,15 @@ _Jv_JNI_GetEnv (JavaVM *, void **penv, jint version)
       return JNI_EDETACHED;
     }
 
+#ifdef ENABLE_JVMPI
+  // Handle JVMPI requests.
+  if (version == JVMPI_VERSION_1)
+    {
+      *penv = (void *) &_Jv_JVMPI_Interface;
+      return 0;
+    }
+#endif
+
   // FIXME: do we really want to support 1.1?
   if (version != JNI_VERSION_1_2 && version != JNI_VERSION_1_1)
     {
@@ -1909,9 +2048,11 @@ JNI_CreateJavaVM (JavaVM **vm, void **penv, void *args)
 }
 
 jint
-JNI_GetCreatedJavaVMs (JavaVM **vm_buffer, jsize /* buf_len */, jsize *n_vms)
+JNI_GetCreatedJavaVMs (JavaVM **vm_buffer, jsize buf_len, jsize *n_vms)
 {
-  JvAssert (buf_len > 0);
+  if (buf_len <= 0)
+    return JNI_ERR;
+
   // We only support a single VM.
   if (the_vm != NULL)
     {
@@ -1964,239 +2105,240 @@ struct JNINativeInterface _Jv_JNIFunctions =
   RESERVED,
   RESERVED,
   RESERVED,
-  _Jv_JNI_GetVersion,
-  _Jv_JNI_DefineClass,
-  _Jv_JNI_FindClass,
-  _Jv_JNI_FromReflectedMethod,
-  _Jv_JNI_FromReflectedField,
-  _Jv_JNI_ToReflectedMethod,
-  _Jv_JNI_GetSuperclass,
-  _Jv_JNI_IsAssignableFrom,
-  _Jv_JNI_ToReflectedField,
-  _Jv_JNI_Throw,
-  _Jv_JNI_ThrowNew,
-  _Jv_JNI_ExceptionOccurred,
-  _Jv_JNI_ExceptionDescribe,
-  _Jv_JNI_ExceptionClear,
-  _Jv_JNI_FatalError,
-
-  _Jv_JNI_PushLocalFrame,
-  _Jv_JNI_PopLocalFrame,
-  _Jv_JNI_NewGlobalRef,
-  _Jv_JNI_DeleteGlobalRef,
-  _Jv_JNI_DeleteLocalRef,
-
-  _Jv_JNI_IsSameObject,
-
-  _Jv_JNI_NewLocalRef,
-  _Jv_JNI_EnsureLocalCapacity,
-
-  _Jv_JNI_AllocObject,
-  _Jv_JNI_NewObject,
-  _Jv_JNI_NewObjectV,
-  _Jv_JNI_NewObjectA,
-  _Jv_JNI_GetObjectClass,
-  _Jv_JNI_IsInstanceOf,
-  _Jv_JNI_GetAnyMethodID<false>,
-
-  _Jv_JNI_CallMethod<jobject>,
-  _Jv_JNI_CallMethodV<jobject>,
-  _Jv_JNI_CallMethodA<jobject>,
-  _Jv_JNI_CallMethod<jboolean>,
-  _Jv_JNI_CallMethodV<jboolean>,
-  _Jv_JNI_CallMethodA<jboolean>,
-  _Jv_JNI_CallMethod<jbyte>,
-  _Jv_JNI_CallMethodV<jbyte>,
-  _Jv_JNI_CallMethodA<jbyte>,
-  _Jv_JNI_CallMethod<jchar>,
-  _Jv_JNI_CallMethodV<jchar>,
-  _Jv_JNI_CallMethodA<jchar>,
-  _Jv_JNI_CallMethod<jshort>,
-  _Jv_JNI_CallMethodV<jshort>,
-  _Jv_JNI_CallMethodA<jshort>,
-  _Jv_JNI_CallMethod<jint>,
-  _Jv_JNI_CallMethodV<jint>,
-  _Jv_JNI_CallMethodA<jint>,
-  _Jv_JNI_CallMethod<jlong>,
-  _Jv_JNI_CallMethodV<jlong>,
-  _Jv_JNI_CallMethodA<jlong>,
-  _Jv_JNI_CallMethod<jfloat>,
-  _Jv_JNI_CallMethodV<jfloat>,
-  _Jv_JNI_CallMethodA<jfloat>,
-  _Jv_JNI_CallMethod<jdouble>,
-  _Jv_JNI_CallMethodV<jdouble>,
-  _Jv_JNI_CallMethodA<jdouble>,
-  _Jv_JNI_CallVoidMethod,
-  _Jv_JNI_CallVoidMethodV,
-  _Jv_JNI_CallVoidMethodA,
+  _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>,
-  _Jv_JNI_CallAnyMethodV<jobject, nonvirtual>,
-  _Jv_JNI_CallAnyMethodA<jobject, nonvirtual>,
-  _Jv_JNI_CallAnyMethod<jboolean, nonvirtual>,
-  _Jv_JNI_CallAnyMethodV<jboolean, nonvirtual>,
-  _Jv_JNI_CallAnyMethodA<jboolean, nonvirtual>,
-  _Jv_JNI_CallAnyMethod<jbyte, nonvirtual>,
-  _Jv_JNI_CallAnyMethodV<jbyte, nonvirtual>,
-  _Jv_JNI_CallAnyMethodA<jbyte, nonvirtual>,
-  _Jv_JNI_CallAnyMethod<jchar, nonvirtual>,
-  _Jv_JNI_CallAnyMethodV<jchar, nonvirtual>,
-  _Jv_JNI_CallAnyMethodA<jchar, nonvirtual>,
-  _Jv_JNI_CallAnyMethod<jshort, nonvirtual>,
-  _Jv_JNI_CallAnyMethodV<jshort, nonvirtual>,
-  _Jv_JNI_CallAnyMethodA<jshort, nonvirtual>,
-  _Jv_JNI_CallAnyMethod<jint, nonvirtual>,
-  _Jv_JNI_CallAnyMethodV<jint, nonvirtual>,
-  _Jv_JNI_CallAnyMethodA<jint, nonvirtual>,
-  _Jv_JNI_CallAnyMethod<jlong, nonvirtual>,
-  _Jv_JNI_CallAnyMethodV<jlong, nonvirtual>,
-  _Jv_JNI_CallAnyMethodA<jlong, nonvirtual>,
-  _Jv_JNI_CallAnyMethod<jfloat, nonvirtual>,
-  _Jv_JNI_CallAnyMethodV<jfloat, nonvirtual>,
-  _Jv_JNI_CallAnyMethodA<jfloat, nonvirtual>,
-  _Jv_JNI_CallAnyMethod<jdouble, nonvirtual>,
-  _Jv_JNI_CallAnyMethodV<jdouble, nonvirtual>,
-  _Jv_JNI_CallAnyMethodA<jdouble, nonvirtual>,
-  _Jv_JNI_CallAnyVoidMethod<nonvirtual>,
-  _Jv_JNI_CallAnyVoidMethodV<nonvirtual>,
-  _Jv_JNI_CallAnyVoidMethodA<nonvirtual>,
-
-  _Jv_JNI_GetAnyFieldID<false>,
-  _Jv_JNI_GetField<jobject>,
-  _Jv_JNI_GetField<jboolean>,
-  _Jv_JNI_GetField<jbyte>,
-  _Jv_JNI_GetField<jchar>,
-  _Jv_JNI_GetField<jshort>,
-  _Jv_JNI_GetField<jint>,
-  _Jv_JNI_GetField<jlong>,
-  _Jv_JNI_GetField<jfloat>,
-  _Jv_JNI_GetField<jdouble>,
-  _Jv_JNI_SetField,
-  _Jv_JNI_SetField,
-  _Jv_JNI_SetField,
-  _Jv_JNI_SetField,
-  _Jv_JNI_SetField,
-  _Jv_JNI_SetField,
-  _Jv_JNI_SetField,
-  _Jv_JNI_SetField,
-  _Jv_JNI_SetField,
-  _Jv_JNI_GetAnyMethodID<true>,
-
-  _Jv_JNI_CallStaticMethod<jobject>,
-  _Jv_JNI_CallStaticMethodV<jobject>,
-  _Jv_JNI_CallStaticMethodA<jobject>,
-  _Jv_JNI_CallStaticMethod<jboolean>,
-  _Jv_JNI_CallStaticMethodV<jboolean>,
-  _Jv_JNI_CallStaticMethodA<jboolean>,
-  _Jv_JNI_CallStaticMethod<jbyte>,
-  _Jv_JNI_CallStaticMethodV<jbyte>,
-  _Jv_JNI_CallStaticMethodA<jbyte>,
-  _Jv_JNI_CallStaticMethod<jchar>,
-  _Jv_JNI_CallStaticMethodV<jchar>,
-  _Jv_JNI_CallStaticMethodA<jchar>,
-  _Jv_JNI_CallStaticMethod<jshort>,
-  _Jv_JNI_CallStaticMethodV<jshort>,
-  _Jv_JNI_CallStaticMethodA<jshort>,
-  _Jv_JNI_CallStaticMethod<jint>,
-  _Jv_JNI_CallStaticMethodV<jint>,
-  _Jv_JNI_CallStaticMethodA<jint>,
-  _Jv_JNI_CallStaticMethod<jlong>,
-  _Jv_JNI_CallStaticMethodV<jlong>,
-  _Jv_JNI_CallStaticMethodA<jlong>,
-  _Jv_JNI_CallStaticMethod<jfloat>,
-  _Jv_JNI_CallStaticMethodV<jfloat>,
-  _Jv_JNI_CallStaticMethodA<jfloat>,
-  _Jv_JNI_CallStaticMethod<jdouble>,
-  _Jv_JNI_CallStaticMethodV<jdouble>,
-  _Jv_JNI_CallStaticMethodA<jdouble>,
-  _Jv_JNI_CallStaticVoidMethod,
-  _Jv_JNI_CallStaticVoidMethodV,
-  _Jv_JNI_CallStaticVoidMethodA,
-
-  _Jv_JNI_GetAnyFieldID<true>,
-  _Jv_JNI_GetStaticField<jobject>,
-  _Jv_JNI_GetStaticField<jboolean>,
-  _Jv_JNI_GetStaticField<jbyte>,
-  _Jv_JNI_GetStaticField<jchar>,
-  _Jv_JNI_GetStaticField<jshort>,
-  _Jv_JNI_GetStaticField<jint>,
-  _Jv_JNI_GetStaticField<jlong>,
-  _Jv_JNI_GetStaticField<jfloat>,
-  _Jv_JNI_GetStaticField<jdouble>,
-  _Jv_JNI_SetStaticField,
-  _Jv_JNI_SetStaticField,
-  _Jv_JNI_SetStaticField,
-  _Jv_JNI_SetStaticField,
-  _Jv_JNI_SetStaticField,
-  _Jv_JNI_SetStaticField,
-  _Jv_JNI_SetStaticField,
-  _Jv_JNI_SetStaticField,
-  _Jv_JNI_SetStaticField,
-  _Jv_JNI_NewString,
-  _Jv_JNI_GetStringLength,
-  _Jv_JNI_GetStringChars,
-  _Jv_JNI_ReleaseStringChars,
-  _Jv_JNI_NewStringUTF,
-  _Jv_JNI_GetStringUTFLength,
-  _Jv_JNI_GetStringUTFChars,
-  _Jv_JNI_ReleaseStringUTFChars,
-  _Jv_JNI_GetArrayLength,
-  _Jv_JNI_NewObjectArray,
-  _Jv_JNI_GetObjectArrayElement,
-  _Jv_JNI_SetObjectArrayElement,
+  _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,          // GetStringUTFLength
+  _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)>,
-  _Jv_JNI_NewPrimitiveArray<jbyte, JvPrimClass (byte)>,
-  _Jv_JNI_NewPrimitiveArray<jchar, JvPrimClass (char)>,
-  _Jv_JNI_NewPrimitiveArray<jshort, JvPrimClass (short)>,
-  _Jv_JNI_NewPrimitiveArray<jint, JvPrimClass (int)>,
-  _Jv_JNI_NewPrimitiveArray<jlong, JvPrimClass (long)>,
-  _Jv_JNI_NewPrimitiveArray<jfloat, JvPrimClass (float)>,
-  _Jv_JNI_NewPrimitiveArray<jdouble, JvPrimClass (double)>,
-  _Jv_JNI_GetPrimitiveArrayElements,
-  _Jv_JNI_GetPrimitiveArrayElements,
-  _Jv_JNI_GetPrimitiveArrayElements,
-  _Jv_JNI_GetPrimitiveArrayElements,
-  _Jv_JNI_GetPrimitiveArrayElements,
-  _Jv_JNI_GetPrimitiveArrayElements,
-  _Jv_JNI_GetPrimitiveArrayElements,
-  _Jv_JNI_GetPrimitiveArrayElements,
-  _Jv_JNI_ReleasePrimitiveArrayElements,
-  _Jv_JNI_ReleasePrimitiveArrayElements,
-  _Jv_JNI_ReleasePrimitiveArrayElements,
-  _Jv_JNI_ReleasePrimitiveArrayElements,
-  _Jv_JNI_ReleasePrimitiveArrayElements,
-  _Jv_JNI_ReleasePrimitiveArrayElements,
-  _Jv_JNI_ReleasePrimitiveArrayElements,
-  _Jv_JNI_ReleasePrimitiveArrayElements,
-  _Jv_JNI_GetPrimitiveArrayRegion,
-  _Jv_JNI_GetPrimitiveArrayRegion,
-  _Jv_JNI_GetPrimitiveArrayRegion,
-  _Jv_JNI_GetPrimitiveArrayRegion,
-  _Jv_JNI_GetPrimitiveArrayRegion,
-  _Jv_JNI_GetPrimitiveArrayRegion,
-  _Jv_JNI_GetPrimitiveArrayRegion,
-  _Jv_JNI_GetPrimitiveArrayRegion,
-  _Jv_JNI_SetPrimitiveArrayRegion,
-  _Jv_JNI_SetPrimitiveArrayRegion,
-  _Jv_JNI_SetPrimitiveArrayRegion,
-  _Jv_JNI_SetPrimitiveArrayRegion,
-  _Jv_JNI_SetPrimitiveArrayRegion,
-  _Jv_JNI_SetPrimitiveArrayRegion,
-  _Jv_JNI_SetPrimitiveArrayRegion,
-  _Jv_JNI_SetPrimitiveArrayRegion,
-  _Jv_JNI_RegisterNatives,
-  _Jv_JNI_UnregisterNatives,
-  _Jv_JNI_MonitorEnter,
-  _Jv_JNI_MonitorExit,
-  _Jv_JNI_GetJavaVM,
-
-  _Jv_JNI_GetStringRegion,
-  _Jv_JNI_GetStringUTFRegion,
-  _Jv_JNI_GetPrimitiveArrayCritical,
-  _Jv_JNI_ReleasePrimitiveArrayCritical,
-  _Jv_JNI_GetStringCritical,
-  _Jv_JNI_ReleaseStringCritical,
+                                                           // 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,       // GetBooleanArrayElements
+  _Jv_JNI_GetPrimitiveArrayElements,       // GetByteArrayElements
+  _Jv_JNI_GetPrimitiveArrayElements,       // GetCharArrayElements
+  _Jv_JNI_GetPrimitiveArrayElements,       // GetShortArrayElements
+  _Jv_JNI_GetPrimitiveArrayElements,       // GetIntArrayElements
+  _Jv_JNI_GetPrimitiveArrayElements,       // GetLongArrayElements
+  _Jv_JNI_GetPrimitiveArrayElements,       // GetFloatArrayElements
+  _Jv_JNI_GetPrimitiveArrayElements,       // GetDoubleArrayElements
+  _Jv_JNI_ReleasePrimitiveArrayElements,    // ReleaseBooleanArrayElements
+  _Jv_JNI_ReleasePrimitiveArrayElements,    // ReleaseByteArrayElements
+  _Jv_JNI_ReleasePrimitiveArrayElements,    // ReleaseCharArrayElements
+  _Jv_JNI_ReleasePrimitiveArrayElements,    // ReleaseShortArrayElements
+  _Jv_JNI_ReleasePrimitiveArrayElements,    // ReleaseIntArrayElements
+  _Jv_JNI_ReleasePrimitiveArrayElements,    // ReleaseLongArrayElements
+  _Jv_JNI_ReleasePrimitiveArrayElements,    // ReleaseFloatArrayElements
+  _Jv_JNI_ReleasePrimitiveArrayElements,    // ReleaseDoubleArrayElements
+  _Jv_JNI_GetPrimitiveArrayRegion,         // GetBooleanArrayRegion
+  _Jv_JNI_GetPrimitiveArrayRegion,         // GetByteArrayRegion
+  _Jv_JNI_GetPrimitiveArrayRegion,         // GetCharArrayRegion
+  _Jv_JNI_GetPrimitiveArrayRegion,         // GetShortArrayRegion
+  _Jv_JNI_GetPrimitiveArrayRegion,         // GetIntArrayRegion
+  _Jv_JNI_GetPrimitiveArrayRegion,         // GetLongArrayRegion
+  _Jv_JNI_GetPrimitiveArrayRegion,         // GetFloatArrayRegion
+  _Jv_JNI_GetPrimitiveArrayRegion,         // GetDoubleArrayRegion
+  _Jv_JNI_SetPrimitiveArrayRegion,         // SetBooleanArrayRegion
+  _Jv_JNI_SetPrimitiveArrayRegion,         // SetByteArrayRegion
+  _Jv_JNI_SetPrimitiveArrayRegion,         // SetCharArrayRegion
+  _Jv_JNI_SetPrimitiveArrayRegion,         // SetShortArrayRegion
+  _Jv_JNI_SetPrimitiveArrayRegion,         // SetIntArrayRegion
+  _Jv_JNI_SetPrimitiveArrayRegion,         // SetLongArrayRegion
+  _Jv_JNI_SetPrimitiveArrayRegion,         // SetFloatArrayRegion
+  _Jv_JNI_SetPrimitiveArrayRegion,         // 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
 
   NOT_IMPL /* newweakglobalref */,
   NOT_IMPL /* deleteweakglobalref */,