Makefile.in: Rebuilt.
authorTom Tromey <tromey@redhat.com>
Tue, 13 Nov 2001 17:43:41 +0000 (17:43 +0000)
committerTom Tromey <tromey@gcc.gnu.org>
Tue, 13 Nov 2001 17:43:41 +0000 (17:43 +0000)
* Makefile.in: Rebuilt.
* Makefile.am (ordinary_java_source_files): Added JNIWeakRef.java.
* jni.cc: Include JNIWeakRef.h.
(unwrap): New function.
(_Jv_JNI_DefineClass): Use it.
(_Jv_JNI_GetSuperclass): Likewise.
(_Jv_JNI_IsAssignableFrom): Likewise.
(_Jv_JNI_Throw): Likewise.
(_Jv_JNI_ThrowNew): Likewise.
(_Jv_JNI_IsSameObject): Likewise.
(_Jv_JNI_AllocObject): Likewise.
(_Jv_JNI_GetObjectClass): Likewise.
(_Jv_JNI_IsInstanceOf): Likewise.
(_Jv_JNI_GetAnyMethodID): Likewise.
(array_from_valist): Likewise.
(_Jv_JNI_CallAnyMethodV): Likewise.
(_Jv_JNI_CallAnyMethodA): Likewise.
(_Jv_JNI_CallAnyVoidMethodV): Likewise.
(_Jv_JNI_CallAnyVoidMethodA): Likewise.
(_Jv_JNI_CallStaticMethodV): Likewise.
(_Jv_JNI_CallStaticMethod): Likewise.
(_Jv_JNI_CallStaticMethodA): Likewise.
(_Jv_JNI_NewObjectV): Likewise.
(_Jv_JNI_NewObject): Likewise.
(_Jv_JNI_NewObjectA): Likewise.
(_Jv_JNI_GetField): Likewise.
(_Jv_JNI_SetField): Likewise.
(_Jv_JNI_GetAnyFieldID): Likewise.
(_Jv_JNI_SetStaticField): Likewise.
(_Jv_JNI_GetStringLength): Likewise.
(_Jv_JNI_GetStringChars): Likewise.
(_Jv_JNI_ReleaseStringChars): Likewise.
(_Jv_JNI_GetStringUTFLength): Likewise
(_Jv_JNI_GetStringUTFChars): Likewise.
(_Jv_JNI_GetStringRegion): Likewise.
(_Jv_JNI_GetStringUTFRegion): Likewise.
(_Jv_JNI_GetStringCritical): Likewise.
(_Jv_JNI_GetArrayLength): Likewise.
(_Jv_JNI_NewObjectArray): Likewise.
(_Jv_JNI_GetObjectArrayElement): Likewise.
(_Jv_JNI_SetObjectArrayElement): Likewise.
(_Jv_JNI_GetPrimitiveArrayElements): Likewise.
(_Jv_JNI_ReleasePrimitiveArrayElements): Likewise.
(_Jv_JNI_GetPrimitiveArrayRegion): Likewise.
(_Jv_JNI_SetPrimitiveArrayRegion): Likewise.
(_Jv_JNI_MonitorEnter): Likewise.
(_Jv_JNI_MonitorExit): Likewise.
(_Jv_JNI_ToReflectedField): Likewise.
(_Jv_JNI_FromReflectedField): Likewise.
(_Jv_JNI_ToReflectedMethod): Likewise.
(_Jv_JNI_FromReflectedMethod): Likewise.
(_Jv_JNI_NewGlobalRef): Likewise.
(_Jv_JNI_DeleteGlobalRef): Likewise.
(_Jv_JNI_DeleteLocalRef): Likewise.
(_Jv_JNI_NewLocalRef): Likewise.
(_Jv_JNI_NewWeakGlobalRef): New function.
(_Jv_JNI_DeleteWeakGlobalRef): Likewise.
(_Jv_JNIFunctions): Updated for new methods.
(NOT_IMPL): Removed.
* gnu/gcj/runtime/JNIWeakRef.java: New file.

From-SVN: r46990

libjava/ChangeLog
libjava/Makefile.am
libjava/Makefile.in
libjava/gnu/gcj/runtime/JNIWeakRef.java [new file with mode: 0644]
libjava/jni.cc

index 0b6c195a7b9da8b43ca6beeebf8a62949099a0e0..9dfcd7b32e9febe147c60b3a26b26a2118a4b535 100644 (file)
@@ -1,3 +1,66 @@
+2001-11-07  Tom Tromey  <tromey@redhat.com>
+
+       * Makefile.in: Rebuilt.
+       * Makefile.am (ordinary_java_source_files): Added JNIWeakRef.java.
+       * jni.cc: Include JNIWeakRef.h.
+       (unwrap): New function.
+       (_Jv_JNI_DefineClass): Use it.
+       (_Jv_JNI_GetSuperclass): Likewise.
+       (_Jv_JNI_IsAssignableFrom): Likewise.
+       (_Jv_JNI_Throw): Likewise.
+       (_Jv_JNI_ThrowNew): Likewise.
+       (_Jv_JNI_IsSameObject): Likewise.
+       (_Jv_JNI_AllocObject): Likewise.
+       (_Jv_JNI_GetObjectClass): Likewise.
+       (_Jv_JNI_IsInstanceOf): Likewise.
+       (_Jv_JNI_GetAnyMethodID): Likewise.
+       (array_from_valist): Likewise.
+       (_Jv_JNI_CallAnyMethodV): Likewise.
+       (_Jv_JNI_CallAnyMethodA): Likewise.
+       (_Jv_JNI_CallAnyVoidMethodV): Likewise.
+       (_Jv_JNI_CallAnyVoidMethodA): Likewise.
+       (_Jv_JNI_CallStaticMethodV): Likewise.
+       (_Jv_JNI_CallStaticMethod): Likewise.
+       (_Jv_JNI_CallStaticMethodA): Likewise.
+       (_Jv_JNI_NewObjectV): Likewise.
+       (_Jv_JNI_NewObject): Likewise.
+       (_Jv_JNI_NewObjectA): Likewise.
+       (_Jv_JNI_GetField): Likewise.
+       (_Jv_JNI_SetField): Likewise.
+       (_Jv_JNI_GetAnyFieldID): Likewise.
+       (_Jv_JNI_SetStaticField): Likewise.
+       (_Jv_JNI_GetStringLength): Likewise.
+       (_Jv_JNI_GetStringChars): Likewise.
+       (_Jv_JNI_ReleaseStringChars): Likewise.
+       (_Jv_JNI_GetStringUTFLength): Likewise
+       (_Jv_JNI_GetStringUTFChars): Likewise.
+       (_Jv_JNI_GetStringRegion): Likewise.
+       (_Jv_JNI_GetStringUTFRegion): Likewise.
+       (_Jv_JNI_GetStringCritical): Likewise.
+       (_Jv_JNI_GetArrayLength): Likewise.
+       (_Jv_JNI_NewObjectArray): Likewise.
+       (_Jv_JNI_GetObjectArrayElement): Likewise.
+       (_Jv_JNI_SetObjectArrayElement): Likewise.
+       (_Jv_JNI_GetPrimitiveArrayElements): Likewise.
+       (_Jv_JNI_ReleasePrimitiveArrayElements): Likewise.
+       (_Jv_JNI_GetPrimitiveArrayRegion): Likewise.
+       (_Jv_JNI_SetPrimitiveArrayRegion): Likewise.
+       (_Jv_JNI_MonitorEnter): Likewise.
+       (_Jv_JNI_MonitorExit): Likewise.
+       (_Jv_JNI_ToReflectedField): Likewise.
+       (_Jv_JNI_FromReflectedField): Likewise.
+       (_Jv_JNI_ToReflectedMethod): Likewise.
+       (_Jv_JNI_FromReflectedMethod): Likewise.
+       (_Jv_JNI_NewGlobalRef): Likewise.
+       (_Jv_JNI_DeleteGlobalRef): Likewise.
+       (_Jv_JNI_DeleteLocalRef): Likewise.
+       (_Jv_JNI_NewLocalRef): Likewise.
+       (_Jv_JNI_NewWeakGlobalRef): New function.
+       (_Jv_JNI_DeleteWeakGlobalRef): Likewise.
+       (_Jv_JNIFunctions): Updated for new methods.
+       (NOT_IMPL): Removed.
+       * gnu/gcj/runtime/JNIWeakRef.java: New file.
+
 2001-11-12  Bryce McKinlay  <bryce@waitaki.otago.ac.nz>
 
        * boehm.cc (_Jv_GCCanReclaimSoftReference): Fix warning.
index a75d886eddd9660e3690a0cd75b07289171cc887..eaf3f12b793b3ccb764535295e6176bbc2e305d9 100644 (file)
@@ -1263,6 +1263,7 @@ gnu/gcj/protocol/jar/Handler.java \
 gnu/gcj/runtime/FileDeleter.java \
 gnu/gcj/runtime/FinalizerThread.java \
 gnu/gcj/runtime/FirstThread.java \
+gnu/gcj/runtime/JNIWeakRef.java \
 gnu/gcj/runtime/SharedLibLoader.java \
 gnu/gcj/runtime/VMClassLoader.java \
 gnu/java/io/ClassLoaderObjectInputStream.java \
index 5d51c32599402a9d6aec5da4ab03bff03fd32a9c..7696a378ad970a39dfbbf5bc0a15cedc3941a2f4 100644 (file)
@@ -996,6 +996,7 @@ gnu/gcj/protocol/jar/Handler.java \
 gnu/gcj/runtime/FileDeleter.java \
 gnu/gcj/runtime/FinalizerThread.java \
 gnu/gcj/runtime/FirstThread.java \
+gnu/gcj/runtime/JNIWeakRef.java \
 gnu/gcj/runtime/SharedLibLoader.java \
 gnu/gcj/runtime/VMClassLoader.java \
 gnu/java/io/ClassLoaderObjectInputStream.java \
@@ -1636,7 +1637,7 @@ DEP_FILES =  .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \
 .deps/gnu/gcj/protocol/jar/Handler.P \
 .deps/gnu/gcj/runtime/FileDeleter.P \
 .deps/gnu/gcj/runtime/FinalizerThread.P \
-.deps/gnu/gcj/runtime/FirstThread.P \
+.deps/gnu/gcj/runtime/FirstThread.P .deps/gnu/gcj/runtime/JNIWeakRef.P \
 .deps/gnu/gcj/runtime/SharedLibLoader.P \
 .deps/gnu/gcj/runtime/VMClassLoader.P \
 .deps/gnu/gcj/runtime/natFinalizerThread.P \
diff --git a/libjava/gnu/gcj/runtime/JNIWeakRef.java b/libjava/gnu/gcj/runtime/JNIWeakRef.java
new file mode 100644 (file)
index 0000000..c0c76cd
--- /dev/null
@@ -0,0 +1,24 @@
+// JNIWeakRef.java - Wrapper class for JNI-specific weak references.
+
+/* Copyright (C) 2001  Free Software Foundation
+
+   This file is part of libgcj.
+
+This software is copyrighted work licensed under the terms of the
+Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
+details.  */
+
+package gnu.gcj.runtime;
+
+import java.lang.ref.*;
+
+// This wrapper is used by the JNI implementation to keep track of
+// global weak references.  Each such reference is wrapped in an
+// instance of this class, and automatically unwrapped when used.
+public final class JNIWeakRef extends WeakReference
+{
+  public JNIWeakRef (Object referent)
+  {
+    super (referent);
+  }
+}
index 0348d1de620d022f0fe3b5e551e54674290f1cfb..1aa77bc2c04417d5a667afa144e0030fa8e6ed5c 100644 (file)
@@ -41,6 +41,7 @@ details.  */
 #include <java/lang/Integer.h>
 #include <java/lang/ThreadGroup.h>
 #include <java/lang/Thread.h>
+#include <gnu/gcj/runtime/JNIWeakRef.h>
 
 #include <gcj/method.h>
 #include <gcj/field.h>
@@ -194,11 +195,36 @@ unmark_for_gc (jobject obj, java::util::IdentityHashMap *ref_table)
     ref_table->put (obj, new Integer (val));
 }
 
+// "Unwrap" some random non-reference type.  This exists to simplify
+// other template functions.
+template<typename T>
+static T
+unwrap (T val)
+{
+  return val;
+}
+
+// Unwrap a weak reference, if required.
+template<typename T>
+static T *
+unwrap (T *obj)
+{
+  using namespace gnu::gcj::runtime;
+  // We can compare the class directly because JNIWeakRef is `final'.
+  // Doing it this way is much faster.
+  if (obj == NULL || obj->getClass () == &JNIWeakRef::class$)
+    return obj;
+  JNIWeakRef *wr = reinterpret_cast<JNIWeakRef *> (obj);
+  return reinterpret_cast<T *> (wr->get ());
+}
+
 \f
 
 static jobject
 _Jv_JNI_NewGlobalRef (JNIEnv *, jobject obj)
 {
+  // This seems weird but I think it is correct.
+  obj = unwrap (obj);
   mark_for_gc (obj, global_ref_table);
   return obj;
 }
@@ -206,6 +232,8 @@ _Jv_JNI_NewGlobalRef (JNIEnv *, jobject obj)
 static void
 _Jv_JNI_DeleteGlobalRef (JNIEnv *, jobject obj)
 {
+  // This seems weird but I think it is correct.
+  obj = unwrap (obj);
   unmark_for_gc (obj, global_ref_table);
 }
 
@@ -214,6 +242,9 @@ _Jv_JNI_DeleteLocalRef (JNIEnv *env, jobject obj)
 {
   _Jv_JNI_LocalFrame *frame;
 
+  // This seems weird but I think it is correct.
+  obj = unwrap (obj);
+
   for (frame = env->locals; frame != NULL; frame = frame->next)
     {
       for (int i = 0; i < frame->size; ++i)
@@ -277,6 +308,9 @@ _Jv_JNI_PushLocalFrame (JNIEnv *env, jint size)
 static jobject
 _Jv_JNI_NewLocalRef (JNIEnv *env, jobject obj)
 {
+  // This seems weird but I think it is correct.
+  obj = unwrap (obj);
+
   // Try to find an open slot somewhere in the topmost frame.
   _Jv_JNI_LocalFrame *frame = env->locals;
   bool done = false, set = false;
@@ -403,6 +437,8 @@ _Jv_JNI_DefineClass (JNIEnv *env, jobject loader,
 {
   try
     {
+      loader = unwrap (loader);
+
       jbyteArray bytes = JvNewByteArray (bufLen);
 
       jbyte *elts = elements (bytes);
@@ -460,19 +496,20 @@ _Jv_JNI_FindClass (JNIEnv *env, const char *name)
 static jclass
 _Jv_JNI_GetSuperclass (JNIEnv *env, jclass clazz)
 {
-  return (jclass) wrap_value (env, clazz->getSuperclass ());
+  return (jclass) wrap_value (env, unwrap (clazz)->getSuperclass ());
 }
 
 static jboolean
 _Jv_JNI_IsAssignableFrom(JNIEnv *, jclass clazz1, jclass clazz2)
 {
-  return clazz1->isAssignableFrom (clazz2);
+  return unwrap (clazz1)->isAssignableFrom (unwrap (clazz2));
 }
 
 static jint
 _Jv_JNI_Throw (JNIEnv *env, jthrowable obj)
 {
   // We check in case the user did some funky cast.
+  obj = unwrap (obj);
   JvAssert (obj != NULL && java::lang::Throwable::class$.isInstance (obj));
   env->ex = obj;
   return 0;
@@ -483,6 +520,7 @@ _Jv_JNI_ThrowNew (JNIEnv *env, jclass clazz, const char *message)
 {
   using namespace java::lang::reflect;
 
+  clazz = unwrap (clazz);
   JvAssert (java::lang::Throwable::class$.isAssignableFrom (clazz));
 
   int r = JNI_OK;
@@ -550,7 +588,7 @@ _Jv_JNI_FatalError (JNIEnv *, const char *message)
 static jboolean
 _Jv_JNI_IsSameObject (JNIEnv *, jobject obj1, jobject obj2)
 {
-  return obj1 == obj2;
+  return unwrap (obj1) == unwrap (obj2);
 }
 
 static jobject
@@ -561,6 +599,7 @@ _Jv_JNI_AllocObject (JNIEnv *env, jclass clazz)
 
   try
     {
+      clazz = unwrap (clazz);
       JvAssert (clazz && ! clazz->isArray ());
       if (clazz->isInterface() || Modifier::isAbstract(clazz->getModifiers()))
        env->ex = new java::lang::InstantiationException ();
@@ -581,6 +620,7 @@ _Jv_JNI_AllocObject (JNIEnv *env, jclass clazz)
 static jclass
 _Jv_JNI_GetObjectClass (JNIEnv *env, jobject obj)
 {
+  obj = unwrap (obj);
   JvAssert (obj);
   return (jclass) wrap_value (env, obj->getClass());
 }
@@ -588,7 +628,7 @@ _Jv_JNI_GetObjectClass (JNIEnv *env, jobject obj)
 static jboolean
 _Jv_JNI_IsInstanceOf (JNIEnv *, jobject obj, jclass clazz)
 {
-  return clazz->isInstance(obj);
+  return unwrap (clazz)->isInstance(unwrap (obj));
 }
 
 \f
@@ -604,6 +644,7 @@ _Jv_JNI_GetAnyMethodID (JNIEnv *env, jclass clazz,
 {
   try
     {
+      clazz = unwrap (clazz);
       _Jv_InitClass (clazz);
 
       _Jv_Utf8Const *name_u = _Jv_makeUtf8Const ((char *) name, -1);
@@ -676,7 +717,7 @@ array_from_valist (jvalue *values, JArray<jclass> *arg_types, va_list vargs)
       else
        {
          // An object.
-         values[i].l = va_arg (vargs, jobject);
+         values[i].l = unwrap (va_arg (vargs, jobject));
        }
     }
 }
@@ -688,6 +729,9 @@ static T
 _Jv_JNI_CallAnyMethodV (JNIEnv *env, jobject obj, jclass klass,
                        jmethodID id, va_list vargs)
 {
+  obj = unwrap (obj);
+  klass = unwrap (klass);
+
   if (style == normal)
     id = _Jv_LookupDeclaredMethod (obj->getClass (), id->name, id->signature);
 
@@ -748,6 +792,9 @@ static T
 _Jv_JNI_CallAnyMethodA (JNIEnv *env, jobject obj, jclass klass,
                        jmethodID id, jvalue *args)
 {
+  obj = unwrap (obj);
+  klass = unwrap (klass);
+
   if (style == normal)
     id = _Jv_LookupDeclaredMethod (obj->getClass (), id->name, id->signature);
 
@@ -765,10 +812,21 @@ _Jv_JNI_CallAnyMethodA (JNIEnv *env, jobject obj, jclass klass,
       if (style == constructor)
        return_type = klass;
 
+      // Unwrap arguments as required.  Eww.
+      jclass *type_elts = elements (arg_types);
+      jvalue arg_copy[arg_types->length];
+      for (int i = 0; i < arg_types->length; ++i)
+       {
+         if (type_elts[i]->isPrimitive ())
+           arg_copy[i] = args[i];
+         else
+           arg_copy[i].l = unwrap (args[i].l);
+       }
+
       jvalue result;
       jthrowable ex = _Jv_CallAnyMethodA (obj, return_type, id,
                                          style == constructor,
-                                         arg_types, args, &result);
+                                         arg_types, arg_copy, &result);
 
       if (ex != NULL)
        env->ex = ex;
@@ -789,6 +847,9 @@ static void
 _Jv_JNI_CallAnyVoidMethodV (JNIEnv *env, jobject obj, jclass klass,
                            jmethodID id, va_list vargs)
 {
+  obj = unwrap (obj);
+  klass = unwrap (klass);
+
   if (style == normal)
     id = _Jv_LookupDeclaredMethod (obj->getClass (), id->name, id->signature);
 
@@ -852,6 +913,17 @@ _Jv_JNI_CallAnyVoidMethodA (JNIEnv *env, jobject obj, jclass klass,
       _Jv_GetTypesFromSignature (id, decl_class,
                                 &arg_types, &return_type);
 
+      // Unwrap arguments as required.  Eww.
+      jclass *type_elts = elements (arg_types);
+      jvalue arg_copy[arg_types->length];
+      for (int i = 0; i < arg_types->length; ++i)
+       {
+         if (type_elts[i]->isPrimitive ())
+           arg_copy[i] = args[i];
+         else
+           arg_copy[i].l = unwrap (args[i].l);
+       }
+
       jthrowable ex = _Jv_CallAnyMethodA (obj, return_type, id,
                                          style == constructor,
                                          arg_types, args, NULL);
@@ -929,7 +1001,7 @@ _Jv_JNI_CallStaticMethodV (JNIEnv *env, jclass klass,
                           jmethodID id, va_list args)
 {
   JvAssert (((id->accflags) & java::lang::reflect::Modifier::STATIC));
-  JvAssert (java::lang::Class::class$.isInstance (klass));
+  JvAssert (java::lang::Class::class$.isInstance (unwrap (klass)));
 
   return _Jv_JNI_CallAnyMethodV<T, static_type> (env, NULL, klass, id, args);
 }
@@ -944,7 +1016,7 @@ _Jv_JNI_CallStaticMethod (JNIEnv *env, jclass klass, jmethodID id, ...)
   T result;
 
   JvAssert (((id->accflags) & java::lang::reflect::Modifier::STATIC));
-  JvAssert (java::lang::Class::class$.isInstance (klass));
+  JvAssert (java::lang::Class::class$.isInstance (unwrap (klass)));
 
   va_start (args, id);
   result = _Jv_JNI_CallAnyMethodV<T, static_type> (env, NULL, klass,
@@ -962,7 +1034,7 @@ _Jv_JNI_CallStaticMethodA (JNIEnv *env, jclass klass, jmethodID id,
                           jvalue *args)
 {
   JvAssert (((id->accflags) & java::lang::reflect::Modifier::STATIC));
-  JvAssert (java::lang::Class::class$.isInstance (klass));
+  JvAssert (java::lang::Class::class$.isInstance (unwrap (klass)));
 
   return _Jv_JNI_CallAnyMethodA<T, static_type> (env, NULL, klass, id, args);
 }
@@ -1048,6 +1120,7 @@ template<typename T>
 static T
 _Jv_JNI_GetField (JNIEnv *env, jobject obj, jfieldID field)
 {
+  obj = unwrap (obj);
   JvAssert (obj);
   T *ptr = (T *) ((char *) obj + field->getOffset ());
   return wrap_value (env, *ptr);
@@ -1057,6 +1130,9 @@ template<typename T>
 static void
 _Jv_JNI_SetField (JNIEnv *, jobject obj, jfieldID field, T value)
 {
+  obj = unwrap (obj);
+  value = unwrap (value);
+
   JvAssert (obj);
   T *ptr = (T *) ((char *) obj + field->getOffset ());
   *ptr = value;
@@ -1069,6 +1145,8 @@ _Jv_JNI_GetAnyFieldID (JNIEnv *env, jclass clazz,
 {
   try
     {
+      clazz = unwrap (clazz);
+
       _Jv_InitClass (clazz);
 
       _Jv_Utf8Const *a_name = _Jv_makeUtf8Const ((char *) name, -1);
@@ -1133,6 +1211,7 @@ template<typename T>
 static void
 _Jv_JNI_SetStaticField (JNIEnv *, jclass, jfieldID field, T value)
 {
+  value = unwrap (value);
   T *ptr = (T *) field->u.addr;
   *ptr = value;
 }
@@ -1155,12 +1234,13 @@ _Jv_JNI_NewString (JNIEnv *env, const jchar *unichars, jsize len)
 static jsize
 _Jv_JNI_GetStringLength (JNIEnv *, jstring string)
 {
-  return string->length();
+  return unwrap (string)->length();
 }
 
 static const jchar *
 _Jv_JNI_GetStringChars (JNIEnv *, jstring string, jboolean *isCopy)
 {
+  string = unwrap (string);
   jchar *result = _Jv_GetStringChars (string);
   mark_for_gc (string, global_ref_table);
   if (isCopy)
@@ -1171,7 +1251,7 @@ _Jv_JNI_GetStringChars (JNIEnv *, jstring string, jboolean *isCopy)
 static void
 _Jv_JNI_ReleaseStringChars (JNIEnv *, jstring string, const jchar *)
 {
-  unmark_for_gc (string, global_ref_table);
+  unmark_for_gc (unwrap (string), global_ref_table);
 }
 
 static jstring
@@ -1192,12 +1272,13 @@ _Jv_JNI_NewStringUTF (JNIEnv *env, const char *bytes)
 static jsize
 _Jv_JNI_GetStringUTFLength (JNIEnv *, jstring string)
 {
-  return JvGetStringUTFLength (string);
+  return JvGetStringUTFLength (unwrap (string));
 }
 
 static const char *
 _Jv_JNI_GetStringUTFChars (JNIEnv *env, jstring string, jboolean *isCopy)
 {
+  string = unwrap (string);
   jsize len = JvGetStringUTFLength (string);
   try
     {
@@ -1227,6 +1308,7 @@ static void
 _Jv_JNI_GetStringRegion (JNIEnv *env, jstring string, jsize start, jsize len,
                         jchar *buf)
 {
+  string = unwrap (string);
   jchar *result = _Jv_GetStringChars (string);
   if (start < 0 || start > string->length ()
       || len < 0 || start + len > string->length ())
@@ -1248,6 +1330,8 @@ static void
 _Jv_JNI_GetStringUTFRegion (JNIEnv *env, jstring str, jsize start,
                            jsize len, char *buf)
 {
+  str = unwrap (str);
+    
   if (start < 0 || start > str->length ()
       || len < 0 || start + len > str->length ())
     {
@@ -1267,7 +1351,7 @@ _Jv_JNI_GetStringUTFRegion (JNIEnv *env, jstring str, jsize start,
 static const jchar *
 _Jv_JNI_GetStringCritical (JNIEnv *, jstring str, jboolean *isCopy)
 {
-  jchar *result = _Jv_GetStringChars (str);
+  jchar *result = _Jv_GetStringChars (unwrap (str));
   if (isCopy)
     *isCopy = false;
   return result;
@@ -1282,7 +1366,7 @@ _Jv_JNI_ReleaseStringCritical (JNIEnv *, jstring, const jchar *)
 static jsize
 _Jv_JNI_GetArrayLength (JNIEnv *, jarray array)
 {
-  return array->length;
+  return unwrap (array)->length;
 }
 
 static jarray
@@ -1291,6 +1375,9 @@ _Jv_JNI_NewObjectArray (JNIEnv *env, jsize length, jclass elementClass,
 {
   try
     {
+      elementClass = unwrap (elementClass);
+      init = unwrap (init);
+
       jarray result = JvNewObjectArray (length, elementClass, init);
       return (jarray) wrap_value (env, result);
     }
@@ -1304,7 +1391,7 @@ _Jv_JNI_NewObjectArray (JNIEnv *env, jsize length, jclass elementClass,
 static jobject
 _Jv_JNI_GetObjectArrayElement (JNIEnv *env, jobjectArray array, jsize index)
 {
-  jobject *elts = elements (array);
+  jobject *elts = elements (unwrap (array));
   return wrap_value (env, elts[index]);
 }
 
@@ -1314,6 +1401,9 @@ _Jv_JNI_SetObjectArrayElement (JNIEnv *env, jobjectArray array, jsize index,
 {
   try
     {
+      array = unwrap (array);
+      value = unwrap (value);
+
       _Jv_CheckArrayStore (array, value);
       jobject *elts = elements (array);
       elts[index] = value;
@@ -1344,6 +1434,7 @@ static T *
 _Jv_JNI_GetPrimitiveArrayElements (JNIEnv *, JArray<T> *array,
                                   jboolean *isCopy)
 {
+  array = unwrap (array);
   T *elts = elements (array);
   if (isCopy)
     {
@@ -1359,6 +1450,7 @@ static void
 _Jv_JNI_ReleasePrimitiveArrayElements (JNIEnv *, JArray<T> *array,
                                       T *, jint /* mode */)
 {
+  array = unwrap (array);
   // 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.
@@ -1371,6 +1463,8 @@ _Jv_JNI_GetPrimitiveArrayRegion (JNIEnv *env, JArray<T> *array,
                                 jsize start, jsize len,
                                 T *buf)
 {
+  array = unwrap (array);
+
   // The cast to unsigned lets us save a comparison.
   if (start < 0 || len < 0
       || (unsigned long) (start + len) > (unsigned long) array->length)
@@ -1398,6 +1492,8 @@ static void
 _Jv_JNI_SetPrimitiveArrayRegion (JNIEnv *env, JArray<T> *array,
                                 jsize start, jsize len, T *buf)
 {
+  array = unwrap (array);
+
   // The cast to unsigned lets us save a comparison.
   if (start < 0 || len < 0
       || (unsigned long) (start + len) > (unsigned long) array->length)
@@ -1423,6 +1519,7 @@ static void *
 _Jv_JNI_GetPrimitiveArrayCritical (JNIEnv *, jarray array,
                                   jboolean *isCopy)
 {
+  array = unwrap (array);
   // FIXME: does this work?
   jclass klass = array->getClass()->getComponentType();
   JvAssert (klass->isPrimitive ());
@@ -1443,7 +1540,7 @@ _Jv_JNI_MonitorEnter (JNIEnv *env, jobject obj)
 {
   try
     {
-      _Jv_MonitorEnter (obj);
+      _Jv_MonitorEnter (unwrap (obj));
       return 0;
     }
   catch (jthrowable t)
@@ -1458,7 +1555,7 @@ _Jv_JNI_MonitorExit (JNIEnv *env, jobject obj)
 {
   try
     {
-      _Jv_MonitorExit (obj);
+      _Jv_MonitorExit (unwrap (obj));
       return 0;
     }
   catch (jthrowable t)
@@ -1475,6 +1572,7 @@ _Jv_JNI_ToReflectedField (JNIEnv *env, jclass cls, jfieldID fieldID,
 {
   try
     {
+      cls = unwrap (cls);
       java::lang::reflect::Field *field = new java::lang::reflect::Field();
       field->declaringClass = cls;
       field->offset = (char*) fieldID - (char *) cls->fields;
@@ -1494,6 +1592,7 @@ _Jv_JNI_FromReflectedField (JNIEnv *, jobject f)
 {
   using namespace java::lang::reflect;
 
+  f = unwrap (f);
   Field *field = reinterpret_cast<Field *> (f);
   return _Jv_FromReflectedField (field);
 }
@@ -1505,6 +1604,7 @@ _Jv_JNI_ToReflectedMethod (JNIEnv *env, jclass klass, jmethodID id,
   using namespace java::lang::reflect;
 
   jobject result = NULL;
+  klass = unwrap (klass);
 
   try
     {
@@ -1536,12 +1636,44 @@ static jmethodID
 _Jv_JNI_FromReflectedMethod (JNIEnv *, jobject method)
 {
   using namespace java::lang::reflect;
+  method = unwrap (method);
   if (Method::class$.isInstance (method))
     return _Jv_FromReflectedMethod (reinterpret_cast<Method *> (method));
   return
     _Jv_FromReflectedConstructor (reinterpret_cast<Constructor *> (method));
 }
 
+// JDK 1.2.
+jweak
+_Jv_JNI_NewWeakGlobalRef (JNIEnv *env, jobject obj)
+{
+  using namespace gnu::gcj::runtime;
+  JNIWeakRef *ref = NULL;
+
+  try
+    {
+      // This seems weird but I think it is correct.
+      obj = unwrap (obj);
+      ref = new JNIWeakRef (obj);
+      mark_for_gc (ref, global_ref_table);
+    }
+  catch (jthrowable t)
+    {
+      env->ex = t;
+    }
+
+  return reinterpret_cast<jweak> (ref);
+}
+
+void
+_Jv_JNI_DeleteWeakGlobalRef (JNIEnv *, jweak obj)
+{
+  using namespace gnu::gcj::runtime;
+  JNIWeakRef *ref = reinterpret_cast<JNIWeakRef *> (obj);
+  unmark_for_gc (ref, global_ref_table);
+  ref->clear ();
+}
+
 \f
 
 // Hash table of native methods.
@@ -2218,7 +2350,6 @@ _Jv_JNI_GetJavaVM (JNIEnv *, JavaVM **vm)
 
 \f
 
-#define NOT_IMPL NULL
 #define RESERVED NULL
 
 struct JNINativeInterface _Jv_JNIFunctions =
@@ -2462,8 +2593,8 @@ struct JNINativeInterface _Jv_JNIFunctions =
   _Jv_JNI_GetStringCritical,               // GetStringCritical
   _Jv_JNI_ReleaseStringCritical,           // ReleaseStringCritical
 
-  NOT_IMPL /* newweakglobalref */,
-  NOT_IMPL /* deleteweakglobalref */,
+  _Jv_JNI_NewWeakGlobalRef,                // NewWeakGlobalRef
+  _Jv_JNI_DeleteWeakGlobalRef,             // DeleteWeakGlobalRef
 
   _Jv_JNI_ExceptionCheck
 };