jvm.h (_Jv_GetJavaVM): Declare.
authorTom Tromey <tromey@cygnus.com>
Fri, 18 Feb 2000 21:22:06 +0000 (21:22 +0000)
committerTom Tromey <tromey@gcc.gnu.org>
Fri, 18 Feb 2000 21:22:06 +0000 (21:22 +0000)
* include/jvm.h (_Jv_GetJavaVM): Declare.
* include/java-interp.h (_Jv_GetFirstMethod): New function.
(_Jv_MethodBase::get_method): New method.
(_Jv_JNIMethod::set_function): New method.
* jni.cc (_Jv_JNI_UnregisterNatives): New function.
(_Jv_JNI_RegisterNatives): New function.
(_Jv_JNIFunctions): Updated for new functions.
(_Jv_GetJavaVM): New function.
(_Jv_JNI_GetJavaVM): Use it.  Now static.
(_Jv_JNI_AttachCurrentThread): Create a new JNIEnv if this thread
is already a Java thread but does not have a JNIEnv yet.

* java/lang/natRuntime.cc (_load): Pass the JavaVM to the onload
function.

From-SVN: r32056

libjava/ChangeLog
libjava/include/java-interp.h
libjava/include/jvm.h
libjava/java/lang/natRuntime.cc
libjava/jni.cc

index f5e4fb787d1155b157096d9aef9393895e4f9eab..fb2e46a48cfb397dc39da7caddb23d5607325a62 100644 (file)
@@ -1,3 +1,20 @@
+2000-02-18  Tom Tromey  <tromey@cygnus.com>
+
+       * include/jvm.h (_Jv_GetJavaVM): Declare.
+       * include/java-interp.h (_Jv_GetFirstMethod): New function.
+       (_Jv_MethodBase::get_method): New method.
+       (_Jv_JNIMethod::set_function): New method.
+       * jni.cc (_Jv_JNI_UnregisterNatives): New function.
+       (_Jv_JNI_RegisterNatives): New function.
+       (_Jv_JNIFunctions): Updated for new functions.
+       (_Jv_GetJavaVM): New function.
+       (_Jv_JNI_GetJavaVM): Use it.  Now static.
+       (_Jv_JNI_AttachCurrentThread): Create a new JNIEnv if this thread
+       is already a Java thread but does not have a JNIEnv yet.
+
+       * java/lang/natRuntime.cc (_load): Pass the JavaVM to the onload
+       function.
+
 2000-02-17  Tom Tromey  <tromey@cygnus.com>
 
        * gcj/field.h (_Jv_Field::getClass): Don't use JvAssert.
index a0ca3470de8ad587a854fb1d2ef01a74f2044ed1..3f33d54bb555688be1bc0312983dd340edd5f2fe 100644 (file)
@@ -79,6 +79,12 @@ protected:
 
   // Size of raw arguments.
   _Jv_ushort args_raw_size;
+
+public:
+  _Jv_Method *get_method ()
+  {
+    return self;
+  }
 };
 
 class _Jv_InterpMethod : public _Jv_MethodBase
@@ -156,8 +162,16 @@ class _Jv_InterpClass : public java::lang::Class
   friend void  _Jv_PrepareClass(jclass);
   friend void  _Jv_InitField (jobject, jclass, int);
   friend void* _Jv_MarkObj (void *, void *, void *, void *);
+
+  friend _Jv_MethodBase ** _Jv_GetFirstMethod (_Jv_InterpClass *klass);
 };
 
+extern inline _Jv_MethodBase **
+_Jv_GetFirstMethod (_Jv_InterpClass *klass)
+{
+  return klass->interpreted_methods;
+}
+
 struct _Jv_ResolvedMethod {
   jint            stack_item_count;    
   jint            vtable_index;        
@@ -190,6 +204,13 @@ class _Jv_JNIMethod : public _Jv_MethodBase
 
   friend class _Jv_ClassReader;
   friend void _Jv_PrepareClass(jclass);
+
+public:
+  // FIXME: this is ugly.
+  void set_function (void *f)
+  {
+    function = f;
+  }
 };
 
 #endif /* INTERPRETER */
index d21da78923a3e5d61996e55ceb828440bbb71c7f..40a0c2a983005df6d14113928a5a486402d0ab7d 100644 (file)
@@ -211,4 +211,7 @@ extern void _Jv_JNI_Init (void);
 _Jv_JNIEnv *_Jv_GetCurrentJNIEnv ();
 void _Jv_SetCurrentJNIEnv (_Jv_JNIEnv *);
 
+struct _Jv_JavaVM;
+_Jv_JavaVM *_Jv_GetJavaVM ();
+
 #endif /* __JAVA_JVM_H__ */
index b9b9c57365a038d49127965293323f5e0191c872..eb1d477002a0e8bca7b93ff6682c2f1f201bf947 100644 (file)
@@ -135,8 +135,13 @@ java::lang::Runtime::_load (jstring path, jboolean do_search)
   void *onload = lt_dlsym (h, "JNI_OnLoad");
   if (onload != NULL)
     {
-      // FIXME: need invocation API to get JavaVM.
-      jint vers = ((jint (*) (...)) onload) (NULL, NULL);
+      JavaVM *vm = _Jv_GetJavaVM ();
+      if (vm == NULL)
+       {
+         // FIXME: what?
+         return;
+       }
+      jint vers = ((jint (*) (JavaVM *, void *)) onload) (vm, NULL);
       if (vers != JNI_VERSION_1_1 && vers != JNI_VERSION_1_2)
        {
          // FIXME: unload the library.
index 51b7b19f5a2ae53cb1f279aa809561ebae7e7604..42c0d07a0995f2a2090eb589461e0936bf698020 100644 (file)
@@ -1258,6 +1258,63 @@ _Jv_JNI_FromReflectedMethod (JNIEnv *, jobject method)
     _Jv_FromReflectedConstructor (reinterpret_cast<Constructor *> (method));
 }
 
+static jint
+_Jv_JNI_RegisterNatives (JNIEnv *env, jclass k,
+                        const JNINativeMethod *methods,
+                        jint nMethods)
+{
+  // For now, this only matters for interpreted methods.  FIXME.
+  if (! _Jv_IsInterpretedClass (k))
+    {
+      // FIXME: throw exception.
+      return JNI_ERR;
+    }
+  _Jv_InterpClass *klass = reinterpret_cast<_Jv_InterpClass *> (k);
+
+  // Look at each descriptor given us, and find the corresponding
+  // method in the class.
+  for (int j = 0; j < nMethods; ++j)
+    {
+      bool found = false;
+
+      _Jv_MethodBase **imeths = _Jv_GetFirstMethod (klass);
+      for (int i = 0; i < JvNumMethods (klass); ++i)
+       {
+         _Jv_MethodBase *meth = imeths[i];
+         _Jv_Method *self = meth->get_method ();
+
+         if (! strcmp (self->name->data, methods[j].name)
+             && ! strcmp (self->signature->data, methods[j].signature))
+           {
+             if (! (self->accflags
+                    & java::lang::reflect::Modifier::NATIVE))
+               break;
+
+             // Found a match that is native.
+             _Jv_JNIMethod *jmeth = reinterpret_cast<_Jv_JNIMethod *> (meth);
+             jmeth->set_function (methods[i].fnPtr);
+             found = true;
+             break;
+           }
+       }
+
+      if (! found)
+       {
+         jstring m = JvNewStringUTF (methods[j].name);
+         _Jv_JNI_Throw (env, new java::lang::NoSuchMethodError (m));
+         return JNI_ERR;
+       }
+    }
+
+  return JNI_OK;
+}
+
+static jint
+_Jv_JNI_UnregisterNatives (JNIEnv *, jclass)
+{
+  return JNI_ERR;
+}
+
 \f
 
 #ifdef INTERPRETER
@@ -1460,7 +1517,7 @@ _Jv_JNI_AttachCurrentThread (JavaVM *, jstring name, void **penv, void *args)
     }
 
   // Attaching an already-attached thread is a no-op.
-  if (_Jv_ThreadCurrent () != NULL)
+  if (_Jv_GetCurrentJNIEnv () != NULL)
     return 0;
 
   JNIEnv *env = (JNIEnv *) _Jv_MallocUnchecked (sizeof (JNIEnv));
@@ -1480,8 +1537,13 @@ _Jv_JNI_AttachCurrentThread (JavaVM *, jstring name, void **penv, void *args)
     }
   *penv = reinterpret_cast<void *> (env);
 
-  java::lang::Thread *t = new gnu::gcj::jni::NativeThread (group, name);
-  t = t;                       // Avoid compiler warning.  Eww.
+  // This thread might already be a Java thread -- this function might
+  // have been called simply to set the new JNIEnv.
+  if (_Jv_ThreadCurrent () == NULL)
+    {
+      java::lang::Thread *t = new gnu::gcj::jni::NativeThread (group, name);
+      t = t;                   // Avoid compiler warning.  Eww.
+    }
   _Jv_SetCurrentJNIEnv (env);
 
   return 0;
@@ -1655,21 +1717,34 @@ JNI_GetCreatedJavaVMs (JavaVM **vm_buffer, jsize buf_len, jsize *n_vms)
   return 0;
 }
 
-jint
-_Jv_JNI_GetJavaVM (JNIEnv *, JavaVM **vm)
+JavaVM *
+_Jv_GetJavaVM ()
 {
   // FIXME: synchronize
   if (! the_vm)
     {
       JavaVM *nvm = (JavaVM *) _Jv_MallocUnchecked (sizeof (JavaVM));
-      if (nvm == NULL)
-       return JNI_ERR;
-      nvm->functions = &_Jv_JNI_InvokeFunctions;
+      if (nvm != NULL)
+       nvm->functions = &_Jv_JNI_InvokeFunctions;
       the_vm = nvm;
     }
 
-  *vm = the_vm;
-  return 0;
+  // If this is a Java thread, we want to make sure it has an
+  // associated JNIEnv.
+  if (_Jv_ThreadCurrent () != NULL)
+    {
+      void *ignore;
+      _Jv_JNI_AttachCurrentThread (the_vm, &ignore, NULL);
+    }
+
+  return the_vm;
+}
+
+static jint
+_Jv_JNI_GetJavaVM (JNIEnv *, JavaVM **vm)
+{
+  *vm = _Jv_GetJavaVM ();
+  return *vm == NULL ? JNI_ERR : JNI_OK;
 }
 
 \f
@@ -1904,8 +1979,8 @@ struct JNINativeInterface _Jv_JNIFunctions =
   _Jv_JNI_SetPrimitiveArrayRegion,
   _Jv_JNI_SetPrimitiveArrayRegion,
   _Jv_JNI_SetPrimitiveArrayRegion,
-  NOT_IMPL /* RegisterNatives */,
-  NOT_IMPL /* UnregisterNatives */,
+  _Jv_JNI_RegisterNatives,
+  _Jv_JNI_UnregisterNatives,
   _Jv_JNI_MonitorEnter,
   _Jv_JNI_MonitorExit,
   _Jv_JNI_GetJavaVM,