OSDN Git Service

* gcj/method.h (JvNumMethods): Moved from Class.h.
authortromey <tromey@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 26 Jan 2000 23:56:36 +0000 (23:56 +0000)
committertromey <tromey@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 26 Jan 2000 23:56:36 +0000 (23:56 +0000)
(JvGetFirstMethod): Likewise.
* java/lang/Class.h (Object): Updated decl of
_Jv_JNI_ToReflectedField.
(Object): Added _Jv_JNI_ToReflectedMethod as a friend.
* Makefile.in: Rebuilt.
* Makefile.am (java/lang/reflect/Field.h): Added `jboolean'
argument of _Jv_JNI_ToReflectedField.
(java/lang/reflect/Constructor.h): Added _Jv_JNI_ToReflectedMethod
as a friend.
(java/lang/reflect/Method.h): Likewise.
* include/jni.h (class _Jv_JNIEnv): Added `klass' member.  Use
__GCJ_JNI_IMPL__.
(jweak): New typedef.
(struct JNINativeInterface): Correctly declare remaining entries.
* jni.cc: Include Class.h, ClassLoader.h.
(_Jv_JNI_FindClass): New function.
(_Jv_JNI_DefineClass): New function.
(_Jv_JNI_conversion_call): New function.
(_Jv_JNI_FindClass): Use current class loader to find class.
(_Jv_JNI_ExceptionCheck): New function.
(_Jv_JNI_FromReflectedField): Now static.
(MethodClass): New define.
(_Jv_JNI_FromReflectedMethod): New function.
(_Jv_JNI_ToReflectedMethod): Likewise.
Include Method.h.
(_Jv_JNI_IsAssignableFrom): Renamed.
(_Jv_JNI_GetStringRegion): New function.
Include StringIndexOutOfBoundsException.h.
(_Jv_JNI_GetStringUTFRegion): New function.
(_Jv_JNIFunctions): Updated for new functions.
(_Jv_JNI_GetPrimitiveArrayCritical): New function
(_Jv_JNI_ReleasePrimitiveArrayCritical): Likewise.
(_Jv_JNI_GetStringCritical): New function.
(_Jv_JNI_ReleaseStringCritical): Likewise.
(get_throwable): Removed.
(GCJ_JV_JNIENV_FRIEND): Removed.
(__GCJ_JNI_IMPL__): Define.
Include method.h.

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

libjava/ChangeLog
libjava/Makefile.am
libjava/Makefile.in
libjava/gcj/method.h
libjava/include/jni.h
libjava/java/lang/Class.h
libjava/jni.cc

index e3f2139..bfd61f0 100644 (file)
@@ -1,5 +1,45 @@
 2000-01-26  Tom Tromey  <tromey@cygnus.com>
 
+       * gcj/method.h (JvNumMethods): Moved from Class.h.
+       (JvGetFirstMethod): Likewise.
+       * java/lang/Class.h (Object): Updated decl of
+       _Jv_JNI_ToReflectedField.
+       (Object): Added _Jv_JNI_ToReflectedMethod as a friend.
+       * Makefile.in: Rebuilt.
+       * Makefile.am (java/lang/reflect/Field.h): Added `jboolean'
+       argument of _Jv_JNI_ToReflectedField.
+       (java/lang/reflect/Constructor.h): Added _Jv_JNI_ToReflectedMethod
+       as a friend.
+       (java/lang/reflect/Method.h): Likewise.
+       * include/jni.h (class _Jv_JNIEnv): Added `klass' member.  Use
+       __GCJ_JNI_IMPL__.
+       (jweak): New typedef.
+       (struct JNINativeInterface): Correctly declare remaining entries.
+       * jni.cc: Include Class.h, ClassLoader.h.
+       (_Jv_JNI_FindClass): New function.
+       (_Jv_JNI_DefineClass): New function.
+       (_Jv_JNI_conversion_call): New function.
+       (_Jv_JNI_FindClass): Use current class loader to find class.
+       (_Jv_JNI_ExceptionCheck): New function.
+       (_Jv_JNI_FromReflectedField): Now static.
+       (MethodClass): New define.
+       (_Jv_JNI_FromReflectedMethod): New function.
+       (_Jv_JNI_ToReflectedMethod): Likewise.
+       Include Method.h.
+       (_Jv_JNI_IsAssignableFrom): Renamed.
+       (_Jv_JNI_GetStringRegion): New function.
+       Include StringIndexOutOfBoundsException.h.
+       (_Jv_JNI_GetStringUTFRegion): New function.
+       (_Jv_JNIFunctions): Updated for new functions.
+       (_Jv_JNI_GetPrimitiveArrayCritical): New function
+       (_Jv_JNI_ReleasePrimitiveArrayCritical): Likewise.
+       (_Jv_JNI_GetStringCritical): New function.
+       (_Jv_JNI_ReleaseStringCritical): Likewise.
+       (get_throwable): Removed.
+       (GCJ_JV_JNIENV_FRIEND): Removed.
+       (__GCJ_JNI_IMPL__): Define.
+       Include method.h.
+
        * resolve.cc (get_ffi_type_from_signature): Handle case where
        boolean is an int.
 
index 91d851e..a8765a2 100644 (file)
@@ -235,12 +235,13 @@ java/lang/reflect/Constructor.h: java/lang/reflect/Constructor.class libgcj.zip
        $(GCJH) -classpath $(top_builddir) \
            -friend 'jmethodID _Jv_FromReflectedConstructor (java::lang::reflect::Constructor *);' \
            -friend 'java::lang::Class;' \
+           -friend 'jobject _Jv_JNI_ToReflectedMethod (_Jv_JNIEnv *, jclass, jmethodID, jboolean);' \
            $(basename $<)
 
 java/lang/reflect/Field.h: java/lang/reflect/Field.class libgcj.zip
        $(GCJH) -classpath $(top_builddir) \
            -friend 'jfieldID _Jv_FromReflectedField (java::lang::reflect::Field *);' \
-           -friend 'jobject _Jv_JNI_ToReflectedField (_Jv_JNIEnv*, jclass, jfieldID);' \
+           -friend 'jobject _Jv_JNI_ToReflectedField (_Jv_JNIEnv*, jclass, jfieldID, jboolean);' \
            -friend 'java::lang::Class;' \
            $(basename $<)
 
@@ -248,6 +249,7 @@ java/lang/reflect/Method.h: java/lang/reflect/Method.class libgcj.zip
        $(GCJH) -classpath $(top_builddir) \
            -friend 'jmethodID _Jv_FromReflectedMethod (java::lang::reflect::Method *);' \
            -friend 'java::lang::Class;' \
+           -friend 'jobject _Jv_JNI_ToReflectedMethod (_Jv_JNIEnv *, jclass, jmethodID, jboolean);' \
            $(basename $<)
 
 gnu/gcj/runtime/VMClassLoader.h: gnu/gcj/runtime/VMClassLoader.class libgcj.zip
index 0ba42bd..f6818b3 100644 (file)
@@ -1553,12 +1553,13 @@ java/lang/reflect/Constructor.h: java/lang/reflect/Constructor.class libgcj.zip
        $(GCJH) -classpath $(top_builddir) \
            -friend 'jmethodID _Jv_FromReflectedConstructor (java::lang::reflect::Constructor *);' \
            -friend 'java::lang::Class;' \
+           -friend 'jobject _Jv_JNI_ToReflectedMethod (_Jv_JNIEnv *, jclass, jmethodID, jboolean);' \
            $(basename $<)
 
 java/lang/reflect/Field.h: java/lang/reflect/Field.class libgcj.zip
        $(GCJH) -classpath $(top_builddir) \
            -friend 'jfieldID _Jv_FromReflectedField (java::lang::reflect::Field *);' \
-           -friend 'jobject _Jv_JNI_ToReflectedField (_Jv_JNIEnv*, jclass, jfieldID);' \
+           -friend 'jobject _Jv_JNI_ToReflectedField (_Jv_JNIEnv*, jclass, jfieldID, jboolean);' \
            -friend 'java::lang::Class;' \
            $(basename $<)
 
@@ -1566,6 +1567,7 @@ java/lang/reflect/Method.h: java/lang/reflect/Method.class libgcj.zip
        $(GCJH) -classpath $(top_builddir) \
            -friend 'jmethodID _Jv_FromReflectedMethod (java::lang::reflect::Method *);' \
            -friend 'java::lang::Class;' \
+           -friend 'jobject _Jv_JNI_ToReflectedMethod (_Jv_JNIEnv *, jclass, jmethodID, jboolean);' \
            $(basename $<)
 
 gnu/gcj/runtime/VMClassLoader.h: gnu/gcj/runtime/VMClassLoader.class libgcj.zip
index fe8f03b..fa3484d 100644 (file)
@@ -27,4 +27,16 @@ _Jv_FromReflectedConstructor (java::lang::reflect::Constructor *constructor)
     ((char *) constructor->declaringClass->methods + constructor->offset);
 }
 
+extern inline jint
+JvNumMethods (jclass klass)
+{
+  return klass->method_count;
+}
+
+extern inline jmethodID
+JvGetFirstMethod (jclass klass)
+{
+  return &klass->methods[0];
+}
+
 #endif /* __GCJ_METHOD_H__ */
index c2ba2f2..60b2302 100644 (file)
@@ -65,6 +65,9 @@ typedef const struct JNINativeInterface *JNIEnv;
 
 #endif /* __cplusplus */
 
+/* FIXME: this is wrong.  */
+typedef jobject jweak;
+
 /* Version numbers.  */
 #define JNI_VERSION_1_1 0x00010001
 #define JNI_VERSION_1_2 0x00010002
@@ -88,35 +91,57 @@ typedef union jvalue
 
 typedef void * (*_Jv_func)(...);
 
+/* This structure is used when registering native methods.  */
+typedef struct
+{
+  char *name;
+  char *signature;
+  void *fnPtr;                 /* Sigh.  */
+} JNINativeMethod;
+
+/* FIXME: this is just a placeholder.  */
+typedef int JavaVM;
+
 struct JNINativeInterface
 {
   _Jv_func reserved0;
   _Jv_func reserved1;
   _Jv_func reserved2;
   _Jv_func reserved3;
-  jint     (*GetVersion)                   (JNIEnv*);
-  _Jv_func DefineClass;
-  _Jv_func FindClass;
-  _Jv_func reserved4;
-  _Jv_func reserved5;
-  _Jv_func reserved6;
-  jclass   (*GetSuperclass)                (JNIEnv*, jclass);
-  jboolean (*IsAssignableFrom)             (JNIEnv*, jclass, jclass);
-  _Jv_func reserved7;
-  jint     (*Throw)                        (JNIEnv*, jthrowable);
-  jint     (*ThrowNew)                     (JNIEnv*, jclass, const char *);
+
+  jint     (*GetVersion)                   (JNIEnv *);
+  jclass   (*DefineClass)                  (JNIEnv *, jobject,
+                                           const jbyte *, jsize);
+  jclass   (*FindClass)                    (JNIEnv *, const char *);
+
+  jmethodID (*FromReflectedMethod)        (JNIEnv *, jobject);
+  jfieldID  (*FromReflectedField)         (JNIEnv *, jobject);
+  jobject   (*ToReflectedMethod)          (JNIEnv *, jclass, jmethodID,
+                                           jboolean);
+
+  jclass   (*GetSuperclass)                (JNIEnv *, jclass);
+  jboolean (*IsAssignableFrom)             (JNIEnv *, jclass, jclass);
+
+  jobject  (*ToReflectedField)            (JNIEnv *, jclass, jfieldID,
+                                           jboolean);
+
+  jint     (*Throw)                        (JNIEnv *, jthrowable);
+  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;
+
+  jint     (*PushLocalFrame)              (JNIEnv *, jint);
+  jobject  (*PopLocalFrame)               (JNIEnv *, jobject result);
+
+  jobject  (*NewGlobalRef)                 (JNIEnv *, jobject);
+  void     (*DeleteGlobalRef)              (JNIEnv *, jobject);
+  void     (*DeleteLocalRef)               (JNIEnv *, jobject);;
   jboolean (*IsSameObject)                 (JNIEnv *, jobject, jobject);
-  _Jv_func reserved10;
-  _Jv_func reserved11;
+
+  jobject  (*NewLocalRef)                 (JNIEnv *, jobject);
+  jint     (*EnsureLocalCapacity)         (JNIEnv *, jint);
 
   jobject  (*AllocObject)                  (JNIEnv *, jclass);
   jobject (*NewObject)                    (JNIEnv *, jclass, jmethodID, ...);
@@ -471,20 +496,29 @@ struct JNINativeInterface
   void                 (*SetDoubleArrayRegion)    (JNIEnv *, jbooleanArray,
                                            jsize, jsize, jboolean *);
 
-  _Jv_func RegisterNatives;
-  _Jv_func UnregisterNatives;
+  jint     (*RegisterNatives)              (JNIEnv *, jclass,
+                                           const JNINativeMethod *, jint);
+  jint     (*UnregisterNatives)            (JNIEnv *, jclass);
   jint     (*MonitorEnter)                 (JNIEnv *, jobject);
   jint     (*MonitorExit)                  (JNIEnv *, jobject);
-  _Jv_func GetJavaVM;
-};
+  jint     (*GetJavaVM)                    (JNIEnv *, JavaVM **);
 
-/* This structure is used when registering native methods.  */
-typedef struct
-{
-  char *name;
-  char *signature;
-  void *fnPtr;                 /* Sigh.  */
-} JNINativeMethod;
+  void    (*GetStringRegion)              (JNIEnv *, jstring, jsize,
+                                           jsize, jchar *);
+  void     (*GetStringUTFRegion)          (JNIEnv *, jstring, jsize,
+                                           jsize, char *);
+
+  void * (*GetPrimitiveArrayCritical)      (JNIEnv *, jarray, jboolean *);
+  void   (*ReleasePrimitiveArrayCritical)  (JNIEnv *, jarray, void *, jint);
+
+  const jchar * (*GetStringCritical)       (JNIEnv *, jstring, jboolean *);
+  void          (*ReleaseStringCritical)   (JNIEnv *, jstring, const jchar *);
+
+  jweak  (*NewWeakGlobalRef)               (JNIEnv *, jobject);
+  void   (*DeleteWeakGlobalRef)            (JNIEnv *, jweak);
+
+  jboolean     (*ExceptionCheck)          (JNIEnv *);
+};
 
 #ifdef __cplusplus
 
@@ -494,16 +528,15 @@ public:
   /* The method table.  */
   struct JNINativeInterface *p;
 
+  /* FIXME: this is really ugly.  */
+#ifndef __GCJ_JNI_IMPL__
 private:
+#endif
   /* 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
+  /* The class of the current native method.  */
+  jclass klass;
 
 public:
   jclass GetSuperclass (jclass cl)
index b7477c7..2ad6c5d 100644 (file)
@@ -177,7 +177,11 @@ private:
   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 jobject _Jv_JNI_ToReflectedField (_Jv_JNIEnv *, jclass, jfieldID,
+                                          jboolean);
+  friend jobject _Jv_JNI_ToReflectedMethod (_Jv_JNIEnv *, jclass, jmethodID,
+                                           jboolean);
   friend jfieldID _Jv_FromReflectedField (java::lang::reflect::Field *);
 
   friend jmethodID _Jv_FromReflectedMethod (java::lang::reflect::Method *);
@@ -266,17 +270,4 @@ 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 cc0ba6b..e67bd8c 100644 (file)
@@ -18,28 +18,37 @@ details.  */
 
 #include <stddef.h>
 
-// Must define this before jni.h.
-#define GCJ_JV_JNIENV_FRIEND \
-    friend jthrowable &get_throwable (JNIEnv *)
+// Define this before including jni.h.
+#define __GCJ_JNI_IMPL__
 
 #include <gcj/cni.h>
 #include <jvm.h>
 #include <java-assert.h>
 #include <jni.h>
-#include <gcj/field.h>
+
+#include <java/lang/Class.h>
+#include <java/lang/ClassLoader.h>
 #include <java/lang/Throwable.h>
 #include <java/lang/ArrayIndexOutOfBoundsException.h>
+#include <java/lang/StringIndexOutOfBoundsException.h>
 #include <java/lang/InstantiationException.h>
 #include <java/lang/NoSuchFieldError.h>
 #include <java/lang/NoSuchMethodError.h>
 #include <java/lang/reflect/Constructor.h>
+#include <java/lang/reflect/Method.h>
 #include <java/lang/reflect/Modifier.h>
 
+#include <gcj/method.h>
+#include <gcj/field.h>
+
 #define ClassClass _CL_Q34java4lang5Class
 extern java::lang::Class ClassClass;
 #define ObjectClass _CL_Q34java4lang6Object
 extern java::lang::Class ObjectClass;
 
+#define MethodClass _CL_Q44java4lang7reflect6Method
+extern java::lang::Class MethodClass;
+
 // This enum is used to select different template instantiations in
 // the invocation code.
 enum invocation_type
@@ -50,6 +59,9 @@ enum invocation_type
   constructor
 };
 
+// Forward declaration.
+extern struct JNINativeInterface _Jv_JNIFunctions;
+
 \f
 
 // Tell the GC that a certain pointer is live.
@@ -66,13 +78,6 @@ unmark_for_gc (void *)
   // FIXME.
 }
 
-// Return throwable in env.
-jthrowable &
-get_throwable (JNIEnv *env)
-{
-  return env->ex;
-}
-
 \f
 
 static jint
@@ -82,13 +87,55 @@ _Jv_JNI_GetVersion (JNIEnv *)
 }
 
 static jclass
+_Jv_JNI_DefineClass (JNIEnv *, jobject loader, 
+                    const jbyte *buf, jsize bufLen)
+{
+  jbyteArray bytes = JvNewByteArray (bufLen);
+  jbyte *elts = elements (bytes);
+  memcpy (elts, buf, bufLen * sizeof (jbyte));
+
+  java::lang::ClassLoader *l
+    = reinterpret_cast<java::lang::ClassLoader *> (loader);
+
+  // FIXME: exception processing.
+  jclass result = l->defineClass (bytes, 0, bufLen);
+  return result;
+}
+
+static jclass
+_Jv_JNI_FindClass (JNIEnv *env, const char *name)
+{
+  // FIXME: assume that NAME isn't too long.
+  int len = strlen (name);
+  char s[len + 1];
+  for (int i = 0; i <= len; ++i)
+    s[i] = (name[i] == '/') ? '.' : name[i];
+  jstring n = JvNewStringUTF (s);
+
+  java::lang::ClassLoader *loader;
+  if (env->klass == NULL)
+    {
+      // FIXME: should use getBaseClassLoader, but we don't have that
+      // yet.
+      loader = java::lang::ClassLoader::getSystemClassLoader ();
+    }
+  else
+    loader = env->klass->getClassLoader ();
+
+  // FIXME: exception processing.
+  jclass r = loader->findClass (n);
+
+  return r;
+}
+
+static jclass
 _Jv_JNI_GetSuperclass (JNIEnv *, jclass clazz)
 {
   return clazz->getSuperclass ();
 }
 
 static jboolean
-IsAssignableFrom(JNIEnv *, jclass clazz1, jclass clazz2)
+_Jv_JNI_IsAssignableFrom(JNIEnv *, jclass clazz1, jclass clazz2)
 {
   return clazz1->isAssignableFrom (clazz2);
 }
@@ -96,7 +143,7 @@ IsAssignableFrom(JNIEnv *, jclass clazz1, jclass clazz2)
 static jint
 _Jv_JNI_Throw (JNIEnv *env, jthrowable obj)
 {
-  get_throwable (env) = obj;
+  env->ex = obj;
   return 0;
 }
 
@@ -121,27 +168,34 @@ _Jv_JNI_ThrowNew (JNIEnv *env, jclass clazz, const char *message)
   // FIXME: exception processing.
   jobject obj = cons->newInstance (values);
 
-  get_throwable (env) = reinterpret_cast<jthrowable> (obj);
+  env->ex = reinterpret_cast<jthrowable> (obj);
   return 0;
 }
 
 static jthrowable
 _Jv_JNI_ExceptionOccurred (JNIEnv *env)
 {
-  return get_throwable (env);
+  // FIXME: create local reference.
+  return env->ex;
 }
 
 static void
 _Jv_JNI_ExceptionDescribe (JNIEnv *env)
 {
-  if (get_throwable (env) != NULL)
-    get_throwable (env)->printStackTrace();
+  if (env->ex != NULL)
+    env->ex->printStackTrace();
 }
 
 static void
 _Jv_JNI_ExceptionClear (JNIEnv *env)
 {
-  get_throwable (env) = NULL;
+  env->ex = NULL;
+}
+
+static jboolean
+_Jv_JNI_ExceptionCheck (JNIEnv *env)
+{
+  return env->ex != NULL;
 }
 
 static void
@@ -162,7 +216,7 @@ _Jv_JNI_AllocObject (JNIEnv *env, jclass clazz)
   jobject obj = NULL;
   using namespace java::lang::reflect;
   if (clazz->isInterface() || Modifier::isAbstract(clazz->getModifiers()))
-    get_throwable (env) = new java::lang::InstantiationException ();
+    env->ex = new java::lang::InstantiationException ();
   else
     {
       // FIXME: exception processing.
@@ -225,7 +279,7 @@ _Jv_JNI_GetAnyMethodID (JNIEnv *env, jclass clazz,
       clazz = clazz->getSuperclass ();
     }
 
-  get_throwable (env) = new java::lang::NoSuchMethodError ();
+  env->ex = new java::lang::NoSuchMethodError ();
   return NULL;
 }
 
@@ -290,7 +344,7 @@ _Jv_JNI_CallAnyMethodV (JNIEnv *env, jobject obj, jclass klass,
                                      arg_types, args, &result);
 
   if (ex != NULL)
-    get_throwable (env) = ex;
+    env->ex = ex;
 
   // We cheat a little here.  FIXME.
   return * (T *) &result;
@@ -334,7 +388,7 @@ _Jv_JNI_CallAnyMethodA (JNIEnv *env, jobject obj, jclass klass,
                                      arg_types, args, &result);
 
   if (ex != NULL)
-    get_throwable (env) = ex;
+    env->ex = ex;
 
   // We cheat a little here.  FIXME.
   return * (T *) &result;
@@ -365,7 +419,7 @@ _Jv_JNI_CallAnyVoidMethodV (JNIEnv *env, jobject obj, jclass klass,
                                      arg_types, args, NULL);
 
   if (ex != NULL)
-    get_throwable (env) = ex;
+    env->ex = ex;
 }
 
 template<invocation_type style>
@@ -402,7 +456,7 @@ _Jv_JNI_CallAnyVoidMethodA (JNIEnv *env, jobject obj, jclass klass,
                                      arg_types, args, NULL);
 
   if (ex != NULL)
-    get_throwable (env) = ex;
+    env->ex = ex;
 }
 
 // Functions with this signature are used to implement functions in
@@ -617,7 +671,7 @@ _Jv_JNI_GetAnyFieldID (JNIEnv *env, jclass clazz,
       clazz = clazz->getSuperclass ();
     }
 
-  get_throwable (env) = new java::lang::NoSuchFieldError ();
+  env->ex = new java::lang::NoSuchFieldError ();
   return NULL;
 }
 
@@ -702,6 +756,44 @@ _Jv_JNI_ReleaseStringUTFChars (JNIEnv *, jstring, const char *utf)
   _Jv_Free ((void *) utf);
 }
 
+static void
+_Jv_JNI_GetStringRegion (JNIEnv *env, jstring string, jsize start, jsize len,
+                        jchar *buf)
+{
+  jchar *result = _Jv_GetStringChars (string);
+  if (start < 0 || start > string->length ()
+      || len < 0 || start + len > string->length ())
+    env->ex = new java::lang::StringIndexOutOfBoundsException ();
+  else
+    memcpy (buf, &result[start], len * sizeof (jchar));
+}
+
+static void
+_Jv_JNI_GetStringUTFRegion (JNIEnv *env, jstring str, jsize start,
+                           jsize len, char *buf)
+{
+  if (start < 0 || start > str->length ()
+      || len < 0 || start + len > str->length ())
+    env->ex = new java::lang::StringIndexOutOfBoundsException ();
+  else
+    _Jv_GetStringUTFRegion (str, start, len, buf);
+}
+
+static const jchar *
+_Jv_JNI_GetStringCritical (JNIEnv *, jstring str, jboolean *isCopy)
+{
+  jchar *result = _Jv_GetStringChars (str);
+  if (isCopy)
+    *isCopy = false;
+  return result;
+}
+
+static void
+_Jv_JNI_ReleaseStringCritical (JNIEnv *, jstring, const jchar *)
+{
+  // Nothing.
+}
+
 static jsize
 _Jv_JNI_GetArrayLength (JNIEnv *, jarray array)
 {
@@ -776,7 +868,7 @@ _Jv_JNI_GetPrimitiveArrayRegion (JNIEnv *env, JArray<T> *array,
   if (start < 0 || len >= array->length || start + len >= array->length)
     {
       // FIXME: index.
-      get_throwable (env) = new java::lang::ArrayIndexOutOfBoundsException ();
+      env->ex = new java::lang::ArrayIndexOutOfBoundsException ();
     }
   else
     {
@@ -793,7 +885,7 @@ _Jv_JNI_SetPrimitiveArrayRegion (JNIEnv *env, JArray<T> *array,
   if (start < 0 || len >= array->length || start + len >= array->length)
     {
       // FIXME: index.
-      get_throwable (env) = new java::lang::ArrayIndexOutOfBoundsException ();
+      env->ex = new java::lang::ArrayIndexOutOfBoundsException ();
     }
   else
     {
@@ -802,6 +894,25 @@ _Jv_JNI_SetPrimitiveArrayRegion (JNIEnv *env, JArray<T> *array,
     }
 }
 
+static void *
+_Jv_JNI_GetPrimitiveArrayCritical (JNIEnv *, jarray array,
+                                  jboolean *isCopy)
+{
+  // FIXME: does this work?
+  jclass klass = array->getClass()->getComponentType();
+  JvAssert (klass->isPrimitive ());
+  char *r = _Jv_GetArrayElementFromElementType (array, klass);
+  if (isCopy)
+    *isCopy = false;
+  return r;
+}
+
+static void
+_Jv_JNI_ReleasePrimitiveArrayCritical (JNIEnv *, jarray, void *, jint)
+{
+  // Nothing.
+}
+
 static jint
 _Jv_JNI_MonitorEnter (JNIEnv *, jobject obj)
 {
@@ -820,22 +931,94 @@ _Jv_JNI_MonitorExit (JNIEnv *, jobject obj)
 
 // JDK 1.2
 jobject
-_Jv_JNI_ToReflectedField (JNIEnv *, jclass cls, jfieldID fieldID)
+_Jv_JNI_ToReflectedField (JNIEnv *, jclass cls, jfieldID fieldID,
+                         jboolean)
 {
+  // FIXME: exception processing.
   java::lang::reflect::Field *field = new java::lang::reflect::Field();
   field->declaringClass = cls;
   field->offset = (char*) fieldID - (char *) cls->fields;
   field->name = _Jv_NewStringUtf8Const (fieldID->getNameUtf8Const (cls));
+  // FIXME: make a local reference.
   return field;
 }
 
 // JDK 1.2
-jfieldID
-_Jv_JNI_FromReflectedField (JNIEnv *, java::lang::reflect::Field *field)
+static jfieldID
+_Jv_JNI_FromReflectedField (JNIEnv *, jobject f)
 {
+  using namespace java::lang::reflect;
+
+  Field *field = reinterpret_cast<Field *> (f);
   return _Jv_FromReflectedField (field);
 }
 
+jobject
+_Jv_JNI_ToReflectedMethod (JNIEnv *, jclass klass, jmethodID id,
+                          jboolean)
+{
+  using namespace java::lang::reflect;
+
+  // FIXME.
+  static _Jv_Utf8Const *init_name = _Jv_makeUtf8Const ("<init>", 6);
+
+  jobject result;
+  if (_Jv_equalUtf8Consts (id->name, init_name))
+    {
+      // A constructor.
+      Constructor *cons = new Constructor ();
+      cons->offset = (char *) id - (char *) &klass->methods;
+      cons->declaringClass = klass;
+      result = cons;
+    }
+  else
+    {
+      Method *meth = new Method ();
+      meth->offset = (char *) id - (char *) &klass->methods;
+      meth->declaringClass = klass;
+      result = meth;
+    }
+
+  // FIXME: make a local reference.
+  return result;
+}
+
+static jmethodID
+_Jv_JNI_FromReflectedMethod (JNIEnv *, jobject method)
+{
+  using namespace java::lang::reflect;
+  if ((&MethodClass)->isInstance (method))
+    return _Jv_FromReflectedMethod (reinterpret_cast<Method *> (method));
+  return
+    _Jv_FromReflectedConstructor (reinterpret_cast<Constructor *> (method));
+}
+
+\f
+
+// This function is the stub which is used to turn an ordinary (CNI)
+// method call into a JNI call.
+#if 0
+template<typename T>
+static T
+_Jv_JNI_conversion_call (fixme)
+{
+  JNIEnv env;
+
+  env.p = &_Jv_JNIFunctions;
+  env.ex = NULL;
+  env.klass = FIXME;
+
+  T result = FIXME_ffi_call (args);
+
+  if (env.ex)
+    JvThrow (env.ex);
+
+  return T;
+}
+#endif
+
+\f
+
 #define NOT_IMPL NULL
 #define RESERVED NULL
 
@@ -846,28 +1029,28 @@ struct JNINativeInterface _Jv_JNIFunctions =
   RESERVED,
   RESERVED,
   _Jv_JNI_GetVersion,
-  NOT_IMPL /* DefineClass */,
-  NOT_IMPL /* FindClass */,
-  RESERVED,
-  RESERVED,
-  RESERVED,
+  _Jv_JNI_DefineClass,
+  _Jv_JNI_FindClass,
+  _Jv_JNI_FromReflectedMethod,
+  _Jv_JNI_FromReflectedField,
+  _Jv_JNI_ToReflectedMethod,
   _Jv_JNI_GetSuperclass,
-  IsAssignableFrom,
-  RESERVED,
+  _Jv_JNI_IsAssignableFrom,
+  _Jv_JNI_ToReflectedField,
   _Jv_JNI_Throw,
   _Jv_JNI_ThrowNew,
   _Jv_JNI_ExceptionOccurred,
   _Jv_JNI_ExceptionDescribe,
   _Jv_JNI_ExceptionClear,
   _Jv_JNI_FatalError,
-  RESERVED,
-  RESERVED,
+  NOT_IMPL,
+  NOT_IMPL,
   NOT_IMPL /* NewGlobalRef */,
   NOT_IMPL /* DeleteGlobalRef */,
   NOT_IMPL /* DeleteLocalRef */,
   _Jv_JNI_IsSameObject,
-  RESERVED,
-  RESERVED,
+  NOT_IMPL,
+  NOT_IMPL,
   _Jv_JNI_AllocObject,
   _Jv_JNI_NewObject,
   _Jv_JNI_NewObjectV,
@@ -1067,4 +1250,16 @@ struct JNINativeInterface _Jv_JNIFunctions =
   _Jv_JNI_MonitorEnter,
   _Jv_JNI_MonitorExit,
   NOT_IMPL /* GetJavaVM */,
+
+  _Jv_JNI_GetStringRegion,
+  _Jv_JNI_GetStringUTFRegion,
+  _Jv_JNI_GetPrimitiveArrayCritical,
+  _Jv_JNI_ReleasePrimitiveArrayCritical,
+  _Jv_JNI_GetStringCritical,
+  _Jv_JNI_ReleaseStringCritical,
+
+  NOT_IMPL /* newweakglobalref */,
+  NOT_IMPL /* deleteweakglobalref */,
+
+  _Jv_JNI_ExceptionCheck
 };