* java/lang/reflect/natConstructor.cc (newInstance): Use
authortromey <tromey@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 21 Jan 2000 23:50:31 +0000 (23:50 +0000)
committertromey <tromey@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 21 Jan 2000 23:50:31 +0000 (23:50 +0000)
_Jv_CallAnyMethodA.
* include/jvm.h: Declare _Jv_CallAnyMethodA.
* java/lang/reflect/natMethod.cc (_Jv_CallAnyMethodA): Renamed
from _Jv_CallNonvirtualMethodA.  Changed interface; overloaded.
Include <jni.h>.
(COPY): Removed.
(invoke): Use _Jv_CallAnyMethodA.
(VAL): Redefined.
* java/lang/Class.h (Class): Declare JvGetFirstStaticField,
JvNumStaticFields, JvNumMethods, and JvGetFirstMethod as friend
functions.
(struct _Jv_Method): Added getNextMethod method.
(JvNumMethods): New function.
(JvGetFirstMethod): Likewise.
* gcj/field.h (JvGetFirstStaticField): New function.
(JvNumStaticFields): Likewise.
(getNextField): Renamed from getNextInstanceField.
(struct _Jv_Field): New method getClass.
* jni.cc: Wrote many new functions.
* include/jni.h (JNI_TRUE): Define.
(JNI_FALSE): Likewise.
(jobject, jclass, jstring, jarray, jthrowable, jobjectArray,
jbyteArray, jshortArray, jintArray, jlongArray, jbooleanArray,
jcharArray, jfloatArray, jdoubleArray): New typedefs.
(jfieldID, jmethodID): Likewise.
(JNI_COMMIT, JNI_ABORT): New defines.
(JNINativeMethod): New struct.
(struct JNINativeInterface): Correctly declared more entries.
(class _Jv_JNIEnv): Added `ex' member.
(JNI_VERSION_1_1): New define.
(JNI_VERSION_1_2): Likewise.

* boehm.cc (_Jv_MarkObj): Use getNextField, not
getNextInstanceField.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@31553 138bc75d-0d04-0410-961f-82ee72b054a4

libjava/ChangeLog
libjava/boehm.cc
libjava/gcj/field.h
libjava/gcj/method.h
libjava/include/jni.h
libjava/include/jvm.h
libjava/java/lang/Class.h
libjava/java/lang/reflect/natConstructor.cc
libjava/java/lang/reflect/natMethod.cc
libjava/jni.cc

index 8a8e629..ffe657a 100644 (file)
@@ -1,3 +1,41 @@
+2000-01-21  Tom Tromey  <tromey@cygnus.com>
+
+       * java/lang/reflect/natConstructor.cc (newInstance): Use
+       _Jv_CallAnyMethodA.
+       * include/jvm.h: Declare _Jv_CallAnyMethodA.
+       * java/lang/reflect/natMethod.cc (_Jv_CallAnyMethodA): Renamed
+       from _Jv_CallNonvirtualMethodA.  Changed interface; overloaded.
+       Include <jni.h>.
+       (COPY): Removed.
+       (invoke): Use _Jv_CallAnyMethodA.
+       (VAL): Redefined.
+       * java/lang/Class.h (Class): Declare JvGetFirstStaticField,
+       JvNumStaticFields, JvNumMethods, and JvGetFirstMethod as friend
+       functions.
+       (struct _Jv_Method): Added getNextMethod method.
+       (JvNumMethods): New function.
+       (JvGetFirstMethod): Likewise.
+       * gcj/field.h (JvGetFirstStaticField): New function.
+       (JvNumStaticFields): Likewise.
+       (getNextField): Renamed from getNextInstanceField.
+       (struct _Jv_Field): New method getClass.
+       * jni.cc: Wrote many new functions.
+       * include/jni.h (JNI_TRUE): Define.
+       (JNI_FALSE): Likewise.
+       (jobject, jclass, jstring, jarray, jthrowable, jobjectArray,
+       jbyteArray, jshortArray, jintArray, jlongArray, jbooleanArray,
+       jcharArray, jfloatArray, jdoubleArray): New typedefs.
+       (jfieldID, jmethodID): Likewise.
+       (JNI_COMMIT, JNI_ABORT): New defines.
+       (JNINativeMethod): New struct.
+       (struct JNINativeInterface): Correctly declared more entries.
+       (class _Jv_JNIEnv): Added `ex' member.
+       (JNI_VERSION_1_1): New define.
+       (JNI_VERSION_1_2): Likewise.
+
+       * boehm.cc (_Jv_MarkObj): Use getNextField, not
+       getNextInstanceField.
+
 2000-01-20  Tom Tromey  <tromey@cygnus.com>
 
        * resolve.cc (StringClass): Removed.
index c04e578..2c50c5c 100644 (file)
@@ -1,6 +1,6 @@
 // boehm.cc - interface between libjava and Boehm GC.
 
-/* Copyright (C) 1998, 1999  Red Hat, Inc.
+/* Copyright (C) 1998, 1999, 2000  Red Hat, Inc.
 
    This file is part of libgcj.
 
@@ -256,7 +256,7 @@ _Jv_MarkObj (void *addr, void *msp, void *msl, void * /*env*/)
                  MAYBE_MARK (w, mark_stack_ptr, mark_stack_limit,
                              obj, elabel);
                }
-             field = field->getNextInstanceField ();
+             field = field->getNextField ();
            }
          klass = klass->getSuperclass();
        }
index 219da9e..28006fc 100644 (file)
@@ -1,6 +1,6 @@
 // field.h - Header file for fieldID instances.  -*- c++ -*-
 
-/* Copyright (C) 1998, 1999  Red Hat, Inc.
+/* Copyright (C) 1998, 1999, 2000  Red Hat, Inc.
 
    This file is part of libgcj.
 
@@ -30,7 +30,7 @@ struct _Jv_Field
   _Jv_ushort           flags;
 
 #ifdef COMPACT_FIELDS
-  short                        nameIndex;  /* ofsfet in class's name table */
+  short                        nameIndex;  /* offset in class's name table */
 #else
   _Jv_ushort           bsize;  /* not really needed ... */
 #endif
@@ -51,7 +51,7 @@ struct _Jv_Field
   jobject getObjectField (jobject obj)
   { return *(jobject *)((char *)obj + getOffset ()); }
 
-  jfieldID getNextInstanceField () { return this + 1; }
+  jfieldID getNextField () { return this + 1; }
 
   jboolean isRef () 
     { 
@@ -66,6 +66,12 @@ struct _Jv_Field
        }
     }
 
+  jclass getClass ()
+  {
+    JvAssert (isResolved ());
+    return type;
+  }
+
   // FIXME - may need to mask off internal flags.
   int getModifiers() { return flags; }
 
@@ -79,6 +85,7 @@ struct _Jv_Field
 };
 
 #ifdef __cplusplus
+
 inline jbyte
 _Jv_GetStaticByteField (jclass, _Jv_Field* field)
 {
@@ -151,6 +158,18 @@ JvNumInstanceFields (jclass klass)
   return klass->field_count - klass->static_field_count;
 }
 
+extern inline jfieldID
+JvGetFirstStaticField (jclass klass)
+{
+  return &(klass->fields[0]);
+}
+
+extern inline jint
+JvNumStaticFields (jclass klass)
+{
+  return klass->static_field_count;
+}
+
 extern inline jboolean
 JvFieldIsRef (jfieldID field)
 {
@@ -164,6 +183,6 @@ JvGetObjectField (jobject obj, _Jv_Field* field)
 }
 #endif /* defined (__GCJ_CNI_H__) */
 
-#endif
+#endif /* __cplusplus */
 
 #endif /* __GCJ_FIELD_H */
index 13f30fe..fe8f03b 100644 (file)
@@ -1,6 +1,6 @@
-// java-method.h - Header file for methodID instances.  -*- c++ -*-
+// method.h - Header file for methodID instances.  -*- c++ -*-
 
-/* Copyright (C) 1999  Red Hat, Inc.
+/* Copyright (C) 1999, 2000  Red Hat, Inc.
 
    This file is part of libgcj.
 
@@ -11,8 +11,10 @@ details.  */
 #ifndef __GCJ_METHOD_H__
 #define __GCJ_METHOD_H__
 
+#include <java/lang/Class.h>
+
 extern inline jmethodID
-_Jv_FromReflectedMethod(java::lang::reflect::Method *method)
+_Jv_FromReflectedMethod (java::lang::reflect::Method *method)
 {
   return (jmethodID)
     ((char *) method->declaringClass->methods + method->offset);
index f5186e5..c2ba2f2 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998, 1999  Red Hat, Inc.
+/* Copyright (C) 1998, 1999, 2000  Red Hat, Inc.
 
    This file is part of libgcj.
 
@@ -6,6 +6,11 @@ This software is copyrighted work licensed under the terms of the
 Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
 details.  */
 
+/* Note: this file must be compilable by the C compiler (for now,
+   assuming GNU C is ok).  This means you must never use `//'
+   comments, and all C++-specific code must be conditional on
+   __cplusplus.  */
+
 #ifndef __GCJ_JNI_H__
 #define __GCJ_JNI_H__
 
@@ -14,11 +19,15 @@ details.  */
 
 #ifdef __cplusplus
 
-// This is wrong, because it pollutes the name-space too much!
+/* This is wrong, because it pollutes the name-space too much! */
 #include <gcj/javaprims.h>
 
 typedef struct _Jv_JNIEnv JNIEnv;
-#else
+
+#define JNI_TRUE true
+#define JNI_FALSE false
+
+#else /* __cplusplus */
 
 typedef int    jbyte  __attribute__((__mode__(__QI__)));
 typedef int    jshort __attribute__((__mode__(__HI__)));
@@ -30,20 +39,51 @@ typedef float  jfloat;
 typedef double jdouble;
 typedef jint jsize;
 
+typedef void *jobject;
+typedef jobject jclass;
+typedef jobject jstring;
+typedef jobject jarray;
+typedef jobject jthrowable;
+typedef jobject jobjectArray;
+typedef jobject jbyteArray;
+typedef jobject jshortArray;
+typedef jobject jintArray;
+typedef jobject jlongArray;
+typedef jobject jbooleanArray;
+typedef jobject jcharArray;
+typedef jobject jfloatArray;
+typedef jobject jdoubleArray;
+
+/* Dummy defines.  */
+typedef void *jfieldID;
+typedef void *jmethodID;
+
 typedef const struct JNINativeInterface *JNIEnv;
-#endif
+
+#define JNI_TRUE 1
+#define JNI_TRUE 0
+
+#endif /* __cplusplus */
+
+/* Version numbers.  */
+#define JNI_VERSION_1_1 0x00010001
+#define JNI_VERSION_1_2 0x00010002
+
+/* Used when releasing array elements.  */
+#define JNI_COMMIT 1
+#define JNI_ABORT  2
 
 typedef union jvalue
 {
   jboolean z;
   jbyte    b;
   jchar    c;
-  jshort  s;
-  jint    i;
+  jshort   s;
+  jint     i;
   jlong    j;
-  jfloat  f;
+  jfloat   f;
   jdouble  d;
-  jobject l;
+  jobject  l;
 } jvalue;
 
 typedef void * (*_Jv_func)(...);
@@ -54,7 +94,7 @@ struct JNINativeInterface
   _Jv_func reserved1;
   _Jv_func reserved2;
   _Jv_func reserved3;
-  _Jv_func GetVersion;
+  jint     (*GetVersion)                   (JNIEnv*);
   _Jv_func DefineClass;
   _Jv_func FindClass;
   _Jv_func reserved4;
@@ -64,233 +104,415 @@ struct JNINativeInterface
   jboolean (*IsAssignableFrom)             (JNIEnv*, jclass, jclass);
   _Jv_func reserved7;
   jint     (*Throw)                        (JNIEnv*, jthrowable);
-  _Jv_func ThrowNew;
-  _Jv_func ExceptionOccurred;
-  _Jv_func ExceptionDescribe;
-  _Jv_func ExceptionClear;
-  _Jv_func FatalError;
+  jint     (*ThrowNew)                     (JNIEnv*, jclass, const char *);
+  jthrowable (*ExceptionOccurred)          (JNIEnv *);
+  void     (*ExceptionDescribe)            (JNIEnv *);
+  void     (*ExceptionClear)               (JNIEnv *);
+  void     (*FatalError)                   (JNIEnv *, const char *);
   _Jv_func reserved8;
   _Jv_func reserved9;
   _Jv_func NewGlobalRef;
   _Jv_func DeleteGlobalRef;
   _Jv_func DeleteLocalRef;
-  _Jv_func IsSameObject;
+  jboolean (*IsSameObject)                 (JNIEnv *, jobject, jobject);
   _Jv_func reserved10;
   _Jv_func reserved11;
-  _Jv_func AllocObject;
-  _Jv_func NewObject;
-  _Jv_func NewObjectV;
-  _Jv_func NewObjectA;
-  _Jv_func GetObjectClass;
-  _Jv_func IsInstanceOf;
-  _Jv_func GetMethodID;
-  _Jv_func CallObjectMethod;
-  _Jv_func CallObjectMethodV;
-  _Jv_func CallObjectMethodA;
-  _Jv_func CallBooleanMethod;
-  _Jv_func CallBooleanMethodV;
-  _Jv_func CallBooleanMethodA;
-  _Jv_func CallByteMethod;
-  _Jv_func CallByteMethodV;
-  _Jv_func CallByteMethodA;
-  _Jv_func CallCharMethod;
-  _Jv_func CallCharMethodV;
-  _Jv_func CallCharMethodA;
-  _Jv_func CallShortMethod;
-  _Jv_func CallShortMethodV;
-  _Jv_func CallShortMethodA;
-  _Jv_func CallIntMethod;
-  _Jv_func CallIntMethodV;
-  _Jv_func CallIntMethodA;
-  _Jv_func CallLongMethod;
-  _Jv_func CallLongMethodV;
-  _Jv_func CallLongMethodA;
-  _Jv_func CallFloatMethod;
-  _Jv_func CallFloatMethodV;
-  _Jv_func CallFloatMethodA;
-  _Jv_func CallDoubleMethod;
-  _Jv_func CallDoubleMethodV;
-  _Jv_func CallDoubleMethodA;
-  _Jv_func CallVoidMethod;
-  _Jv_func CallVoidMethodV;
-  _Jv_func CallVoidMethodA;
-  _Jv_func CallNonvirtualObjectMethod;
-  _Jv_func CallNonvirtualObjectMethodV;
-  _Jv_func CallNonvirtualObjectMethodA;
-  jboolean (*CallNonvirtualBooleanMethod)  (JNIEnv*, jobject, jclass, jmethodID, ...);
-  jboolean (*CallNonvirtualBooleanMethodV) (JNIEnv*, jobject, jclass, jmethodID, _Jv_va_list);
-  jboolean (*CallNonvirtualBooleanMethodA) (JNIEnv*, jobject, jclass, jmethodID, jvalue*);
-  _Jv_func CallNonvirtualByteMethod;
-  _Jv_func CallNonvirtualByteMethodV;
-  _Jv_func CallNonvirtualByteMethodA;
-  _Jv_func CallNonvirtualCharMethod;
-  _Jv_func CallNonvirtualCharMethodV;
-  _Jv_func CallNonvirtualCharMethodA;
-  _Jv_func CallNonvirtualShortMethod;
-  _Jv_func CallNonvirtualShortMethodV;
-  _Jv_func CallNonvirtualShortMethodA;
-  _Jv_func CallNonvirtualIntMethod;
-  _Jv_func CallNonvirtualIntMethodV;
-  _Jv_func CallNonvirtualIntMethodA;
-  _Jv_func CallNonvirtualLongMethod;
-  _Jv_func CallNonvirtualLongMethodV;
-  _Jv_func CallNonvirtualLongMethodA;
-  _Jv_func CallNonvirtualFloatMethod;
-  _Jv_func CallNonvirtualFloatMethodV;
-  _Jv_func CallNonvirtualFloatMethodA;
-  _Jv_func CallNonvirtualDoubleMethod;
-  jdouble  (*CallNonvirtualDoubleMethodV)  (JNIEnv*, jobject, jclass, jmethodID, _Jv_va_list);
-  _Jv_func CallNonvirtualDoubleMethodA;
-  _Jv_func CallNonvirtualVoidMethod;
-  _Jv_func CallNonvirtualVoidMethodV;
-  _Jv_func CallNonvirtualVoidMethodA;
-  _Jv_func GetFieldID;
-  jobject  (*GetObjectField)               (JNIEnv*, jobject, jfieldID);
-  jboolean (*GetBooleanField)              (JNIEnv*, jobject, jfieldID);
-  jbyte    (*GetByteField)                 (JNIEnv*, jobject, jfieldID);
-  jchar    (*GetCharField)                 (JNIEnv*, jobject, jfieldID);
-  jshort   (*GetShortField)                (JNIEnv*, jobject, jfieldID);
-  jint     (*GetIntField)                  (JNIEnv*, jobject, jfieldID);
-  jlong    (*GetLongField)                 (JNIEnv*, jobject, jfieldID);
-  jfloat   (*GetFloatField)                (JNIEnv*, jobject, jfieldID);
-  jdouble  (*GetDoubleField)               (JNIEnv*, jobject, jfieldID);
-  _Jv_func SetObjectField;
-  _Jv_func SetBooleanField;
-  _Jv_func SetByteField;
-  _Jv_func SetCharField;
-  _Jv_func SetShortField;
-  _Jv_func SetIntField;
-  _Jv_func SetLongField;
-  _Jv_func SetFloatField;
-  _Jv_func SetDoubleField;
-  _Jv_func GetStaticMethodID;
-  _Jv_func CallStaticObjectMethod;
-  _Jv_func CallStaticObjectMethodV;
-  _Jv_func CallStaticObjectMethodA;
-  _Jv_func CallStaticBooleanMethod;
-  _Jv_func CallStaticBooleanMethodV;
-  _Jv_func CallStaticBooleanMethodA;
-  _Jv_func CallStaticByteMethod;
-  _Jv_func CallStaticByteMethodV;
-  _Jv_func CallStaticByteMethodA;
-  _Jv_func CallStaticCharMethod;
-  _Jv_func CallStaticCharMethodV;
-  _Jv_func CallStaticCharMethodA;
-  _Jv_func CallStaticShortMethod;
-  _Jv_func CallStaticShortMethodV;
-  _Jv_func CallStaticShortMethodA;
-  _Jv_func CallStaticIntMethod;
-  _Jv_func CallStaticIntMethodV;
-  _Jv_func CallStaticIntMethodA;
-  _Jv_func CallStaticLongMethod;
-  _Jv_func CallStaticLongMethodV;
-  _Jv_func CallStaticLongMethodA;
-  _Jv_func CallStaticFloatMethod;
-  _Jv_func CallStaticFloatMethodV;
-  _Jv_func CallStaticFloatMethodA;
-  _Jv_func CallStaticDoubleMethod;
-  _Jv_func CallStaticDoubleMethodV;
-  _Jv_func CallStaticDoubleMethodA;
-  _Jv_func CallStaticVoidMethod;
-  _Jv_func CallStaticVoidMethodV;
-  _Jv_func CallStaticVoidMethodA;
-  _Jv_func GetStaticFieldID;
-  _Jv_func GetStaticObjectField;
-  _Jv_func GetStaticBooleanField;
-  _Jv_func GetStaticByteField;
-  _Jv_func GetStaticCharField;
-  _Jv_func GetStaticShortField;
-  _Jv_func GetStaticIntField;
-  _Jv_func GetStaticLongField;
-  _Jv_func GetStaticFloatField;
-  _Jv_func GetStaticDoubleField;
-  _Jv_func SetStaticObjectField;
-  _Jv_func SetStaticBooleanField;
-  _Jv_func SetStaticByteField;
-  _Jv_func SetStaticCharField;
-  _Jv_func SetStaticShortField;
-  _Jv_func SetStaticIntField;
-  _Jv_func SetStaticLongField;
-  _Jv_func SetStaticFloatField;
-  _Jv_func SetStaticDoubleField;
-  _Jv_func NewString;
-  jint     (*GetStringLength)              (JNIEnv*, jstring);
-  _Jv_func GetStringChars;
-  _Jv_func ReleaseStringChars;
-  _Jv_func NewStringUTF;
-  _Jv_func GetStringUTFLength;
-  _Jv_func GetStringUTFChars;
-  _Jv_func ReleaseStringUTFChars;
-  _Jv_func GetArrayLength;
-  _Jv_func NewObjectArray;
-  _Jv_func GetObjectArrayElement;
-  _Jv_func SetObjectArrayElement;
-  _Jv_func NewBooleanArray;
-  _Jv_func NewByteArray;
-  _Jv_func NewCharArray;
-  _Jv_func NewShortArray;
-  _Jv_func NewIntArray;
-  _Jv_func NewLongArray;
-  _Jv_func NewFloatArray;
-  _Jv_func NewDoubleArray;
-  _Jv_func GetBooleanArrayElements;
-  _Jv_func GetByteArrayElements;
-  _Jv_func GetCharArrayElements;
-  _Jv_func GetShortArrayElements;
-  _Jv_func GetIntArrayElements;
-  _Jv_func GetLongArrayElements;
-  _Jv_func GetFloatArrayElements;
-  _Jv_func GetDoubleArrayElements;
-  _Jv_func ReleaseBooleanArrayElements;
-  _Jv_func ReleaseByteArrayElements;
-  _Jv_func ReleaseCharArrayElements;
-  _Jv_func ReleaseShortArrayElements;
-  _Jv_func ReleaseIntArrayElements;
-  _Jv_func ReleaseLongArrayElements;
-  _Jv_func ReleaseFloatArrayElements;
-  _Jv_func ReleaseDoubleArrayElements;
-  _Jv_func GetBooleanArrayRegion;
-  _Jv_func GetByteArrayRegion;
-  _Jv_func GetCharArrayRegion;
-  _Jv_func GetShortArrayRegion;
-  _Jv_func GetIntArrayRegion;
-  _Jv_func GetLongArrayRegion;
-  _Jv_func GetFloatArrayRegion;
-  _Jv_func GetDoubleArrayRegion;
-  _Jv_func SetBooleanArrayRegion;
-  _Jv_func SetByteArrayRegion;
-  _Jv_func SetCharArrayRegion;
-  _Jv_func SetShortArrayRegion;
-  _Jv_func SetIntArrayRegion;
-  _Jv_func SetLongArrayRegion;
-  _Jv_func SetFloatArrayRegion;
-  _Jv_func SetDoubleArrayRegion;
+
+  jobject  (*AllocObject)                  (JNIEnv *, jclass);
+  jobject (*NewObject)                    (JNIEnv *, jclass, jmethodID, ...);
+  jobject (*NewObjectV)                           (JNIEnv *, jclass, jmethodID,
+                                           _Jv_va_list);
+  jobject (*NewObjectA)                           (JNIEnv *, jclass, jmethodID,
+                                           jvalue *);
+
+  jclass   (*GetObjectClass)               (JNIEnv *, jobject);
+  jboolean (*IsInstanceOf)                 (JNIEnv *, jobject, jclass);
+  jmethodID (*GetMethodID)                 (JNIEnv *, jclass, const char *,
+                                           const char *);
+
+  jobject      (*CallObjectMethod)        (JNIEnv *, jobject, jmethodID,
+                                           ...);
+  jobject      (*CallObjectMethodV)       (JNIEnv *, jobject, jmethodID,
+                                           _Jv_va_list);
+  jobject      (*CallObjectMethodA)       (JNIEnv *, jobject, jmethodID,
+                                           jvalue *);
+  jboolean     (*CallBooleanMethod)       (JNIEnv *, jobject, jmethodID,
+                                           ...);
+  jboolean     (*CallBooleanMethodV)      (JNIEnv *, jobject, jmethodID,
+                                           _Jv_va_list);
+  jboolean     (*CallBooleanMethodA)      (JNIEnv *, jobject, jmethodID,
+                                           jvalue *);
+  jbyte        (*CallByteMethod)          (JNIEnv *, jobject, jmethodID,
+                                           ...);
+  jbyte        (*CallByteMethodV)         (JNIEnv *, jobject, jmethodID,
+                                           _Jv_va_list);
+  jbyte        (*CallByteMethodA)         (JNIEnv *, jobject, jmethodID,
+                                           jvalue *);
+  jchar        (*CallCharMethod)          (JNIEnv *, jobject, jmethodID,
+                                           ...);
+  jchar        (*CallCharMethodV)         (JNIEnv *, jobject, jmethodID,
+                                           _Jv_va_list);
+  jchar        (*CallCharMethodA)         (JNIEnv *, jobject, jmethodID,
+                                           jvalue *);
+  jshort       (*CallShortMethod)         (JNIEnv *, jobject, jmethodID,
+                                           ...);
+  jshort       (*CallShortMethodV)        (JNIEnv *, jobject, jmethodID,
+                                           _Jv_va_list);
+  jshort       (*CallShortMethodA)        (JNIEnv *, jobject, jmethodID,
+                                           jvalue *);
+  jint                 (*CallIntMethod)           (JNIEnv *, jobject, jmethodID,
+                                           ...);
+  jint                 (*CallIntMethodV)          (JNIEnv *, jobject, jmethodID,
+                                           _Jv_va_list);
+  jint                 (*CallIntMethodA)          (JNIEnv *, jobject, jmethodID,
+                                           jvalue *);
+  jlong        (*CallLongMethod)          (JNIEnv *, jobject, jmethodID,
+                                           ...);
+  jlong        (*CallLongMethodV)         (JNIEnv *, jobject, jmethodID,
+                                           _Jv_va_list);
+  jlong        (*CallLongMethodA)         (JNIEnv *, jobject, jmethodID,
+                                           jvalue *);
+  jfloat       (*CallFloatMethod)         (JNIEnv *, jobject, jmethodID,
+                                           ...);
+  jfloat       (*CallFloatMethodV)        (JNIEnv *, jobject, jmethodID,
+                                           _Jv_va_list);
+  jfloat       (*CallFloatMethodA)        (JNIEnv *, jobject, jmethodID,
+                                           jvalue *);
+  jdouble      (*CallDoubleMethod)        (JNIEnv *, jobject, jmethodID,
+                                           ...);
+  jdouble      (*CallDoubleMethodV)       (JNIEnv *, jobject, jmethodID,
+                                           _Jv_va_list);
+  jdouble      (*CallDoubleMethodA)       (JNIEnv *, jobject, jmethodID,
+                                           jvalue *);
+  void         (*CallVoidMethod)          (JNIEnv *, jobject, jmethodID,
+                                           ...);
+  void         (*CallVoidMethodV)         (JNIEnv *, jobject, jmethodID,
+                                           _Jv_va_list);
+  void         (*CallVoidMethodA)         (JNIEnv *, jobject, jmethodID,
+                                           jvalue *);
+
+  jobject   (*CallNonvirtualObjectMethod)  (JNIEnv *, jobject, jclass,
+                                           jmethodID, ...);
+  jobject   (*CallNonvirtualObjectMethodV) (JNIEnv *, jobject, jclass,
+                                           jmethodID, _Jv_va_list);
+  jobject   (*CallNonvirtualObjectMethodA) (JNIEnv *, jobject, jclass,
+                                           jmethodID, jvalue *);
+  jboolean  (*CallNonvirtualBooleanMethod) (JNIEnv *, jobject, jclass,
+                                           jmethodID, ...);
+  jboolean  (*CallNonvirtualBooleanMethodV) (JNIEnv *, jobject, jclass,
+                                            jmethodID, _Jv_va_list);
+  jboolean  (*CallNonvirtualBooleanMethodA) (JNIEnv *, jobject, jclass,
+                                            jmethodID, jvalue *);
+  jbyte     (*CallNonvirtualByteMethod)           (JNIEnv *, jobject, jclass,
+                                           jmethodID, ...);
+  jbyte     (*CallNonvirtualByteMethodV)   (JNIEnv *, jobject, jclass,
+                                           jmethodID, _Jv_va_list);
+  jbyte     (*CallNonvirtualByteMethodA)   (JNIEnv *, jobject, jclass,
+                                           jmethodID, jvalue *);
+  jchar     (*CallNonvirtualCharMethod)           (JNIEnv *, jobject, jclass,
+                                           jmethodID, ...);
+  jchar     (*CallNonvirtualCharMethodV)   (JNIEnv *, jobject, jclass,
+                                           jmethodID, _Jv_va_list);
+  jchar     (*CallNonvirtualCharMethodA)   (JNIEnv *, jobject, jclass,
+                                           jmethodID, jvalue *);
+  jshort    (*CallNonvirtualShortMethod)   (JNIEnv *, jobject, jclass,
+                                           jmethodID, ...);
+  jshort    (*CallNonvirtualShortMethodV)  (JNIEnv *, jobject, jclass,
+                                           jmethodID, _Jv_va_list);
+  jshort    (*CallNonvirtualShortMethodA)  (JNIEnv *, jobject, jclass,
+                                           jmethodID, jvalue *);
+  jint             (*CallNonvirtualIntMethod)     (JNIEnv *, jobject, jclass,
+                                           jmethodID, ...);
+  jint             (*CallNonvirtualIntMethodV)    (JNIEnv *, jobject, jclass,
+                                           jmethodID, _Jv_va_list);
+  jint             (*CallNonvirtualIntMethodA)    (JNIEnv *, jobject, jclass,
+                                           jmethodID, jvalue *);
+  jlong     (*CallNonvirtualLongMethod)           (JNIEnv *, jobject, jclass,
+                                           jmethodID, ...);
+  jlong     (*CallNonvirtualLongMethodV)   (JNIEnv *, jobject, jclass,
+                                           jmethodID, _Jv_va_list);
+  jlong     (*CallNonvirtualLongMethodA)   (JNIEnv *, jobject, jclass,
+                                           jmethodID, jvalue *);
+  jfloat    (*CallNonvirtualFloatMethod)   (JNIEnv *, jobject, jclass,
+                                           jmethodID, ...);
+  jfloat    (*CallNonvirtualFloatMethodV)  (JNIEnv *, jobject, jclass,
+                                           jmethodID, _Jv_va_list);
+  jfloat    (*CallNonvirtualFloatMethodA)  (JNIEnv *, jobject, jclass,
+                                           jmethodID, jvalue *);
+  jdouble   (*CallNonvirtualDoubleMethod)  (JNIEnv *, jobject, jclass,
+                                           jmethodID, ...);
+  jdouble   (*CallNonvirtualDoubleMethodV) (JNIEnv *, jobject, jclass,
+                                           jmethodID, _Jv_va_list);
+  jdouble   (*CallNonvirtualDoubleMethodA) (JNIEnv *, jobject, jclass,
+                                           jmethodID, jvalue *);
+  void      (*CallNonvirtualVoidMethod)           (JNIEnv *, jobject, jclass,
+                                           jmethodID, ...);
+  void      (*CallNonvirtualVoidMethodV)   (JNIEnv *, jobject, jclass,
+                                           jmethodID, _Jv_va_list);
+  void      (*CallNonvirtualVoidMethodA)   (JNIEnv *, jobject, jclass,
+                                           jmethodID, jvalue *);
+
+  jfieldID      (*GetFieldID)              (JNIEnv *, jclass, const char *,
+                                           const char *);
+
+  jobject  (*GetObjectField)               (JNIEnv *, jobject, jfieldID);
+  jboolean (*GetBooleanField)              (JNIEnv *, jobject, jfieldID);
+  jbyte    (*GetByteField)                 (JNIEnv *, jobject, jfieldID);
+  jchar    (*GetCharField)                 (JNIEnv *, jobject, jfieldID);
+  jshort   (*GetShortField)                (JNIEnv *, jobject, jfieldID);
+  jint     (*GetIntField)                  (JNIEnv *, jobject, jfieldID);
+  jlong    (*GetLongField)                 (JNIEnv *, jobject, jfieldID);
+  jfloat   (*GetFloatField)                (JNIEnv *, jobject, jfieldID);
+  jdouble  (*GetDoubleField)               (JNIEnv *, jobject, jfieldID);
+
+  void         (*SetObjectField)          (JNIEnv *, jobject,
+                                           jfieldID, jobject);
+  void         (*SetBooleanField)         (JNIEnv *, jobject,
+                                           jfieldID, jboolean);
+  void         (*SetByteField)            (JNIEnv *, jobject,
+                                           jfieldID, jbyte);
+  void         (*SetCharField)            (JNIEnv *, jobject,
+                                           jfieldID, jchar);
+  void         (*SetShortField)           (JNIEnv *, jobject,
+                                           jfieldID, jshort);
+  void         (*SetIntField)             (JNIEnv *, jobject,
+                                           jfieldID, jint);
+  void         (*SetLongField)            (JNIEnv *, jobject,
+                                           jfieldID, jlong);
+  void         (*SetFloatField)           (JNIEnv *, jobject,
+                                           jfieldID, jfloat);
+  void         (*SetDoubleField)          (JNIEnv *, jobject,
+                                           jfieldID, jdouble);
+
+  jmethodID (*GetStaticMethodID)           (JNIEnv *, jclass, const char *,
+                                           const char *);
+
+  jobject      (*CallStaticObjectMethod)  (JNIEnv *, jclass, jmethodID,
+                                           ...);
+  jobject      (*CallStaticObjectMethodV) (JNIEnv *, jclass, jmethodID,
+                                           _Jv_va_list);
+  jobject      (*CallStaticObjectMethodA) (JNIEnv *, jclass, jmethodID,
+                                           jvalue *);
+  jboolean     (*CallStaticBooleanMethod) (JNIEnv *, jclass, jmethodID,
+                                           ...);
+  jboolean     (*CallStaticBooleanMethodV) (JNIEnv *, jclass, jmethodID,
+                                            _Jv_va_list);
+  jboolean     (*CallStaticBooleanMethodA) (JNIEnv *, jclass, jmethodID,
+                                            jvalue *);
+  jbyte        (*CallStaticByteMethod)    (JNIEnv *, jclass, jmethodID,
+                                           ...);
+  jbyte        (*CallStaticByteMethodV)   (JNIEnv *, jclass, jmethodID,
+                                           _Jv_va_list);
+  jbyte        (*CallStaticByteMethodA)   (JNIEnv *, jclass, jmethodID,
+                                           jvalue *);
+  jchar        (*CallStaticCharMethod)    (JNIEnv *, jclass, jmethodID,
+                                           ...);
+  jchar        (*CallStaticCharMethodV)   (JNIEnv *, jclass, jmethodID,
+                                           _Jv_va_list);
+  jchar        (*CallStaticCharMethodA)   (JNIEnv *, jclass, jmethodID,
+                                           jvalue *);
+  jshort       (*CallStaticShortMethod)   (JNIEnv *, jclass, jmethodID,
+                                           ...);
+  jshort       (*CallStaticShortMethodV)  (JNIEnv *, jclass, jmethodID,
+                                           _Jv_va_list);
+  jshort       (*CallStaticShortMethodA)  (JNIEnv *, jclass, jmethodID,
+                                           jvalue *);
+  jint                 (*CallStaticIntMethod)     (JNIEnv *, jclass, jmethodID,
+                                           ...);
+  jint                 (*CallStaticIntMethodV)    (JNIEnv *, jclass, jmethodID,
+                                           _Jv_va_list);
+  jint                 (*CallStaticIntMethodA)    (JNIEnv *, jclass, jmethodID,
+                                           jvalue *);
+  jlong        (*CallStaticLongMethod)    (JNIEnv *, jclass, jmethodID,
+                                           ...);
+  jlong        (*CallStaticLongMethodV)   (JNIEnv *, jclass, jmethodID,
+                                           _Jv_va_list);
+  jlong        (*CallStaticLongMethodA)   (JNIEnv *, jclass, jmethodID,
+                                           jvalue *);
+  jfloat       (*CallStaticFloatMethod)   (JNIEnv *, jclass, jmethodID,
+                                           ...);
+  jfloat       (*CallStaticFloatMethodV)  (JNIEnv *, jclass, jmethodID,
+                                           _Jv_va_list);
+  jfloat       (*CallStaticFloatMethodA)  (JNIEnv *, jclass, jmethodID,
+                                           jvalue *);
+  jdouble      (*CallStaticDoubleMethod)  (JNIEnv *, jclass, jmethodID,
+                                           ...);
+  jdouble      (*CallStaticDoubleMethodV) (JNIEnv *, jclass, jmethodID,
+                                           _Jv_va_list);
+  jdouble      (*CallStaticDoubleMethodA) (JNIEnv *, jclass, jmethodID,
+                                           jvalue *);
+  void         (*CallStaticVoidMethod)    (JNIEnv *, jclass, jmethodID,
+                                           ...);
+  void         (*CallStaticVoidMethodV)   (JNIEnv *, jclass, jmethodID,
+                                           _Jv_va_list);
+  void         (*CallStaticVoidMethodA)   (JNIEnv *, jclass, jmethodID,
+                                           jvalue *);
+
+  jfieldID      (*GetStaticFieldID)        (JNIEnv *, jclass, const char *,
+                                           const char *);
+
+  jobject      (*GetStaticObjectField)    (JNIEnv *, jclass, jfieldID);
+  jboolean     (*GetStaticBooleanField)   (JNIEnv *, jclass, jfieldID);
+  jbyte                (*GetStaticByteField)      (JNIEnv *, jclass, jfieldID);
+  jchar                (*GetStaticCharField)      (JNIEnv *, jclass, jfieldID);
+  jshort       (*GetStaticShortField)     (JNIEnv *, jclass, jfieldID);
+  jint         (*GetStaticIntField)       (JNIEnv *, jclass, jfieldID);
+  jlong                (*GetStaticLongField)      (JNIEnv *, jclass, jfieldID);
+  jfloat       (*GetStaticFloatField)     (JNIEnv *, jclass, jfieldID);
+  jdouble      (*GetStaticDoubleField)    (JNIEnv *, jclass, jfieldID);
+
+  void                 (*SetStaticObjectField)    (JNIEnv *, jclass,
+                                           jfieldID, jobject);
+  void                 (*SetStaticBooleanField)   (JNIEnv *, jclass,
+                                           jfieldID, jboolean);
+  void                 (*SetStaticByteField)      (JNIEnv *, jclass,
+                                           jfieldID, jbyte);
+  void                 (*SetStaticCharField)      (JNIEnv *, jclass,
+                                           jfieldID, jchar);
+  void                 (*SetStaticShortField)     (JNIEnv *, jclass,
+                                           jfieldID, jshort);
+  void                 (*SetStaticIntField)       (JNIEnv *, jclass,
+                                           jfieldID, jint);
+  void                 (*SetStaticLongField)      (JNIEnv *, jclass,
+                                           jfieldID, jlong);
+  void                 (*SetStaticFloatField)     (JNIEnv *, jclass,
+                                           jfieldID, jfloat);
+  void                 (*SetStaticDoubleField)    (JNIEnv *, jclass,
+                                           jfieldID, jdouble);
+
+  jstring  (*NewString)                    (JNIEnv *, const jchar *, jsize);
+  jint     (*GetStringLength)              (JNIEnv *, jstring);
+  const jchar * (*GetStringChars)          (JNIEnv *, jstring, jboolean *);
+  void     (*ReleaseStringChars)           (JNIEnv *, jstring, const jchar *);
+  jstring  (*NewStringUTF)                 (JNIEnv *, const char *);
+  jsize    (*GetStringUTFLength)           (JNIEnv *, jstring);
+  const char * (*GetStringUTFChars)        (JNIEnv *, jstring, jboolean *);
+  void     (*ReleaseStringUTFChars)        (JNIEnv *, jstring, const char *);
+  jsize    (*GetArrayLength)               (JNIEnv *, jarray);
+  jarray   (*NewObjectArray)               (JNIEnv *, jsize, jclass, jobject);
+  jobject  (*GetObjectArrayElement)        (JNIEnv *, jobjectArray, jsize);
+  void     (*SetObjectArrayElement)        (JNIEnv *, jobjectArray, jsize,
+                                           jobject);
+
+  jbooleanArray (*NewBooleanArray)        (JNIEnv *, jsize);
+  jbyteArray    (*NewByteArray)                   (JNIEnv *, jsize);
+  jcharArray    (*NewCharArray)                   (JNIEnv *, jsize);
+  jshortArray   (*NewShortArray)          (JNIEnv *, jsize);
+  jintArray     (*NewIntArray)            (JNIEnv *, jsize);
+  jlongArray    (*NewLongArray)                   (JNIEnv *, jsize);
+  jfloatArray   (*NewFloatArray)          (JNIEnv *, jsize);
+  jdoubleArray  (*NewDoubleArray)         (JNIEnv *, jsize);
+
+  jboolean *   (*GetBooleanArrayElements) (JNIEnv *, jbooleanArray,
+                                           jboolean *);
+  jbyte *      (*GetByteArrayElements)    (JNIEnv *, jbyteArray,
+                                           jboolean *);
+  jchar *      (*GetCharArrayElements)    (JNIEnv *, jcharArray,
+                                           jboolean *);
+  jshort *     (*GetShortArrayElements)   (JNIEnv *, jshortArray,
+                                           jboolean *);
+  jint *       (*GetIntArrayElements)     (JNIEnv *, jintArray,
+                                           jboolean *);
+  jlong *      (*GetLongArrayElements)    (JNIEnv *, jlongArray,
+                                           jboolean *);
+  jfloat *     (*GetFloatArrayElements)   (JNIEnv *, jfloatArray,
+                                           jboolean *);
+  jdouble *    (*GetDoubleArrayElements)  (JNIEnv *, jdoubleArray,
+                                           jboolean *);
+
+  void         (*ReleaseBooleanArrayElements) (JNIEnv *, jbooleanArray,
+                                               jboolean *, jint);
+  void         (*ReleaseByteArrayElements)    (JNIEnv *, jbyteArray,
+                                               jbyte *, jint);
+  void         (*ReleaseCharArrayElements)    (JNIEnv *, jcharArray,
+                                               jchar *, jint);
+  void         (*ReleaseShortArrayElements)   (JNIEnv *, jshortArray,
+                                               jshort *, jint);
+  void         (*ReleaseIntArrayElements)     (JNIEnv *, jintArray,
+                                               jint *, jint);
+  void         (*ReleaseLongArrayElements)    (JNIEnv *, jlongArray,
+                                               jlong *, jint);
+  void         (*ReleaseFloatArrayElements)   (JNIEnv *, jfloatArray,
+                                               jfloat *, jint);
+  void         (*ReleaseDoubleArrayElements)  (JNIEnv *, jdoubleArray,
+                                               jdouble *, jint);
+
+  void                 (*GetBooleanArrayRegion)   (JNIEnv *, jbooleanArray,
+                                           jsize, jsize, jboolean *);
+  void                 (*GetByteArrayRegion)      (JNIEnv *, jbooleanArray,
+                                           jsize, jsize, jboolean *);
+  void                 (*GetCharArrayRegion)      (JNIEnv *, jbooleanArray,
+                                           jsize, jsize, jboolean *);
+  void                 (*GetShortArrayRegion)     (JNIEnv *, jbooleanArray,
+                                           jsize, jsize, jboolean *);
+  void                 (*GetIntArrayRegion)       (JNIEnv *, jbooleanArray,
+                                           jsize, jsize, jboolean *);
+  void                 (*GetLongArrayRegion)      (JNIEnv *, jbooleanArray,
+                                           jsize, jsize, jboolean *);
+  void                 (*GetFloatArrayRegion)     (JNIEnv *, jbooleanArray,
+                                           jsize, jsize, jboolean *);
+  void                 (*GetDoubleArrayRegion)    (JNIEnv *, jbooleanArray,
+                                           jsize, jsize, jboolean *);
+
+  void                 (*SetBooleanArrayRegion)   (JNIEnv *, jbooleanArray,
+                                           jsize, jsize, jboolean *);
+  void                 (*SetByteArrayRegion)      (JNIEnv *, jbooleanArray,
+                                           jsize, jsize, jboolean *);
+  void                 (*SetCharArrayRegion)      (JNIEnv *, jbooleanArray,
+                                           jsize, jsize, jboolean *);
+  void                 (*SetShortArrayRegion)     (JNIEnv *, jbooleanArray,
+                                           jsize, jsize, jboolean *);
+  void                 (*SetIntArrayRegion)       (JNIEnv *, jbooleanArray,
+                                           jsize, jsize, jboolean *);
+  void                 (*SetLongArrayRegion)      (JNIEnv *, jbooleanArray,
+                                           jsize, jsize, jboolean *);
+  void                 (*SetFloatArrayRegion)     (JNIEnv *, jbooleanArray,
+                                           jsize, jsize, jboolean *);
+  void                 (*SetDoubleArrayRegion)    (JNIEnv *, jbooleanArray,
+                                           jsize, jsize, jboolean *);
+
   _Jv_func RegisterNatives;
   _Jv_func UnregisterNatives;
-  _Jv_func MonitorEnter;
-  _Jv_func MonitorExit;
+  jint     (*MonitorEnter)                 (JNIEnv *, jobject);
+  jint     (*MonitorExit)                  (JNIEnv *, jobject);
   _Jv_func GetJavaVM;
 };
 
+/* This structure is used when registering native methods.  */
+typedef struct
+{
+  char *name;
+  char *signature;
+  void *fnPtr;                 /* Sigh.  */
+} JNINativeMethod;
+
 #ifdef __cplusplus
 
-struct _Jv_JNIEnv
+class _Jv_JNIEnv
 {
+public:
+  /* The method table.  */
   struct JNINativeInterface *p;
 
-  jclass GetSuperclass (jclass cl);
-  jsize GetStringLength (jstring str);
+private:
+  /* The current exception.  */
+  jthrowable ex;
 
-};
+  /* This doesn't really protect the private contents, because anybody
+     can set this macro.  However, if they do set it then they at
+     least know they are doing something unportable.  */
+#ifdef GCJ_JV_JNIENV_FRIEND
+  GCJ_JV_JNIENV_FRIEND;
+#endif
 
-extern inline jclass
-_Jv_JNIEnv::GetSuperclass (jclass cl)
-{ return p->GetSuperclass (this, cl); }
+public:
+  jclass GetSuperclass (jclass cl)
+  { return p->GetSuperclass (this, cl); }
 
-extern inline jsize
-_Jv_JNIEnv::GetStringLength (jstring str)
-{ return p->GetStringLength (this, str); }
+  jsize GetStringLength (jstring str)
+  { return p->GetStringLength (this, str); }
+};
 
-#endif
+#endif /* __cplusplus */
 
 #endif /* __GCJ_JNI_H__ */
index ab22cd8..a8d1fac 100644 (file)
@@ -1,6 +1,6 @@
 // jvm.h - Header file for private implementation information. -*- c++ -*-
 
-/* Copyright (C) 1998, 1999  Red Hat, Inc.
+/* Copyright (C) 1998, 1999, 2000  Red Hat, Inc.
 
    This file is part of libgcj.
 
@@ -166,9 +166,20 @@ extern void _Jv_GetTypesFromSignature (jmethodID method,
                                       jclass declaringClass,
                                       JArray<jclass> **arg_types_out,
                                       jclass *return_type_out);
-extern jobject _Jv_CallNonvirtualMethodA (jobject, jclass,
-                                         jmethodID, jboolean,
-                                         JArray<jclass> *, jobjectArray);
+
+extern jobject _Jv_CallAnyMethodA (jobject obj, jclass return_type,
+                                  jmethodID meth, jboolean is_constructor,
+                                  JArray<jclass> *parameter_types,
+                                  jobjectArray args);
+
+union jvalue;
+extern jthrowable _Jv_CallAnyMethodA (jobject obj,
+                                     jclass return_type,
+                                     jmethodID meth,
+                                     jboolean is_constructor,
+                                     JArray<jclass> *parameter_types,
+                                     jvalue *args,
+                                     jvalue *result);
 
 extern jobject _Jv_NewMultiArray (jclass, jint ndims, jint* dims)
   __attribute__((__malloc__));
index 2863adb..84834f3 100644 (file)
@@ -60,6 +60,9 @@ struct _Jv_Method
   _Jv_Utf8Const *signature;
   unsigned short accflags;
   void *ncode;
+
+  _Jv_Method *getNextMethod ()
+  { return this + 1; }
 };
 
 #define JV_PRIMITIVE_VTABLE ((_Jv_VTable *) -1)
@@ -168,13 +171,19 @@ private:
 
   friend jfieldID JvGetFirstInstanceField (jclass);
   friend jint JvNumInstanceFields (jclass);
+  friend jfieldID JvGetFirstStaticField (jclass);
+  friend jint JvNumStaticFields (jclass);
+
   friend jobject _Jv_AllocObject (jclass, jint);
   friend jobjectArray _Jv_NewObjectArray (jsize, jclass, jobject);
   friend jobject _Jv_NewPrimArray (jclass, jint);
   friend jobject _Jv_JNI_ToReflectedField (_Jv_JNIEnv *, jclass, jfieldID);
   friend jfieldID _Jv_FromReflectedField (java::lang::reflect::Field *);
+
   friend jmethodID _Jv_FromReflectedMethod (java::lang::reflect::Method *);
   friend jmethodID _Jv_FromReflectedConstructor (java::lang::reflect::Constructor *);
+  friend jint JvNumMethods (jclass);
+  friend jmethodID JvGetFirstMethod (jclass);
 
   friend class _Jv_PrimClass;
 
@@ -257,4 +266,17 @@ private:
   java::lang::Thread *thread;
 };
 
+
+extern inline jint
+JvNumMethods (jclass klass)
+{
+  return klass->method_count;
+}
+
+extern inline jmethodID
+JvGetFirstMethod (jclass klass)
+{
+  return &klass->methods[0];
+}
+
 #endif /* __JAVA_LANG_CLASS_H__ */
index 6b59c95..82eb3e9 100644 (file)
@@ -48,6 +48,6 @@ java::lang::reflect::Constructor::newInstance (jobjectArray args)
   jmethodID meth = _Jv_FromReflectedConstructor (this);
   // In the constructor case the return type is the type of the
   // constructor.
-  return _Jv_CallNonvirtualMethodA (NULL, declaringClass, meth, true,
-                                   parameter_types, args);
+  return _Jv_CallAnyMethodA (NULL, declaringClass, meth, true,
+                            parameter_types, args);
 }
index e88c0f3..988fa1e 100644 (file)
@@ -12,6 +12,7 @@ details.  */
 
 #include <gcj/cni.h>
 #include <jvm.h>
+#include <jni.h>
 
 #include <java/lang/reflect/Method.h>
 #include <java/lang/reflect/Constructor.h>
@@ -187,8 +188,8 @@ java::lang::reflect::Method::invoke (jobject obj, jobjectArray args)
       meth = _Jv_LookupDeclaredMethod (k, meth->name, meth->signature);
     }
 
-  return _Jv_CallNonvirtualMethodA (obj, return_type, meth, false,
-                                   parameter_types, args);
+  return _Jv_CallAnyMethodA (obj, return_type, meth, false,
+                            parameter_types, args);
 }
 
 jint
@@ -311,23 +312,22 @@ _Jv_GetTypesFromSignature (jmethodID method,
 // functions.  It handles both Methods and Constructors, and it can
 // handle any return type.  In the Constructor case, the `obj'
 // argument is unused and should be NULL; also, the `return_type' is
-// the class that the constructor will construct.
-jobject
-_Jv_CallNonvirtualMethodA (jobject obj,
-                          jclass return_type,
-                          jmethodID meth,
-                          jboolean is_constructor,
-                          JArray<jclass> *parameter_types,
-                          jobjectArray args)
+// the class that the constructor will construct.  RESULT is a pointer
+// to a `jvalue' (see jni.h); for a void method this should be NULL.
+// This function returns an exception (if one was thrown), or NULL if
+// the call went ok.
+jthrowable
+_Jv_CallAnyMethodA (jobject obj,
+                   jclass return_type,
+                   jmethodID meth,
+                   jboolean is_constructor,
+                   JArray<jclass> *parameter_types,
+                   jvalue *args,
+                   jvalue *result)
 {
   JvAssert (! is_constructor || ! obj);
   JvAssert (! is_constructor || ! return_type);
 
-  // FIXME: access checks.
-
-  if (parameter_types->length != args->length)
-    JvThrow (new java::lang::IllegalArgumentException);
-
   // See whether call needs an object as the first argument.  A
   // constructor does need a `this' argument, but it is one we create.
   jboolean needs_this = false;
@@ -349,7 +349,6 @@ _Jv_CallNonvirtualMethodA (jobject obj,
                                              * sizeof (ffi_type *));
 
   jclass *paramelts = elements (parameter_types);
-  jobject *argelts = elements (args);
 
   // FIXME: at some point the compiler is going to add extra arguments
   // to some functions.  In particular we are going to do this for
@@ -376,22 +375,11 @@ _Jv_CallNonvirtualMethodA (jobject obj,
 
   for (int arg = 0; i < param_count; ++i, ++arg)
     {
-      jclass k = argelts[arg] ? argelts[arg]->getClass() : NULL;
-      argtypes[i] = get_ffi_type (k);
+      argtypes[i] = get_ffi_type (paramelts[arg]);
       if (paramelts[arg]->isPrimitive())
-       {
-         if (! argelts[arg]
-             || ! k
-             || ! can_widen (k, paramelts[arg]))
-           JvThrow (new java::lang::IllegalArgumentException);
-         size += paramelts[arg]->size();
-       }
+       size += paramelts[arg]->size();
       else
-       {
-         if (argelts[arg] && ! paramelts[arg]->isAssignableFrom (k))
-           JvThrow (new java::lang::IllegalArgumentException);
-         size += sizeof (jobject);
-       }
+       size += sizeof (jobject);
     }
 
   ffi_cif cif;
@@ -404,89 +392,162 @@ _Jv_CallNonvirtualMethodA (jobject obj,
   char *p = (char *) alloca (size);
   void **values = (void **) alloca (param_count * sizeof (void *));
 
-#define COPY(Where, What, Type) \
-  do { \
-    Type val = (What); \
-    memcpy ((Where), &val, sizeof (Type)); \
-    values[i] = (Where); \
-    Where += sizeof (Type); \
-  } while (0)
-
   i = 0;
   if (needs_this)
     {
-      COPY (p, obj, jobject);
+      values[i] = p;
+      memcpy (p, &obj, sizeof (jobject));
+      p += sizeof (jobject);
       ++i;
     }
 
   for (int arg = 0; i < param_count; ++i, ++arg)
     {
-      java::lang::Number *num = (java::lang::Number *) argelts[arg];
-      if (paramelts[arg] == JvPrimClass (byte))
-       COPY (p, num->byteValue(), jbyte);
-      else if (paramelts[arg] == JvPrimClass (short))
-       COPY (p, num->shortValue(), jshort);
-      else if (paramelts[arg] == JvPrimClass (int))
-       COPY (p, num->intValue(), jint);
-      else if (paramelts[arg] == JvPrimClass (long))
-       COPY (p, num->longValue(), jlong);
-      else if (paramelts[arg] == JvPrimClass (float))
-       COPY (p, num->floatValue(), jfloat);
-      else if (paramelts[arg] == JvPrimClass (double))
-       COPY (p, num->doubleValue(), jdouble);
-      else if (paramelts[arg] == JvPrimClass (boolean))
-       COPY (p, ((java::lang::Boolean *) argelts[arg])->booleanValue(),
-             jboolean);
-      else if (paramelts[arg] == JvPrimClass (char))
-       COPY (p, ((java::lang::Character *) argelts[arg])->charValue(), jchar);
+      int tsize;
+      if (paramelts[arg]->isPrimitive())
+       tsize = paramelts[arg]->size();
       else
-       {
-         JvAssert (! paramelts[arg]->isPrimitive());
-         COPY (p, argelts[arg], jobject);
-       }
+       tsize = sizeof (jobject);
+
+      // Copy appropriate bits from the jvalue into the ffi array.
+      // FIXME: we could do this copying all in one loop, above, by
+      // over-allocating a bit.
+      values[i] = p;
+      memcpy (p, &args[arg], tsize);
+      p += tsize;
     }
 
   // FIXME: initialize class here.
 
-  // Largest possible value.  Hopefully it is aligned!
-  jdouble ret_value;
   java::lang::Throwable *ex;
   using namespace java::lang;
   using namespace java::lang::reflect;
   ex = Method::hack_trampoline ((gnu::gcj::RawData *) &cif,
                                (gnu::gcj::RawData *) meth->ncode,
-                               (gnu::gcj::RawData *) &ret_value,
+                               (gnu::gcj::RawData *) result,
                                (gnu::gcj::RawData *) values);
 
   if (ex)
-    JvThrow (new InvocationTargetException (ex));
+    // FIXME: this is wrong for JNI.  But if we just return the
+    // exception, then the non-JNI cases won't be able to distinguish
+    // it from exceptions we might generate ourselves.  Sigh.
+    ex = new InvocationTargetException (ex);
+
+  if (is_constructor)
+    result->l = obj;
+
+  return ex;
+}
+
+// This is another version of _Jv_CallAnyMethodA, but this one does
+// more checking and is used by the reflection (and not JNI) code.
+jobject
+_Jv_CallAnyMethodA (jobject obj,
+                   jclass return_type,
+                   jmethodID meth,
+                   jboolean is_constructor,
+                   JArray<jclass> *parameter_types,
+                   jobjectArray args)
+{
+  // FIXME: access checks.
+
+  if (parameter_types->length != args->length)
+    JvThrow (new java::lang::IllegalArgumentException);
+
+  int param_count = parameter_types->length;
+
+  jclass *paramelts = elements (parameter_types);
+  jobject *argelts = elements (args);
+  jvalue argvals[param_count];
+
+#define COPY(Where, What, Type) \
+  do { \
+    Type val = (What); \
+    memcpy ((Where), &val, sizeof (Type)); \
+  } while (0)
+
+  for (int i = 0; i < param_count; ++i)
+    {
+      jclass k = argelts[i] ? argelts[i]->getClass() : NULL;
+      if (paramelts[i]->isPrimitive())
+       {
+         if (! argelts[i]
+             || ! k
+             || ! can_widen (k, paramelts[i]))
+           JvThrow (new java::lang::IllegalArgumentException);
+       }
+      else
+       {
+         if (argelts[i] && ! paramelts[i]->isAssignableFrom (k))
+           JvThrow (new java::lang::IllegalArgumentException);
+       }
+
+      java::lang::Number *num = (java::lang::Number *) argelts[i];
+      if (paramelts[i] == JvPrimClass (byte))
+       COPY (&argvals[i], num->byteValue(), jbyte);
+      else if (paramelts[i] == JvPrimClass (short))
+       COPY (&argvals[i], num->shortValue(), jshort);
+      else if (paramelts[i] == JvPrimClass (int))
+       COPY (&argvals[i], num->intValue(), jint);
+      else if (paramelts[i] == JvPrimClass (long))
+       COPY (&argvals[i], num->longValue(), jlong);
+      else if (paramelts[i] == JvPrimClass (float))
+       COPY (&argvals[i], num->floatValue(), jfloat);
+      else if (paramelts[i] == JvPrimClass (double))
+       COPY (&argvals[i], num->doubleValue(), jdouble);
+      else if (paramelts[i] == JvPrimClass (boolean))
+       COPY (&argvals[i],
+             ((java::lang::Boolean *) argelts[i])->booleanValue(),
+             jboolean);
+      else if (paramelts[i] == JvPrimClass (char))
+       COPY (&argvals[i],
+             ((java::lang::Character *) argelts[i])->charValue(),
+             jchar);
+      else
+       {
+         JvAssert (! paramelts[i]->isPrimitive());
+         COPY (&argvals[i], argelts[i], jobject);
+       }
+    }
+
+  jvalue ret_value;
+  java::lang::Throwable *ex = _Jv_CallAnyMethodA (obj,
+                                                 return_type,
+                                                 meth,
+                                                 is_constructor,
+                                                 parameter_types,
+                                                 argvals,
+                                                 &ret_value);
+
+  if (ex)
+    JvThrow (ex);
 
   jobject r;
-#define VAL(Wrapper, Type)  (new Wrapper (* (Type *) &ret_value))
+#define VAL(Wrapper, Field)  (new Wrapper (ret_value.Field))
   if (is_constructor)
-    r = obj;
-  else if (return_type == JvPrimClass (byte))
-    r = VAL (java::lang::Byte, jbyte);
+    r = ret_value.l;
+  else  if (return_type == JvPrimClass (byte))
+    r = VAL (java::lang::Byte, b);
   else if (return_type == JvPrimClass (short))
-    r = VAL (java::lang::Short, jshort);
+    r = VAL (java::lang::Short, s);
   else if (return_type == JvPrimClass (int))
-    r = VAL (java::lang::Integer, jint);
+    r = VAL (java::lang::Integer, i);
   else if (return_type == JvPrimClass (long))
-    r = VAL (java::lang::Long, jlong);
+    r = VAL (java::lang::Long, j);
   else if (return_type == JvPrimClass (float))
-    r = VAL (java::lang::Float, jfloat);
+    r = VAL (java::lang::Float, f);
   else if (return_type == JvPrimClass (double))
-    r = VAL (java::lang::Double, jdouble);
+    r = VAL (java::lang::Double, d);
   else if (return_type == JvPrimClass (boolean))
-    r = VAL (java::lang::Boolean, jboolean);
+    r = VAL (java::lang::Boolean, z);
   else if (return_type == JvPrimClass (char))
-    r = VAL (java::lang::Character, jchar);
+    r = VAL (java::lang::Character, c);
   else if (return_type == JvPrimClass (void))
     r = NULL;
   else
     {
       JvAssert (return_type == NULL || ! return_type->isPrimitive());
-      r = * (Object **) &ret_value;
+      r = ret_value.l;
     }
 
   return r;
index 9a8df1e..cc0ba6b 100644 (file)
@@ -1,6 +1,6 @@
 // jni.cc - JNI implementation, including the jump table.
 
-/* Copyright (C) 1998, 1999  Red Hat, Inc.
+/* Copyright (C) 1998, 1999, 2000  Red Hat, Inc.
 
    This file is part of libgcj.
 
@@ -8,12 +8,78 @@ This software is copyrighted work licensed under the terms of the
 Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
 details.  */
 
+// Note: currently we take the approach of not checking most
+// arguments.  Instead we could do more checking conditionally (e.g.,
+// if DEBUG is defined).  That might be beneficial in some cases,
+// though to me it seems that one could just as easily use the
+// debugger.
+
 #include <config.h>
 
 #include <stddef.h>
 
+// Must define this before jni.h.
+#define GCJ_JV_JNIENV_FRIEND \
+    friend jthrowable &get_throwable (JNIEnv *)
+
+#include <gcj/cni.h>
+#include <jvm.h>
+#include <java-assert.h>
 #include <jni.h>
 #include <gcj/field.h>
+#include <java/lang/Throwable.h>
+#include <java/lang/ArrayIndexOutOfBoundsException.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/Modifier.h>
+
+#define ClassClass _CL_Q34java4lang5Class
+extern java::lang::Class ClassClass;
+#define ObjectClass _CL_Q34java4lang6Object
+extern java::lang::Class ObjectClass;
+
+// This enum is used to select different template instantiations in
+// the invocation code.
+enum invocation_type
+{
+  normal,
+  nonvirtual,
+  static_type,
+  constructor
+};
+
+\f
+
+// Tell the GC that a certain pointer is live.
+static void
+mark_for_gc (void *)
+{
+  // FIXME.
+}
+
+// Unmark a pointer.
+static void
+unmark_for_gc (void *)
+{
+  // FIXME.
+}
+
+// Return throwable in env.
+jthrowable &
+get_throwable (JNIEnv *env)
+{
+  return env->ex;
+}
+
+\f
+
+static jint
+_Jv_JNI_GetVersion (JNIEnv *)
+{
+  return JNI_VERSION_1_2;
+}
 
 static jclass
 _Jv_JNI_GetSuperclass (JNIEnv *, jclass clazz)
@@ -27,34 +93,556 @@ IsAssignableFrom(JNIEnv *, jclass clazz1, jclass clazz2)
   return clazz1->isAssignableFrom (clazz2);
 }
 
+static jint
+_Jv_JNI_Throw (JNIEnv *env, jthrowable obj)
+{
+  get_throwable (env) = obj;
+  return 0;
+}
+
+static jint
+_Jv_JNI_ThrowNew (JNIEnv *env, jclass clazz, const char *message)
+{
+  using namespace java::lang::reflect;
+
+  JArray<jclass> *argtypes
+    = (JArray<jclass> *) JvNewObjectArray (1, &ClassClass, NULL);
+
+  jclass *elts = elements (argtypes);
+  elts[0] = &StringClass;
+
+  // FIXME: exception processing.
+  Constructor *cons = clazz->getConstructor (argtypes);
+
+  jobjectArray values = JvNewObjectArray (1, &StringClass, NULL);
+  jobject *velts = elements (values);
+  velts[0] = JvNewStringUTF (message);
+
+  // FIXME: exception processing.
+  jobject obj = cons->newInstance (values);
+
+  get_throwable (env) = reinterpret_cast<jthrowable> (obj);
+  return 0;
+}
+
+static jthrowable
+_Jv_JNI_ExceptionOccurred (JNIEnv *env)
+{
+  return get_throwable (env);
+}
+
+static void
+_Jv_JNI_ExceptionDescribe (JNIEnv *env)
+{
+  if (get_throwable (env) != NULL)
+    get_throwable (env)->printStackTrace();
+}
+
+static void
+_Jv_JNI_ExceptionClear (JNIEnv *env)
+{
+  get_throwable (env) = NULL;
+}
+
+static void
+_Jv_JNI_FatalError (JNIEnv *, const char *message)
+{
+  JvFail (message);
+}
+
+static jboolean
+_Jv_JNI_IsSameObject (JNIEnv *, jobject obj1, jobject obj2)
+{
+  return obj1 == obj2;
+}
+
 static jobject
-_Jv_JNI_GetObjectField (JNIEnv *, jobject obj, jfieldID field) 
+_Jv_JNI_AllocObject (JNIEnv *env, jclass clazz)
 {
-  return _Jv_GetObjectField (obj, field);
+  jobject obj = NULL;
+  using namespace java::lang::reflect;
+  if (clazz->isInterface() || Modifier::isAbstract(clazz->getModifiers()))
+    get_throwable (env) = new java::lang::InstantiationException ();
+  else
+    {
+      // FIXME: exception processing.
+      // FIXME: will this work for String?
+      obj = JvAllocObject (clazz);
+    }
+
+  return obj;
 }
 
-static jbyte
-_Jv_JNI_GetByteField (JNIEnv *, jobject obj, jfieldID field) 
+static jclass
+_Jv_JNI_GetObjectClass (JNIEnv *, jobject obj)
 {
-  return _Jv_GetByteField (obj, field);
+  return obj->getClass();
 }
 
-static jshort
-_Jv_JNI_GetShortField (JNIEnv *, jobject obj, jfieldID field) 
+static jboolean
+_Jv_JNI_IsInstanceOf (JNIEnv *, jobject obj, jclass clazz)
 {
-  return _Jv_GetShortField (obj, field);
+  return clazz->isInstance(obj);
 }
 
-static jint
-_Jv_JNI_GetIntField (JNIEnv *, jobject obj, jfieldID field) 
+\f
+
+//
+// This section concerns method invocation.
+//
+
+template<jboolean is_static>
+static jmethodID
+_Jv_JNI_GetAnyMethodID (JNIEnv *env, jclass clazz,
+                       const char *name, const char *sig)
 {
-  return _Jv_GetIntField (obj, field);
+  // FIXME: exception processing.
+  _Jv_InitClass (clazz);
+
+  _Jv_Utf8Const *name_u = _Jv_makeUtf8Const ((char *) name, -1);
+  _Jv_Utf8Const *sig_u = _Jv_makeUtf8Const ((char *) sig, -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 ();
+    }
+
+  get_throwable (env) = new java::lang::NoSuchMethodError ();
+  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)
+    {
+      if (arg_elts[i] == JvPrimClass (byte))
+       values[i].b = va_arg (vargs, jbyte);
+      else if (arg_elts[i] == JvPrimClass (short))
+       values[i].s = va_arg (vargs, jshort);
+      else if (arg_elts[i] == JvPrimClass (int))
+       values[i].i = va_arg (vargs, jint);
+      else if (arg_elts[i] == JvPrimClass (long))
+       values[i].j = va_arg (vargs, jlong);
+      else if (arg_elts[i] == JvPrimClass (float))
+       values[i].f = va_arg (vargs, jfloat);
+      else if (arg_elts[i] == JvPrimClass (double))
+       values[i].d = va_arg (vargs, jdouble);
+      else if (arg_elts[i] == JvPrimClass (boolean))
+       values[i].z = va_arg (vargs, jboolean);
+      else if (arg_elts[i] == JvPrimClass (char))
+       values[i].c = va_arg (vargs, jchar);
+      else
+       {
+         // An object.
+         values[i].l = va_arg (vargs, jobject);
+       }
+    }
+}
+
+// This can call any sort of method: virtual, "nonvirtual", static, or
+// constructor.
+template<typename T, invocation_type style>
+static T
+_Jv_JNI_CallAnyMethodV (JNIEnv *env, jobject obj, jclass klass,
+                       jmethodID id, va_list vargs)
+{
+  if (style == normal)
+    id = _Jv_LookupDeclaredMethod (obj->getClass (), id->name, id->signature);
+
+  jclass decl_class = klass ? klass : obj->getClass ();
+  JvAssert (decl_class != NULL);
+
+  jclass return_type;
+  JArray<jclass> *arg_types;
+  // FIXME: exception processing.
+  _Jv_GetTypesFromSignature (id, decl_class,
+                            &arg_types, &return_type);
+
+  jvalue args[arg_types->length];
+  array_from_valist (args, arg_types, vargs);
+
+  jvalue result;
+  jthrowable ex = _Jv_CallAnyMethodA (obj, return_type, id,
+                                     style == constructor,
+                                     arg_types, args, &result);
+
+  if (ex != NULL)
+    get_throwable (env) = ex;
+
+  // We cheat a little here.  FIXME.
+  return * (T *) &result;
+}
+
+template<typename T, invocation_type style>
+static T
+_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
+_Jv_JNI_CallAnyMethodA (JNIEnv *env, jobject obj, jclass klass,
+                       jmethodID id, jvalue *args)
+{
+  if (style == normal)
+    id = _Jv_LookupDeclaredMethod (obj->getClass (), id->name, id->signature);
+
+  jclass decl_class = klass ? klass : obj->getClass ();
+  JvAssert (decl_class != NULL);
+
+  jclass return_type;
+  JArray<jclass> *arg_types;
+  // FIXME: exception processing.
+  _Jv_GetTypesFromSignature (id, decl_class,
+                            &arg_types, &return_type);
+
+  jvalue result;
+  jthrowable ex = _Jv_CallAnyMethodA (obj, return_type, id,
+                                     style == constructor,
+                                     arg_types, args, &result);
+
+  if (ex != NULL)
+    get_throwable (env) = ex;
+
+  // We cheat a little here.  FIXME.
+  return * (T *) &result;
+}
+
+template<invocation_type style>
+static void
+_Jv_JNI_CallAnyVoidMethodV (JNIEnv *env, jobject obj, jclass klass,
+                           jmethodID id, va_list vargs)
+{
+  if (style == normal)
+    id = _Jv_LookupDeclaredMethod (obj->getClass (), id->name, id->signature);
+
+  jclass decl_class = klass ? klass : obj->getClass ();
+  JvAssert (decl_class != NULL);
+
+  jclass return_type;
+  JArray<jclass> *arg_types;
+  // FIXME: exception processing.
+  _Jv_GetTypesFromSignature (id, decl_class,
+                            &arg_types, &return_type);
+
+  jvalue args[arg_types->length];
+  array_from_valist (args, arg_types, vargs);
+
+  jthrowable ex = _Jv_CallAnyMethodA (obj, return_type, id,
+                                     style == constructor,
+                                     arg_types, args, NULL);
+
+  if (ex != NULL)
+    get_throwable (env) = ex;
+}
+
+template<invocation_type style>
+static void
+_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
+_Jv_JNI_CallAnyVoidMethodA (JNIEnv *env, jobject obj, jclass klass,
+                           jmethodID id, jvalue *args)
+{
+  if (style == normal)
+    id = _Jv_LookupDeclaredMethod (obj->getClass (), id->name, id->signature);
+
+  jclass decl_class = klass ? klass : obj->getClass ();
+  JvAssert (decl_class != NULL);
+
+  jclass return_type;
+  JArray<jclass> *arg_types;
+  // FIXME: exception processing.
+  _Jv_GetTypesFromSignature (id, decl_class,
+                            &arg_types, &return_type);
+
+  jthrowable ex = _Jv_CallAnyMethodA (obj, return_type, id,
+                                     style == constructor,
+                                     arg_types, args, NULL);
+
+  if (ex != NULL)
+    get_throwable (env) = ex;
+}
+
+// Functions with this signature are used to implement functions in
+// the CallMethod family.
+template<typename T>
+static T
+_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
+_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
+_Jv_JNI_CallMethodA (JNIEnv *env, jobject obj, jmethodID id, jvalue *args)
+{
+  return _Jv_JNI_CallAnyMethodA<T, normal> (env, obj, NULL, id, args);
+}
+
+static void
+_Jv_JNI_CallVoidMethodV (JNIEnv *env, jobject obj, jmethodID id, va_list args)
+{
+  _Jv_JNI_CallAnyVoidMethodV<normal> (env, obj, NULL, id, args);
+}
+
+static void
+_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 jlong
-_Jv_JNI_GetLongField (JNIEnv *, jobject obj, jfieldID field) 
+static void
+_Jv_JNI_CallVoidMethodA (JNIEnv *env, jobject obj, jmethodID id, jvalue *args)
 {
-  return _Jv_GetLongField (obj, field);
+  _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
+_Jv_JNI_CallStaticMethodV (JNIEnv *env, jclass klass,
+                          jmethodID id, va_list args)
+{
+  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
+_Jv_JNI_CallStaticMethod (JNIEnv *env, jclass klass, jmethodID id, ...)
+{
+  va_list args;
+  T result;
+
+  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
+_Jv_JNI_CallStaticMethodA (JNIEnv *env, jclass klass, jmethodID id,
+                          jvalue *args)
+{
+  return _Jv_JNI_CallAnyMethodA<T, static_type> (env, NULL, klass, id, args);
+}
+
+static void
+_Jv_JNI_CallStaticVoidMethodV (JNIEnv *env, jclass klass, jmethodID id,
+                              va_list args)
+{
+  _Jv_JNI_CallAnyVoidMethodV<static_type> (env, NULL, klass, id, args);
+}
+
+static void
+_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
+_Jv_JNI_CallStaticVoidMethodA (JNIEnv *env, jclass klass, jmethodID id,
+                              jvalue *args)
+{
+  _Jv_JNI_CallAnyVoidMethodA<static_type> (env, NULL, klass, id, args);
+}
+
+static jobject
+_Jv_JNI_NewObjectV (JNIEnv *env, jclass klass,
+                   jmethodID id, va_list args)
+{
+  return _Jv_JNI_CallAnyMethodV<jobject, constructor> (env, NULL, klass,
+                                                      id, args);
+}
+
+static jobject
+_Jv_JNI_NewObject (JNIEnv *env, jclass klass, jmethodID id, ...)
+{
+  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
+_Jv_JNI_NewObjectA (JNIEnv *env, jclass klass, jmethodID id,
+                   jvalue *args)
+{
+  return _Jv_JNI_CallAnyMethodA<jobject, constructor> (env, NULL, klass,
+                                                      id, args);
+}
+
+\f
+
+template<typename T>
+static T
+_Jv_JNI_GetField (JNIEnv *, jobject obj, jfieldID field) 
+{
+  T *ptr = (T *) ((char *) obj + field->getOffset ());
+  return *ptr;
+}
+
+template<typename T>
+static void
+_Jv_JNI_SetField (JNIEnv *, jobject obj, jfieldID field, T value)
+{
+  T *ptr = (T *) ((char *) obj + field->getOffset ());
+  *ptr = value;
+}
+
+template<jboolean is_static>
+static jfieldID
+_Jv_JNI_GetAnyFieldID (JNIEnv *env, jclass clazz,
+                      const char *name, const char *sig)
+{
+  // FIXME: exception processing.
+  _Jv_InitClass (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: what if field_class == NULL?
+
+  while (clazz != NULL)
+    {
+      jint count = (is_static
+                   ? JvNumStaticFields (clazz)
+                   : JvNumInstanceFields (clazz));
+      jfieldID field = (is_static
+                       ? JvGetFirstStaticField (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);
+
+         if (_Jv_equalUtf8Consts (f_name, a_name)
+             && field->getClass() == field_class)
+           return field;
+
+         field = field->getNextField ();
+       }
+
+      clazz = clazz->getSuperclass ();
+    }
+
+  get_throwable (env) = new java::lang::NoSuchFieldError ();
+  return NULL;
+}
+
+template<typename T>
+static T
+_Jv_JNI_GetStaticField (JNIEnv *, jclass, jfieldID field)
+{
+  T *ptr = (T *) field->u.addr;
+  return *ptr;
+}
+
+template<typename T>
+static void
+_Jv_JNI_SetStaticField (JNIEnv *, jclass, jfieldID field, T value)
+{
+  T *ptr = (T *) field->u.addr;
+  *ptr = value;
+}
+
+static jstring
+_Jv_JNI_NewString (JNIEnv *, const jchar *unichars, jsize len)
+{
+  // FIXME: exception processing.
+  jstring r = _Jv_NewString (unichars, len);
+  return r;
 }
 
 static jsize
@@ -63,6 +651,173 @@ _Jv_JNI_GetStringLength (JNIEnv *, jstring string)
   return string->length();
 }
 
+static const jchar *
+_Jv_JNI_GetStringChars (JNIEnv *, jstring string, jboolean *isCopy)
+{
+  jchar *result = _Jv_GetStringChars (string);
+  mark_for_gc (result);
+  if (isCopy)
+    *isCopy = false;
+  return (const jchar *) result;
+}
+
+static void
+_Jv_JNI_ReleaseStringChars (JNIEnv *, jstring, const jchar *chars)
+{
+  unmark_for_gc ((void *) chars);
+}
+
+static jstring
+_Jv_JNI_NewStringUTF (JNIEnv *, const char *bytes)
+{
+  // FIXME: exception processing.
+  jstring r = JvNewStringUTF (bytes);
+  return r;
+}
+
+static jsize
+_Jv_JNI_GetStringUTFLength (JNIEnv *, jstring string)
+{
+  return JvGetStringUTFLength (string);
+}
+
+static const char *
+_Jv_JNI_GetStringUTFChars (JNIEnv *, jstring string, jboolean *isCopy)
+{
+  jsize len = JvGetStringUTFLength (string);
+  // FIXME: exception processing.
+  char *r = (char *) _Jv_Malloc (len + 1);
+  JvGetStringUTFRegion (string, 0, len, r);
+  r[len] = '\0';
+
+  if (isCopy)
+    *isCopy = true;
+
+  return (const char *) r;
+}
+
+static void
+_Jv_JNI_ReleaseStringUTFChars (JNIEnv *, jstring, const char *utf)
+{
+  _Jv_Free ((void *) utf);
+}
+
+static jsize
+_Jv_JNI_GetArrayLength (JNIEnv *, jarray array)
+{
+  return array->length;
+}
+
+static jarray
+_Jv_JNI_NewObjectArray (JNIEnv *, jsize length, jclass elementClass,
+                       jobject init)
+{
+  // FIXME: exception processing.
+  jarray result = JvNewObjectArray (length, elementClass, init);
+  return result;
+}
+
+static jobject
+_Jv_JNI_GetObjectArrayElement (JNIEnv *, jobjectArray array, jsize index)
+{
+  jobject *elts = elements (array);
+  return elts[index];
+}
+
+static void
+_Jv_JNI_SetObjectArrayElement (JNIEnv *, jobjectArray array, jsize index,
+                              jobject value)
+{
+  // FIXME: exception processing.
+  _Jv_CheckArrayStore (array, value);
+  jobject *elts = elements (array);
+  elts[index] = value;
+}
+
+template<typename T, jclass K>
+static JArray<T> *
+_Jv_JNI_NewPrimitiveArray (JNIEnv *, jsize length)
+{
+  return (JArray<T> *) _Jv_NewPrimArray (K, length);
+}
+
+template<typename T>
+static T *
+_Jv_JNI_GetPrimitiveArrayElements (JNIEnv *, JArray<T> *array,
+                                  jboolean *isCopy)
+{
+  T *elts = elements (array);
+  if (isCopy)
+    {
+      // We elect never to copy.
+      *isCopy = false;
+    }
+  mark_for_gc (elts);
+  return elts;
+}
+
+template<typename T>
+static void
+_Jv_JNI_ReleasePrimitiveArrayElements (JNIEnv *, JArray<T> *,
+                                      T *elems, jint /* mode */)
+{
+  // 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 (elems);
+}
+
+template<typename T>
+static void
+_Jv_JNI_GetPrimitiveArrayRegion (JNIEnv *env, JArray<T> *array,
+                                jsize start, jsize len,
+                                T *buf)
+{
+  if (start < 0 || len >= array->length || start + len >= array->length)
+    {
+      // FIXME: index.
+      get_throwable (env) = new java::lang::ArrayIndexOutOfBoundsException ();
+    }
+  else
+    {
+      T *elts = elements (array) + start;
+      memcpy (buf, elts, len * sizeof (T));
+    }
+}
+
+template<typename T>
+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)
+    {
+      // FIXME: index.
+      get_throwable (env) = new java::lang::ArrayIndexOutOfBoundsException ();
+    }
+  else
+    {
+      T *elts = elements (array) + start;
+      memcpy (elts, buf, len * sizeof (T));
+    }
+}
+
+static jint
+_Jv_JNI_MonitorEnter (JNIEnv *, jobject obj)
+{
+  // FIXME: exception processing.
+  jint r = _Jv_MonitorEnter (obj);
+  return r;
+}
+
+static jint
+_Jv_JNI_MonitorExit (JNIEnv *, jobject obj)
+{
+  // FIXME: exception processing.
+  jint r = _Jv_MonitorExit (obj);
+  return r;
+}
+
 // JDK 1.2
 jobject
 _Jv_JNI_ToReflectedField (JNIEnv *, jclass cls, jfieldID fieldID)
@@ -82,227 +837,234 @@ _Jv_JNI_FromReflectedField (JNIEnv *, java::lang::reflect::Field *field)
 }
 
 #define NOT_IMPL NULL
+#define RESERVED NULL
 
 struct JNINativeInterface _Jv_JNIFunctions =
 {
-  NULL,
-  NULL,
-  NULL,
-  NULL,
-  NOT_IMPL /* GetVersion */,
+  RESERVED,
+  RESERVED,
+  RESERVED,
+  RESERVED,
+  _Jv_JNI_GetVersion,
   NOT_IMPL /* DefineClass */,
   NOT_IMPL /* FindClass */,
-  NULL,
-  NULL,
-  NULL,
+  RESERVED,
+  RESERVED,
+  RESERVED,
   _Jv_JNI_GetSuperclass,
   IsAssignableFrom,
-  NULL,
-  NOT_IMPL /* Throw */,
-  NOT_IMPL /* ThrowNew */,
-  NOT_IMPL /* ExceptionOccurred */,
-  NOT_IMPL /* ExceptionDescribe */,
-  NOT_IMPL /* ExceptionClear */,
-  NOT_IMPL /* FatalError */,
-  NOT_IMPL /* NULL */,
-  NOT_IMPL /* NULL */,
+  RESERVED,
+  _Jv_JNI_Throw,
+  _Jv_JNI_ThrowNew,
+  _Jv_JNI_ExceptionOccurred,
+  _Jv_JNI_ExceptionDescribe,
+  _Jv_JNI_ExceptionClear,
+  _Jv_JNI_FatalError,
+  RESERVED,
+  RESERVED,
   NOT_IMPL /* NewGlobalRef */,
   NOT_IMPL /* DeleteGlobalRef */,
   NOT_IMPL /* DeleteLocalRef */,
-  NOT_IMPL /* IsSameObject */,
-  NOT_IMPL /* NULL */,
-  NOT_IMPL /* NULL */,
-  NOT_IMPL /* AllocObject */,
-  NOT_IMPL /* NewObject */,
-  NOT_IMPL /* NewObjectV */,
-  NOT_IMPL /* NewObjectA */,
-  NOT_IMPL /* GetObjectClass */,
-  NOT_IMPL /* IsInstanceOf */,
-  NOT_IMPL /* GetMethodID */,
-  NOT_IMPL /* CallObjectMethod */,
-  NOT_IMPL /* CallObjectMethodV */,
-  NOT_IMPL /* CallObjectMethodA */,
-  NOT_IMPL /* CallBooleanMethod */,
-  NOT_IMPL /* CallBooleanMethodV */,
-  NOT_IMPL /* CallBooleanMethodA */,
-  NOT_IMPL /* CallByteMethod */,
-  NOT_IMPL /* CallByteMethodV */,
-  NOT_IMPL /* CallByteMethodA */,
-  NOT_IMPL /* CallCharMethod */,
-  NOT_IMPL /* CallCharMethodV */,
-  NOT_IMPL /* CallCharMethodA */,
-  NOT_IMPL /* CallShortMethod */,
-  NOT_IMPL /* CallShortMethodV */,
-  NOT_IMPL /* CallShortMethodA */,
-  NOT_IMPL /* CallIntMethod */,
-  NOT_IMPL /* CallIntMethodV */,
-  NOT_IMPL /* CallIntMethodA */,
-  NOT_IMPL /* CallLongMethod */,
-  NOT_IMPL /* CallLongMethodV */,
-  NOT_IMPL /* CallLongMethodA */,
-  NOT_IMPL /* CallFloatMethod */,
-  NOT_IMPL /* CallFloatMethodV */,
-  NOT_IMPL /* CallFloatMethodA */,
-  NOT_IMPL /* CallDoubleMethod */,
-  NOT_IMPL /* CallDoubleMethodV */,
-  NOT_IMPL /* CallDoubleMethodA */,
-  NOT_IMPL /* CallVoidMethod */,
-  NOT_IMPL /* CallVoidMethodV */,
-  NOT_IMPL /* CallVoidMethodA */,
-  NOT_IMPL /* CallNonvirtualObjectMethod */,
-  NOT_IMPL /* CallNonvirtualObjectMethodV */,
-  NOT_IMPL /* CallNonvirtualObjectMethodA */,
-  NOT_IMPL /* CallNonvirtualBooleanMethod */,
-  NOT_IMPL /* CallNonvirtualBooleanMethodV */,
-  NOT_IMPL /* CallNonvirtualBooleanMethodA */,
-  NOT_IMPL /* CallNonvirtualByteMethod */,
-  NOT_IMPL /* CallNonvirtualByteMethodV */,
-  NOT_IMPL /* CallNonvirtualByteMethodA */,
-  NOT_IMPL /* CallNonvirtualCharMethod */,
-  NOT_IMPL /* CallNonvirtualCharMethodV */,
-  NOT_IMPL /* CallNonvirtualCharMethodA */,
-  NOT_IMPL /* CallNonvirtualShortMethod */,
-  NOT_IMPL /* CallNonvirtualShortMethodV */,
-  NOT_IMPL /* CallNonvirtualShortMethodA */,
-  NOT_IMPL /* CallNonvirtualIntMethod */,
-  NOT_IMPL /* CallNonvirtualIntMethodV */,
-  NOT_IMPL /* CallNonvirtualIntMethodA */,
-  NOT_IMPL /* CallNonvirtualLongMethod */,
-  NOT_IMPL /* CallNonvirtualLongMethodV */,
-  NOT_IMPL /* CallNonvirtualLongMethodA */,
-  NOT_IMPL /* CallNonvirtualFloatMethod */,
-  NOT_IMPL /* CallNonvirtualFloatMethodV */,
-  NOT_IMPL /* CallNonvirtualFloatMethodA */,
-  NOT_IMPL /* CallNonvirtualDoubleMethod */,
-  NOT_IMPL /* CallNonvirtualDoubleMethodV */,
-  NOT_IMPL /* CallNonvirtualDoubleMethodA */,
-  NOT_IMPL /* CallNonvirtualVoidMethod */,
-  NOT_IMPL /* CallNonvirtualVoidMethodV */,
-  NOT_IMPL /* CallNonvirtualVoidMethodA */,
-  NOT_IMPL /* GetFieldID */,
-  _Jv_JNI_GetObjectField,
-  NOT_IMPL /* GetBooleanField */,
-  _Jv_JNI_GetByteField,
-  NOT_IMPL /* GetCharField */,
-  _Jv_JNI_GetShortField,
-  _Jv_JNI_GetIntField,
-  _Jv_JNI_GetLongField,
-  NOT_IMPL /* GetFloatField */,
-  NOT_IMPL /* GetDoubleField */,
-  NOT_IMPL /* SetObjectField */,
-  NOT_IMPL /* SetBooleanField */,
-  NOT_IMPL /* SetByteField */,
-  NOT_IMPL /* SetCharField */,
-  NOT_IMPL /* SetShortField */,
-  NOT_IMPL /* SetIntField */,
-  NOT_IMPL /* SetLongField */,
-  NOT_IMPL /* SetFloatField */,
-  NOT_IMPL /* SetDoubleField */,
-  NOT_IMPL /* GetStaticMethodID */,
-  NOT_IMPL /* CallStaticObjectMethod */,
-  NOT_IMPL /* CallStaticObjectMethodV */,
-  NOT_IMPL /* CallStaticObjectMethodA */,
-  NOT_IMPL /* CallStaticBooleanMethod */,
-  NOT_IMPL /* CallStaticBooleanMethodV */,
-  NOT_IMPL /* CallStaticBooleanMethodA */,
-  NOT_IMPL /* CallStaticByteMethod */,
-  NOT_IMPL /* CallStaticByteMethodV */,
-  NOT_IMPL /* CallStaticByteMethodA */,
-  NOT_IMPL /* CallStaticCharMethod */,
-  NOT_IMPL /* CallStaticCharMethodV */,
-  NOT_IMPL /* CallStaticCharMethodA */,
-  NOT_IMPL /* CallStaticShortMethod */,
-  NOT_IMPL /* CallStaticShortMethodV */,
-  NOT_IMPL /* CallStaticShortMethodA */,
-  NOT_IMPL /* CallStaticIntMethod */,
-  NOT_IMPL /* CallStaticIntMethodV */,
-  NOT_IMPL /* CallStaticIntMethodA */,
-  NOT_IMPL /* CallStaticLongMethod */,
-  NOT_IMPL /* CallStaticLongMethodV */,
-  NOT_IMPL /* CallStaticLongMethodA */,
-  NOT_IMPL /* CallStaticFloatMethod */,
-  NOT_IMPL /* CallStaticFloatMethodV */,
-  NOT_IMPL /* CallStaticFloatMethodA */,
-  NOT_IMPL /* CallStaticDoubleMethod */,
-  NOT_IMPL /* CallStaticDoubleMethodV */,
-  NOT_IMPL /* CallStaticDoubleMethodA */,
-  NOT_IMPL /* CallStaticVoidMethod */,
-  NOT_IMPL /* CallStaticVoidMethodV */,
-  NOT_IMPL /* CallStaticVoidMethodA */,
-  NOT_IMPL /* GetStaticFieldID */,
-  NOT_IMPL /* GetStaticObjectField */,
-  NOT_IMPL /* GetStaticBooleanField */,
-  NOT_IMPL /* GetStaticByteField */,
-  NOT_IMPL /* GetStaticCharField */,
-  NOT_IMPL /* GetStaticShortField */,
-  NOT_IMPL /* GetStaticIntField */,
-  NOT_IMPL /* GetStaticLongField */,
-  NOT_IMPL /* GetStaticFloatField */,
-  NOT_IMPL /* GetStaticDoubleField */,
-  NOT_IMPL /* SetStaticObjectField */,
-  NOT_IMPL /* SetStaticBooleanField */,
-  NOT_IMPL /* SetStaticByteField */,
-  NOT_IMPL /* SetStaticCharField */,
-  NOT_IMPL /* SetStaticShortField */,
-  NOT_IMPL /* SetStaticIntField */,
-  NOT_IMPL /* SetStaticLongField */,
-  NOT_IMPL /* SetStaticFloatField */,
-  NOT_IMPL /* SetStaticDoubleField */,
-  NOT_IMPL /* NewString */,
+  _Jv_JNI_IsSameObject,
+  RESERVED,
+  RESERVED,
+  _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,
+
+  // 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,
-  NOT_IMPL /* GetStringChars */,
-  NOT_IMPL /* ReleaseStringChars */,
-  NOT_IMPL /* NewStringUTF */,
-  NOT_IMPL /* GetStringUTFLength */,
-  NOT_IMPL /* GetStringUTFChars */,
-  NOT_IMPL /* ReleaseStringUTFChars */,
-  NOT_IMPL /* GetArrayLength */,
-  NOT_IMPL /* NewObjectArray */,
-  NOT_IMPL /* GetObjectArrayElement */,
-  NOT_IMPL /* SetObjectArrayElement */,
-  NOT_IMPL /* NewBooleanArray */,
-  NOT_IMPL /* NewByteArray */,
-  NOT_IMPL /* NewCharArray */,
-  NOT_IMPL /* NewShortArray */,
-  NOT_IMPL /* NewIntArray */,
-  NOT_IMPL /* NewLongArray */,
-  NOT_IMPL /* NewFloatArray */,
-  NOT_IMPL /* NewDoubleArray */,
-  NOT_IMPL /* GetBooleanArrayElements */,
-  NOT_IMPL /* GetByteArrayElements */,
-  NOT_IMPL /* GetCharArrayElements */,
-  NOT_IMPL /* GetShortArrayElements */,
-  NOT_IMPL /* GetIntArrayElements */,
-  NOT_IMPL /* GetLongArrayElements */,
-  NOT_IMPL /* GetFloatArrayElements */,
-  NOT_IMPL /* GetDoubleArrayElements */,
-  NOT_IMPL /* ReleaseBooleanArrayElements */,
-  NOT_IMPL /* ReleaseByteArrayElements */,
-  NOT_IMPL /* ReleaseCharArrayElements */,
-  NOT_IMPL /* ReleaseShortArrayElements */,
-  NOT_IMPL /* ReleaseIntArrayElements */,
-  NOT_IMPL /* ReleaseLongArrayElements */,
-  NOT_IMPL /* ReleaseFloatArrayElements */,
-  NOT_IMPL /* ReleaseDoubleArrayElements */,
-  NOT_IMPL /* GetBooleanArrayRegion */,
-  NOT_IMPL /* GetByteArrayRegion */,
-  NOT_IMPL /* GetCharArrayRegion */,
-  NOT_IMPL /* GetShortArrayRegion */,
-  NOT_IMPL /* GetIntArrayRegion */,
-  NOT_IMPL /* GetLongArrayRegion */,
-  NOT_IMPL /* GetFloatArrayRegion */,
-  NOT_IMPL /* GetDoubleArrayRegion */,
-  NOT_IMPL /* SetBooleanArrayRegion */,
-  NOT_IMPL /* SetByteArrayRegion */,
-  NOT_IMPL /* SetCharArrayRegion */,
-  NOT_IMPL /* SetShortArrayRegion */,
-  NOT_IMPL /* SetIntArrayRegion */,
-  NOT_IMPL /* SetLongArrayRegion */,
-  NOT_IMPL /* SetFloatArrayRegion */,
-  NOT_IMPL /* SetDoubleArrayRegion */,
+  _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_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,
   NOT_IMPL /* RegisterNatives */,
   NOT_IMPL /* UnregisterNatives */,
-  NOT_IMPL /* MonitorEnter */,
-  NOT_IMPL /* MonitorExit */,
+  _Jv_JNI_MonitorEnter,
+  _Jv_JNI_MonitorExit,
   NOT_IMPL /* GetJavaVM */,
 };