summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Tromey <tromey@cygnus.com>2000-02-18 21:22:06 +0000
committerTom Tromey <tromey@gcc.gnu.org>2000-02-18 21:22:06 +0000
commit8ade47715eddea64a001e982da714b791e5e6e44 (patch)
tree6637b7627b283f1bc28869d88ab6c8eecc6e22fc
parent31e890f0f32d3132d0519f640203060a9fc0f0a6 (diff)
downloadgcc-8ade47715eddea64a001e982da714b791e5e6e44.tar.gz
jvm.h (_Jv_GetJavaVM): Declare.
* 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
-rw-r--r--libjava/ChangeLog17
-rw-r--r--libjava/include/java-interp.h21
-rw-r--r--libjava/include/jvm.h3
-rw-r--r--libjava/java/lang/natRuntime.cc9
-rw-r--r--libjava/jni.cc99
5 files changed, 135 insertions, 14 deletions
diff --git a/libjava/ChangeLog b/libjava/ChangeLog
index f5e4fb787d1..fb2e46a48cf 100644
--- a/libjava/ChangeLog
+++ b/libjava/ChangeLog
@@ -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.
diff --git a/libjava/include/java-interp.h b/libjava/include/java-interp.h
index a0ca3470de8..3f33d54bb55 100644
--- a/libjava/include/java-interp.h
+++ b/libjava/include/java-interp.h
@@ -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 */
diff --git a/libjava/include/jvm.h b/libjava/include/jvm.h
index d21da78923a..40a0c2a9830 100644
--- a/libjava/include/jvm.h
+++ b/libjava/include/jvm.h
@@ -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__ */
diff --git a/libjava/java/lang/natRuntime.cc b/libjava/java/lang/natRuntime.cc
index b9b9c57365a..eb1d477002a 100644
--- a/libjava/java/lang/natRuntime.cc
+++ b/libjava/java/lang/natRuntime.cc
@@ -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.
diff --git a/libjava/jni.cc b/libjava/jni.cc
index 51b7b19f5a2..42c0d07a099 100644
--- a/libjava/jni.cc
+++ b/libjava/jni.cc
@@ -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;
+}
+
#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;
}
@@ -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,