OSDN Git Service

* gcc_release: Add /usr/local/bin to path when local.
[pf3gnuchains/gcc-fork.git] / libjava / jni.cc
index be45cb2..dbe1d1f 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>
@@ -48,6 +49,8 @@ details.  */
 #include <java-interp.h>
 #include <java-threads.h>
 
+using namespace gcj;
+
 // This enum is used to select different template instantiations in
 // the invocation code.
 enum invocation_type
@@ -110,19 +113,19 @@ jvmpiEnableEvent (jint event_type, void *)
     case JVMPI_EVENT_OBJECT_ALLOC:
       _Jv_JVMPI_Notify_OBJECT_ALLOC = _Jv_JVMPI_Interface.NotifyEvent;
       break;
-      
+
     case JVMPI_EVENT_THREAD_START:
       _Jv_JVMPI_Notify_THREAD_START = _Jv_JVMPI_Interface.NotifyEvent;
       break;
-      
+
     case JVMPI_EVENT_THREAD_END:
       _Jv_JVMPI_Notify_THREAD_END = _Jv_JVMPI_Interface.NotifyEvent;
       break;
-      
+
     default:
       return JVMPI_NOT_AVAILABLE;
     }
-  
+
   return JVMPI_SUCCESS;
 }
 
@@ -134,11 +137,11 @@ jvmpiDisableEvent (jint event_type, void *)
     case JVMPI_EVENT_OBJECT_ALLOC:
       _Jv_JVMPI_Notify_OBJECT_ALLOC = NULL;
       break;
-      
+
     default:
       return JVMPI_NOT_AVAILABLE;
     }
-  
+
   return JVMPI_SUCCESS;
 }
 #endif
@@ -192,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;
 }
@@ -204,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);
 }
 
@@ -212,9 +242,12 @@ _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)
+      for (int i = 0; i < frame->size; ++i)
        {
          if (frame->vec[i] == obj)
            {
@@ -275,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;
@@ -317,7 +353,7 @@ _Jv_JNI_PopLocalFrame (JNIEnv *env, jobject result, int stop)
 
   bool done = false;
   while (rf != NULL && ! done)
-    {  
+    {
       for (int i = 0; i < rf->size; ++i)
        if (rf->vec[i] != NULL)
          unmark_for_gc (rf->vec[i], local_ref_table);
@@ -396,11 +432,13 @@ _Jv_JNI_GetVersion (JNIEnv *)
 }
 
 static jclass
-_Jv_JNI_DefineClass (JNIEnv *env, jobject loader, 
+_Jv_JNI_DefineClass (JNIEnv *env, jobject loader,
                     const jbyte *buf, jsize bufLen)
 {
   try
     {
+      loader = unwrap (loader);
+
       jbyteArray bytes = JvNewByteArray (bufLen);
 
       jbyte *elts = elements (bytes);
@@ -458,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;
@@ -481,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;
@@ -548,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
@@ -559,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 ();
@@ -579,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());
 }
@@ -586,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
@@ -602,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);
@@ -656,9 +699,9 @@ array_from_valist (jvalue *values, JArray<jclass> *arg_types, va_list vargs)
   for (int i = 0; i < arg_types->length; ++i)
     {
       if (arg_elts[i] == JvPrimClass (byte))
-       values[i].b = va_arg (vargs, jbyte);
+       values[i].b = (jbyte) va_arg (vargs, int);
       else if (arg_elts[i] == JvPrimClass (short))
-       values[i].s = va_arg (vargs, jshort);
+       values[i].s = (jshort) va_arg (vargs, int);
       else if (arg_elts[i] == JvPrimClass (int))
        values[i].i = va_arg (vargs, jint);
       else if (arg_elts[i] == JvPrimClass (long))
@@ -668,13 +711,13 @@ array_from_valist (jvalue *values, JArray<jclass> *arg_types, va_list vargs)
       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);
+       values[i].z = (jboolean) va_arg (vargs, int);
       else if (arg_elts[i] == JvPrimClass (char))
-       values[i].c = va_arg (vargs, jchar);
+       values[i].c = (jchar) va_arg (vargs, int);
       else
        {
          // An object.
-         values[i].l = va_arg (vargs, jobject);
+         values[i].l = unwrap (va_arg (vargs, jobject));
        }
     }
 }
@@ -686,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);
 
@@ -746,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);
 
@@ -763,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;
@@ -787,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);
 
@@ -850,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);
@@ -927,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);
 }
@@ -942,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,
@@ -960,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);
 }
@@ -1044,8 +1118,9 @@ _Jv_JNI_NewObjectA (JNIEnv *env, jclass klass, jmethodID id,
 
 template<typename T>
 static T
-_Jv_JNI_GetField (JNIEnv *env, jobject obj, jfieldID field) 
+_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);
@@ -1055,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;
@@ -1067,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);
@@ -1131,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;
 }
@@ -1153,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)
@@ -1169,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
@@ -1190,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
     {
@@ -1225,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 ())
@@ -1246,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 ())
     {
@@ -1265,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;
@@ -1280,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
@@ -1289,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);
     }
@@ -1302,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]);
 }
 
@@ -1312,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;
@@ -1342,6 +1434,7 @@ static T *
 _Jv_JNI_GetPrimitiveArrayElements (JNIEnv *, JArray<T> *array,
                                   jboolean *isCopy)
 {
+  array = unwrap (array);
   T *elts = elements (array);
   if (isCopy)
     {
@@ -1357,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.
@@ -1369,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)
@@ -1393,9 +1489,11 @@ _Jv_JNI_GetPrimitiveArrayRegion (JNIEnv *env, JArray<T> *array,
 
 template<typename T>
 static void
-_Jv_JNI_SetPrimitiveArrayRegion (JNIEnv *env, JArray<T> *array, 
+_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)
@@ -1421,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 ());
@@ -1441,7 +1540,7 @@ _Jv_JNI_MonitorEnter (JNIEnv *env, jobject obj)
 {
   try
     {
-      _Jv_MonitorEnter (obj);
+      _Jv_MonitorEnter (unwrap (obj));
       return 0;
     }
   catch (jthrowable t)
@@ -1456,7 +1555,7 @@ _Jv_JNI_MonitorExit (JNIEnv *env, jobject obj)
 {
   try
     {
-      _Jv_MonitorExit (obj);
+      _Jv_MonitorExit (unwrap (obj));
       return 0;
     }
   catch (jthrowable t)
@@ -1473,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;
@@ -1492,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);
 }
@@ -1502,10 +1603,8 @@ _Jv_JNI_ToReflectedMethod (JNIEnv *env, jclass klass, jmethodID id,
 {
   using namespace java::lang::reflect;
 
-  // FIXME.
-  static _Jv_Utf8Const *init_name = _Jv_makeUtf8Const ("<init>", 6);
-
   jobject result = NULL;
+  klass = unwrap (klass);
 
   try
     {
@@ -1537,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.
@@ -2109,6 +2240,9 @@ jint
 JNI_CreateJavaVM (JavaVM **vm, void **penv, void *args)
 {
   JvAssert (! the_vm);
+
+  _Jv_CreateJavaVM (NULL);
+
   // FIXME: synchronize
   JavaVM *nvm = (JavaVM *) _Jv_MallocUnchecked (sizeof (JavaVM));
   if (nvm == NULL)
@@ -2164,8 +2298,6 @@ JNI_CreateJavaVM (JavaVM **vm, void **penv, void *args)
   the_vm = nvm;
   *vm = the_vm;
 
-  _Jv_JNI_Init();
-
   return 0;
 }
 
@@ -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
 };