summaryrefslogtreecommitdiff
path: root/libjava
diff options
context:
space:
mode:
authortromey <tromey@138bc75d-0d04-0410-961f-82ee72b054a4>2000-02-10 20:31:48 +0000
committertromey <tromey@138bc75d-0d04-0410-961f-82ee72b054a4>2000-02-10 20:31:48 +0000
commitbf1967d63c238862df52d7823dbfd4abc9d5c647 (patch)
tree893852baae8ef6aa653f36d94ed11d6728aa30ea /libjava
parent083909e35fea95ba09493d725327722f279eaf14 (diff)
downloadgcc-bf1967d63c238862df52d7823dbfd4abc9d5c647.tar.gz
* gnu/gcj/jni/natNativeThread.cc: New file.
* gnu/gcj/jni/NativeThread.java: New file. * java/lang/Thread.java (data): Now a RawData. * include/jvm.h (_Jv_GetCurrentJNIEnv, _Jv_SetCurrentJNIEnv): Declare. * Makefile.in: Rebuilt. * Makefile.am (java/lang/Thread.h): New target. (ordinary_java_source_files): Added NativeThread.java. (nat_source_files): Added natNativeThread.cc. * java/lang/natThread.cc: Include <jni.h> (struct natThread): Added `jni_env' field. (_Jv_GetCurrentJNIEnv): New function. (_Jv_SetCurrentJNIEnv): Likewise. (initialize_native): Initialize jni_env. Include RawData.h. * jni.cc (ThreadGroupClass): New define. (_Jv_JNI_InvokeFunctions): New structure. (JNI_GetCreatedJavaVMs): New function. (the_vm): New global. (JNI_GetDefaultJavaVMInitArgs): New function. Include NativeThread.h. (NativeThreadClass): New define. (_Jv_JNI_EnsureLocalCapacity): Return JNI_ERR, not -1. (_Jv_JNI_DestroyJavaVM): New function. (_Jv_JNI_AttachCurrentThread): New function. (_Jv_JNI_DetachCurrentThread): New function. (_Jv_JNI_GetEnv): New function. (JNI_CreateJavaVM): New function. (_Jv_JNI_GetJavaVM): New function. (_Jv_JNIFunctions): Added entry for GetJavaVM. * include/jni.h (JavaVMAttachArgs): New structure. (JNI_EDETACHED): New define. (JNI_EVERSION): Likewise. (JavaVM): Define properly. (struct JNIInvokeInterface): New structure. (class _Jv_JavaVM): New class. (JNI_OnLoad, JNI_OnUnload): Declare. (JNI_GetDefaultJavaVMInitArgs, JNI_CreateJavaVM, JNI_GetCreatedJavaVMs): Declare. (JavaVMInitArgs): New typedef. (JavaVMOption): Likewise. (JNI_ERR): New define. (JNI_OK): Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@31901 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libjava')
-rw-r--r--libjava/ChangeLog46
-rw-r--r--libjava/Makefile.am12
-rw-r--r--libjava/Makefile.in75
-rw-r--r--libjava/gnu/gcj/jni/NativeThread.java28
-rw-r--r--libjava/gnu/gcj/jni/natNativeThread.cc24
-rw-r--r--libjava/include/jni.h101
-rw-r--r--libjava/include/jvm.h4
-rw-r--r--libjava/java/lang/Thread.java11
-rw-r--r--libjava/java/lang/natThread.cc30
-rw-r--r--libjava/jni.cc259
10 files changed, 560 insertions, 30 deletions
diff --git a/libjava/ChangeLog b/libjava/ChangeLog
index 159853c6b04..91485fc98b0 100644
--- a/libjava/ChangeLog
+++ b/libjava/ChangeLog
@@ -1,3 +1,49 @@
+2000-02-10 Tom Tromey <tromey@cygnus.com>
+
+ * gnu/gcj/jni/natNativeThread.cc: New file.
+ * gnu/gcj/jni/NativeThread.java: New file.
+ * java/lang/Thread.java (data): Now a RawData.
+ * include/jvm.h (_Jv_GetCurrentJNIEnv, _Jv_SetCurrentJNIEnv):
+ Declare.
+ * Makefile.in: Rebuilt.
+ * Makefile.am (java/lang/Thread.h): New target.
+ (ordinary_java_source_files): Added NativeThread.java.
+ (nat_source_files): Added natNativeThread.cc.
+ * java/lang/natThread.cc: Include <jni.h>
+ (struct natThread): Added `jni_env' field.
+ (_Jv_GetCurrentJNIEnv): New function.
+ (_Jv_SetCurrentJNIEnv): Likewise.
+ (initialize_native): Initialize jni_env.
+ Include RawData.h.
+ * jni.cc (ThreadGroupClass): New define.
+ (_Jv_JNI_InvokeFunctions): New structure.
+ (JNI_GetCreatedJavaVMs): New function.
+ (the_vm): New global.
+ (JNI_GetDefaultJavaVMInitArgs): New function.
+ Include NativeThread.h.
+ (NativeThreadClass): New define.
+ (_Jv_JNI_EnsureLocalCapacity): Return JNI_ERR, not -1.
+ (_Jv_JNI_DestroyJavaVM): New function.
+ (_Jv_JNI_AttachCurrentThread): New function.
+ (_Jv_JNI_DetachCurrentThread): New function.
+ (_Jv_JNI_GetEnv): New function.
+ (JNI_CreateJavaVM): New function.
+ (_Jv_JNI_GetJavaVM): New function.
+ (_Jv_JNIFunctions): Added entry for GetJavaVM.
+ * include/jni.h (JavaVMAttachArgs): New structure.
+ (JNI_EDETACHED): New define.
+ (JNI_EVERSION): Likewise.
+ (JavaVM): Define properly.
+ (struct JNIInvokeInterface): New structure.
+ (class _Jv_JavaVM): New class.
+ (JNI_OnLoad, JNI_OnUnload): Declare.
+ (JNI_GetDefaultJavaVMInitArgs, JNI_CreateJavaVM,
+ JNI_GetCreatedJavaVMs): Declare.
+ (JavaVMInitArgs): New typedef.
+ (JavaVMOption): Likewise.
+ (JNI_ERR): New define.
+ (JNI_OK): Likewise.
+
2000-02-10 Andrew Haley <aph@cygnus.com>
* interpret.cc: Don't include fdlibm.h.
diff --git a/libjava/Makefile.am b/libjava/Makefile.am
index 4abbeab4278..c22a2c8b99c 100644
--- a/libjava/Makefile.am
+++ b/libjava/Makefile.am
@@ -221,6 +221,16 @@ java/lang/FirstThread.h: java/lang/FirstThread.class libgcj.zip
-friend 'void _Jv_RunMain (const char*, int, const char **);' \
$(basename $<)
+java/lang/Thread.h: java/lang/Thread.class libgcj.zip
+ $(GCJH) -classpath $(top_builddir) \
+ -prepend 'class _Jv_JNIEnv;' \
+## Eww.
+ -prepend 'extern "Java" { namespace gnu { namespace gcj { namespace jni { class NativeThread; } } } };' \
+ -friend '_Jv_JNIEnv * _Jv_GetCurrentJNIEnv ();' \
+ -friend 'void _Jv_SetCurrentJNIEnv (_Jv_JNIEnv *env);' \
+ -friend 'class gnu::gcj::jni::NativeThread;' \
+ $(basename $<)
+
java/lang/String.h: java/lang/String.class libgcj.zip
$(GCJH) -classpath $(top_builddir) \
-friend 'jchar* _Jv_GetStringChars (jstring str);' \
@@ -512,6 +522,7 @@ built_java_source_files = java/lang/ConcreteProcess.java
## convert_source_files. If the .java file has a hand-maintained
## header, please list it in special_java_source_files.
ordinary_java_source_files = $(convert_source_files) \
+gnu/gcj/jni/NativeThread.java \
gnu/gcj/runtime/MethodInvocation.java \
gnu/gcj/runtime/VMClassLoader.java \
gnu/gcj/text/BaseBreakIterator.java \
@@ -796,6 +807,7 @@ gnu/gcj/convert/natInput_EUCJIS.cc \
gnu/gcj/convert/natInput_SJIS.cc \
gnu/gcj/convert/natOutput_EUCJIS.cc \
gnu/gcj/convert/natOutput_SJIS.cc \
+gnu/gcj/jni/natNativeThread.cc \
java/io/natFile.cc \
java/io/natFileDescriptor.cc \
java/lang/natCharacter.cc \
diff --git a/libjava/Makefile.in b/libjava/Makefile.in
index bf0ffec0203..dada6e9f028 100644
--- a/libjava/Makefile.in
+++ b/libjava/Makefile.in
@@ -326,6 +326,7 @@ java/awt/peer/WindowPeer.java
built_java_source_files = java/lang/ConcreteProcess.java
ordinary_java_source_files = $(convert_source_files) \
+gnu/gcj/jni/NativeThread.java \
gnu/gcj/runtime/MethodInvocation.java \
gnu/gcj/runtime/VMClassLoader.java \
gnu/gcj/text/BaseBreakIterator.java \
@@ -610,6 +611,7 @@ gnu/gcj/convert/natInput_EUCJIS.cc \
gnu/gcj/convert/natInput_SJIS.cc \
gnu/gcj/convert/natOutput_EUCJIS.cc \
gnu/gcj/convert/natOutput_SJIS.cc \
+gnu/gcj/jni/natNativeThread.cc \
java/io/natFile.cc \
java/io/natFileDescriptor.cc \
java/lang/natCharacter.cc \
@@ -730,7 +732,8 @@ LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
DATA = $(data_DATA) $(toolexeclib_DATA)
DIST_COMMON = README COPYING.LIB ChangeLog Makefile.am Makefile.in NEWS \
-THANKS acinclude.m4 aclocal.m4 configure configure.in libgcj.spec.in
+THANKS acconfig.h acinclude.m4 aclocal.m4 configure configure.in \
+include/config.h.in include/stamp-h.in libgcj.spec.in
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
@@ -752,8 +755,8 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \
.deps/gnu/gcj/convert/Output_JavaSrc.P \
.deps/gnu/gcj/convert/Output_SJIS.P .deps/gnu/gcj/convert/Output_UTF8.P \
.deps/gnu/gcj/convert/Output_iconv.P \
-.deps/gnu/gcj/convert/UnicodeToBytes.P .deps/gnu/gcj/math/MPN.P \
-.deps/gnu/gcj/protocol/file/Connection.P \
+.deps/gnu/gcj/convert/UnicodeToBytes.P .deps/gnu/gcj/jni/NativeThread.P \
+.deps/gnu/gcj/math/MPN.P .deps/gnu/gcj/protocol/file/Connection.P \
.deps/gnu/gcj/protocol/file/Handler.P \
.deps/gnu/gcj/protocol/http/Connection.P \
.deps/gnu/gcj/protocol/http/Handler.P \
@@ -955,6 +958,34 @@ config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
$(SHELL) ./config.status --recheck
$(srcdir)/configure: @MAINTAINER_MODE_TRUE@$(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES)
cd $(srcdir) && $(AUTOCONF)
+
+include/config.h: include/stamp-h
+ @if test ! -f $@; then \
+ rm -f include/stamp-h; \
+ $(MAKE) include/stamp-h; \
+ else :; fi
+include/stamp-h: $(srcdir)/include/config.h.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES= CONFIG_HEADERS=include/config.h \
+ $(SHELL) ./config.status
+ @echo timestamp > include/stamp-h 2> /dev/null
+$(srcdir)/include/config.h.in: @MAINTAINER_MODE_TRUE@$(srcdir)/include/stamp-h.in
+ @if test ! -f $@; then \
+ rm -f $(srcdir)/include/stamp-h.in; \
+ $(MAKE) $(srcdir)/include/stamp-h.in; \
+ else :; fi
+$(srcdir)/include/stamp-h.in: $(top_srcdir)/configure.in $(ACLOCAL_M4) acconfig.h
+ cd $(top_srcdir) && $(AUTOHEADER)
+ @echo timestamp > $(srcdir)/include/stamp-h.in 2> /dev/null
+
+mostlyclean-hdr:
+
+clean-hdr:
+
+distclean-hdr:
+ -rm -f include/config.h
+
+maintainer-clean-hdr:
libgcj.spec: $(top_builddir)/config.status libgcj.spec.in
cd $(top_builddir) && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
@@ -1393,31 +1424,33 @@ distclean-generic:
-rm -f config.cache config.log stamp-h stamp-h[0-9]*
maintainer-clean-generic:
-mostlyclean-am: mostlyclean-toolexeclibLIBRARIES mostlyclean-compile \
- mostlyclean-libtool mostlyclean-toolexeclibLTLIBRARIES \
+mostlyclean-am: mostlyclean-hdr mostlyclean-toolexeclibLIBRARIES \
+ mostlyclean-compile mostlyclean-libtool \
+ mostlyclean-toolexeclibLTLIBRARIES \
mostlyclean-binPROGRAMS mostlyclean-noinstPROGRAMS \
mostlyclean-tags mostlyclean-depend mostlyclean-generic
mostlyclean: mostlyclean-recursive
-clean-am: clean-toolexeclibLIBRARIES clean-compile clean-libtool \
- clean-toolexeclibLTLIBRARIES clean-binPROGRAMS \
- clean-noinstPROGRAMS clean-tags clean-depend \
- clean-generic mostlyclean-am clean-local
+clean-am: clean-hdr clean-toolexeclibLIBRARIES clean-compile \
+ clean-libtool clean-toolexeclibLTLIBRARIES \
+ clean-binPROGRAMS clean-noinstPROGRAMS clean-tags \
+ clean-depend clean-generic mostlyclean-am clean-local
clean: clean-recursive
-distclean-am: distclean-toolexeclibLIBRARIES distclean-compile \
- distclean-libtool distclean-toolexeclibLTLIBRARIES \
- distclean-binPROGRAMS distclean-noinstPROGRAMS \
- distclean-tags distclean-depend distclean-generic \
- clean-am
+distclean-am: distclean-hdr distclean-toolexeclibLIBRARIES \
+ distclean-compile distclean-libtool \
+ distclean-toolexeclibLTLIBRARIES distclean-binPROGRAMS \
+ distclean-noinstPROGRAMS distclean-tags \
+ distclean-depend distclean-generic clean-am
-rm -f libtool
distclean: distclean-recursive
-rm -f config.status
-maintainer-clean-am: maintainer-clean-toolexeclibLIBRARIES \
+maintainer-clean-am: maintainer-clean-hdr \
+ maintainer-clean-toolexeclibLIBRARIES \
maintainer-clean-compile maintainer-clean-libtool \
maintainer-clean-toolexeclibLTLIBRARIES \
maintainer-clean-binPROGRAMS \
@@ -1430,7 +1463,8 @@ maintainer-clean-am: maintainer-clean-toolexeclibLIBRARIES \
maintainer-clean: maintainer-clean-recursive
-rm -f config.status
-.PHONY: mostlyclean-toolexeclibLIBRARIES distclean-toolexeclibLIBRARIES \
+.PHONY: mostlyclean-hdr distclean-hdr clean-hdr maintainer-clean-hdr \
+mostlyclean-toolexeclibLIBRARIES distclean-toolexeclibLIBRARIES \
clean-toolexeclibLIBRARIES maintainer-clean-toolexeclibLIBRARIES \
uninstall-toolexeclibLIBRARIES install-toolexeclibLIBRARIES \
mostlyclean-compile distclean-compile clean-compile \
@@ -1514,6 +1548,15 @@ java/lang/FirstThread.h: java/lang/FirstThread.class libgcj.zip
-friend 'void _Jv_RunMain (const char*, int, const char **);' \
$(basename $<)
+java/lang/Thread.h: java/lang/Thread.class libgcj.zip
+ $(GCJH) -classpath $(top_builddir) \
+ -prepend 'class _Jv_JNIEnv;' \
+ -prepend 'extern "Java" { namespace gnu { namespace gcj { namespace jni { class NativeThread; } } } };' \
+ -friend '_Jv_JNIEnv * _Jv_GetCurrentJNIEnv ();' \
+ -friend 'void _Jv_SetCurrentJNIEnv (_Jv_JNIEnv *env);' \
+ -friend 'class gnu::gcj::jni::NativeThread;' \
+ $(basename $<)
+
java/lang/String.h: java/lang/String.class libgcj.zip
$(GCJH) -classpath $(top_builddir) \
-friend 'jchar* _Jv_GetStringChars (jstring str);' \
diff --git a/libjava/gnu/gcj/jni/NativeThread.java b/libjava/gnu/gcj/jni/NativeThread.java
new file mode 100644
index 00000000000..9ed6d89cfac
--- /dev/null
+++ b/libjava/gnu/gcj/jni/NativeThread.java
@@ -0,0 +1,28 @@
+// NativeThread.java - Wrapper for attached user threads.
+
+/* Copyright (C) 1998, 1999, 2000 Red Hat, Inc.
+
+ 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.jni;
+
+/**
+ * @author Tom Tromey <tromey@cygnus.com>
+ * @date February 9, 2000
+ */
+
+public class NativeThread extends Thread
+{
+ public NativeThread (ThreadGroup g, String name)
+ {
+ super (g, null, name);
+ alive_flag = true;
+ }
+
+ // Call this to mark the thread as finished.
+ public native void finish ();
+}
diff --git a/libjava/gnu/gcj/jni/natNativeThread.cc b/libjava/gnu/gcj/jni/natNativeThread.cc
new file mode 100644
index 00000000000..b26c95dba94
--- /dev/null
+++ b/libjava/gnu/gcj/jni/natNativeThread.cc
@@ -0,0 +1,24 @@
+// natNativeThread.cc - Native side of attached threads.
+
+/* Copyright (C) 1998, 1999, 2000 Red Hat, Inc.
+
+ 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. */
+
+// Written by Tom Tromey <tromey@cygnus.com>
+
+#include <config.h>
+
+#include <gcj/cni.h>
+#include <jvm.h>
+#include <gnu/gcj/jni/NativeThread.h>
+#include <java/lang/Thread.h>
+
+void
+gnu::gcj::jni::NativeThread::finish ()
+{
+ finish_ ();
+}
diff --git a/libjava/include/jni.h b/libjava/include/jni.h
index fa2fddc5e0e..35477797f40 100644
--- a/libjava/include/jni.h
+++ b/libjava/include/jni.h
@@ -23,6 +23,7 @@ details. */
#include <gcj/javaprims.h>
typedef struct _Jv_JNIEnv JNIEnv;
+typedef struct _Jv_JavaVM JavaVM;
#define JNI_TRUE true
#define JNI_FALSE false
@@ -59,6 +60,7 @@ typedef void *jfieldID;
typedef void *jmethodID;
typedef const struct JNINativeInterface *JNIEnv;
+typedef const struct JNIInvokeInterface *JavaVM;
#define JNI_TRUE 1
#define JNI_TRUE 0
@@ -76,6 +78,32 @@ typedef jobject jweak;
#define JNI_COMMIT 1
#define JNI_ABORT 2
+/* Error codes */
+#define JNI_OK 0
+#define JNI_ERR -1
+#define JNI_EDETACHED -2
+#define JNI_EVERSION -3
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+/* These functions might be defined in libraries which we load; the
+ JNI implementation calls them at the appropriate times. */
+extern jint JNI_OnLoad (JavaVM *, void *);
+extern void JNI_OnUnload (JavaVM *, void *);
+
+/* These functions are called by user code to start using the
+ invocation API. */
+extern jint JNI_GetDefaultJavaVMInitArgs (void *);
+extern jint JNI_CreateJavaVM (JavaVM **, void **, void *);
+extern jint JNI_GetCreatedJavaVMs(JavaVM **, jsize, jsize *);
+
+#ifdef __cplusplus
+};
+#endif /* __cplusplus */
+
typedef union jvalue
{
jboolean z;
@@ -99,9 +127,6 @@ typedef struct
void *fnPtr; /* Sigh. */
} JNINativeMethod;
-/* FIXME: this is just a placeholder. */
-typedef int JavaVM;
-
struct JNINativeInterface
{
_Jv_func reserved0;
@@ -1402,4 +1427,74 @@ public:
};
#endif /* __cplusplus */
+/*
+ * Invocation API.
+ */
+
+struct JNIInvokeInterface
+{
+ _Jv_func reserved0;
+ _Jv_func reserved1;
+ _Jv_func reserved2;
+
+ jint (*DestroyJavaVM) (JavaVM *);
+ jint (*AttachCurrentThread) (JavaVM *, void **, void *);
+ jint (*DetachCurrentThread) (JavaVM *);
+ jint (*GetEnv) (JavaVM *, void **, jint);
+};
+
+#ifdef __cplusplus
+
+class _Jv_JavaVM
+{
+public:
+ const struct JNIInvokeInterface *functions;
+
+private:
+ /* FIXME: other fields. */
+
+public:
+ jint DestroyJavaVM ()
+ { return functions->DestroyJavaVM (this); }
+
+ jint AttachCurrentThread (void **penv, void *args)
+ { return functions->AttachCurrentThread (this, penv, args); }
+
+ jint DetachCurrentThread ()
+ { return functions->DetachCurrentThread (this); }
+
+ jint GetEnv (void **penv, jint version)
+ { return functions->GetEnv (this, penv, version); }
+};
+#endif /* __cplusplus */
+
+typedef struct JavaVMAttachArgs
+{
+ jint version; /* Must be JNI_VERSION_1_2. */
+ char *name; /* The name of the thread (or NULL). */
+ jobject group; /* Global ref of a ThreadGroup object
+ (or NULL). */
+} JavaVMAttachArgs;
+
+typedef struct JavaVMOption
+{
+ char *optionString;
+ void *extraInfo;
+} JavaVMOption;
+
+typedef struct JavaVMInitArgs
+{
+ /* Must be JNI_VERSION_1_2. */
+ jint version;
+
+ /* Number of options. */
+ jint nOptions;
+
+ /* Options to the VM. */
+ JavaVMOption *options;
+
+ /* Whether we should ignore unrecognized options. */
+ jboolean ignoreUnrecognized;
+} JavaVMInitArgs;
+
#endif /* __GCJ_JNI_H__ */
diff --git a/libjava/include/jvm.h b/libjava/include/jvm.h
index 325fe939095..d21da78923a 100644
--- a/libjava/include/jvm.h
+++ b/libjava/include/jvm.h
@@ -207,4 +207,8 @@ void *_Jv_FindSymbolInExecutable (const char *);
/* Initialize JNI. */
extern void _Jv_JNI_Init (void);
+/* Get or set the per-thread JNIEnv used by the invocation API. */
+_Jv_JNIEnv *_Jv_GetCurrentJNIEnv ();
+void _Jv_SetCurrentJNIEnv (_Jv_JNIEnv *);
+
#endif /* __JAVA_JVM_H__ */
diff --git a/libjava/java/lang/Thread.java b/libjava/java/lang/Thread.java
index 34921677c8a..7dbabcf56c5 100644
--- a/libjava/java/lang/Thread.java
+++ b/libjava/java/lang/Thread.java
@@ -1,6 +1,6 @@
// Thread.java - Thread class.
-/* Copyright (C) 1998, 1999 Red Hat, Inc.
+/* Copyright (C) 1998, 1999, 2000 Red Hat, Inc.
This file is part of libgcj.
@@ -10,6 +10,8 @@ details. */
package java.lang;
+import gnu.gcj.RawData;
+
/**
* @author Tom Tromey <tromey@cygnus.com>
* @date August 24, 1998
@@ -297,11 +299,8 @@ public class Thread implements Runnable
private boolean interrupt_flag;
private boolean alive_flag;
- // This is a bit odd. We need a way to represent some data that is
- // manipulated only by the native side of this class. We represent
- // it as a Java object reference. However, it is not actually a
- // Java object.
- private Object data;
+ // Our native data.
+ private RawData data;
// Next thread number to assign.
private static int nextThreadNumber = 0;
diff --git a/libjava/java/lang/natThread.cc b/libjava/java/lang/natThread.cc
index 6870f02c50d..741f2b587e8 100644
--- a/libjava/java/lang/natThread.cc
+++ b/libjava/java/lang/natThread.cc
@@ -1,6 +1,6 @@
// natThread.cc - Native part of Thread class.
-/* Copyright (C) 1998, 1999 Red Hat, Inc.
+/* Copyright (C) 1998, 1999, 2000 Red Hat, Inc.
This file is part of libgcj.
@@ -23,6 +23,9 @@ details. */
#include <java/lang/IllegalThreadStateException.h>
#include <java/lang/InterruptedException.h>
#include <java/lang/NullPointerException.h>
+#include <gnu/gcj/RawData.h>
+
+#include <jni.h>
@@ -40,6 +43,9 @@ struct natThread
// This is private data for the thread system layer.
_Jv_Thread_t *thread;
+ // Each thread has its own JNI object.
+ JNIEnv *jni_env;
+
// All threads waiting to join this thread are linked together and
// waiting on their respective `interrupt' condition variables.
// When this thread exits, it notifies each such thread by
@@ -83,10 +89,13 @@ java::lang::Thread::initialize_native (void)
// own finalizer then we will need to reinitialize this structure at
// any "interesting" point.
natThread *nt = (natThread *) _Jv_AllocBytes (sizeof (natThread));
- data = (jobject) nt;
+ data = reinterpret_cast<gnu::gcj::RawData *> (nt);
_Jv_MutexInit (&nt->interrupt_mutex);
_Jv_CondInit (&nt->interrupt_cond);
_Jv_ThreadInitData (&nt->thread, this);
+ // FIXME: if JNI_ENV is set we will want to free it. It is
+ // malloc()d.
+ nt->jni_env = NULL;
nt->joiner = 0;
nt->next = 0;
}
@@ -324,3 +333,20 @@ java::lang::Thread::yield (void)
{
_Jv_ThreadYield ();
}
+
+JNIEnv *
+_Jv_GetCurrentJNIEnv ()
+{
+ java::lang::Thread *t = _Jv_ThreadCurrent ();
+ if (t == NULL)
+ return NULL;
+ return ((natThread *) t->data)->jni_env;
+}
+
+void
+_Jv_SetCurrentJNIEnv (JNIEnv *env)
+{
+ java::lang::Thread *t = _Jv_ThreadCurrent ();
+ JvAssert (t != NULL);
+ ((natThread *) t->data)->jni_env = env;
+}
diff --git a/libjava/jni.cc b/libjava/jni.cc
index b6728e5ab86..6beb6f7f8a4 100644
--- a/libjava/jni.cc
+++ b/libjava/jni.cc
@@ -36,6 +36,7 @@ details. */
#include <java/lang/OutOfMemoryError.h>
#include <java/util/Hashtable.h>
#include <java/lang/Integer.h>
+#include <gnu/gcj/jni/NativeThread.h>
#include <gcj/method.h>
#include <gcj/field.h>
@@ -51,6 +52,10 @@ extern java::lang::Class ObjectClass;
extern java::lang::Class ThrowableClass;
#define MethodClass _CL_Q44java4lang7reflect6Method
extern java::lang::Class MethodClass;
+#define ThreadGroupClass _CL_Q34java4lang11ThreadGroup
+extern java::lang::Class ThreadGroupClass;
+#define NativeThreadClass _CL_Q43gnu3gcj3jni12NativeThread
+extern java::lang::Class ThreadGroupClass;
// This enum is used to select different template instantiations in
// the invocation code.
@@ -62,8 +67,9 @@ enum invocation_type
constructor
};
-// Forward declaration.
+// Forward declarations.
extern struct JNINativeInterface _Jv_JNIFunctions;
+extern struct JNIInvokeInterface _Jv_JNI_InvokeFunctions;
// Number of slots in the default frame. The VM must allow at least
// 16.
@@ -89,6 +95,9 @@ struct _Jv_JNI_LocalFrame
// This holds a reference count for all local and global references.
static java::util::Hashtable *ref_table;
+// The only VM.
+static JavaVM *the_vm;
+
void
@@ -178,7 +187,7 @@ _Jv_JNI_EnsureLocalCapacity (JNIEnv *env, jint size)
{
// FIXME: exception processing.
env->ex = new java::lang::OutOfMemoryError;
- return -1;
+ return JNI_ERR;
}
frame->marker = true;
@@ -1380,6 +1389,238 @@ _Jv_JNIMethod::call (ffi_cif *cif, void *ret, ffi_raw *args, void *__this)
+//
+// Invocation API.
+//
+
+// An internal helper function.
+static jint
+_Jv_JNI_AttachCurrentThread (JavaVM *, jstring name, void **penv, void *args)
+{
+ JavaVMAttachArgs *attach = reinterpret_cast<JavaVMAttachArgs *> (args);
+ java::lang::ThreadGroup *group = NULL;
+
+ if (attach)
+ {
+ // FIXME: do we really want to support 1.1?
+ if (attach->version != JNI_VERSION_1_2
+ && attach->version != JNI_VERSION_1_1)
+ return JNI_EVERSION;
+
+ JvAssert ((&ThreadGroupClass)->isInstance (attach->group));
+ group = reinterpret_cast<java::lang::ThreadGroup *> (attach->group);
+ }
+
+ // Attaching an already-attached thread is a no-op.
+ if (_Jv_ThreadCurrent () != NULL)
+ return 0;
+
+ // FIXME: NULL return?
+ JNIEnv *env = (JNIEnv *) _Jv_MallocUnchecked (sizeof (JNIEnv));
+ env->p = &_Jv_JNIFunctions;
+ env->ex = NULL;
+ env->klass = NULL;
+ // FIXME: NULL return?
+ env->locals
+ = (_Jv_JNI_LocalFrame *) _Jv_MallocUnchecked (sizeof (_Jv_JNI_LocalFrame)
+ + (FRAME_SIZE
+ * sizeof (jobject)));
+ *penv = reinterpret_cast<void *> (env);
+
+ java::lang::Thread *t = new gnu::gcj::jni::NativeThread (group, name);
+ t = t; // Avoid compiler warning. Eww.
+ _Jv_SetCurrentJNIEnv (env);
+
+ return 0;
+}
+
+// This is the one actually used by JNI.
+static jint
+_Jv_JNI_AttachCurrentThread (JavaVM *vm, void **penv, void *args)
+{
+ return _Jv_JNI_AttachCurrentThread (vm, NULL, penv, args);
+}
+
+static jint
+_Jv_JNI_DestroyJavaVM (JavaVM *vm)
+{
+ JvAssert (the_vm && vm == the_vm);
+
+ JNIEnv *env;
+ if (_Jv_ThreadCurrent () != NULL)
+ {
+ jint r = _Jv_JNI_AttachCurrentThread (vm,
+ JvNewStringLatin1 ("main"),
+ reinterpret_cast<void **> (&env),
+ NULL);
+ if (r < 0)
+ return r;
+ }
+ else
+ env = _Jv_GetCurrentJNIEnv ();
+
+ _Jv_ThreadWait ();
+
+ // Docs say that this always returns an error code.
+ return JNI_ERR;
+}
+
+static jint
+_Jv_JNI_DetachCurrentThread (JavaVM *)
+{
+ java::lang::Thread *t = _Jv_ThreadCurrent ();
+ if (t == NULL)
+ return JNI_EDETACHED;
+
+ // FIXME: we only allow threads attached via AttachCurrentThread to
+ // be detached. I have no idea how we could implement detaching
+ // other threads, given the requirement that we must release all the
+ // monitors. That just seems evil.
+ JvAssert ((&NativeThreadClass)->isInstance (t));
+
+ // FIXME: release the monitors. We'll take this to mean all
+ // monitors acquired via the JNI interface. This means we have to
+ // keep track of them.
+
+ gnu::gcj::jni::NativeThread *nt
+ = reinterpret_cast<gnu::gcj::jni::NativeThread *> (t);
+ nt->finish ();
+
+ return 0;
+}
+
+static jint
+_Jv_JNI_GetEnv (JavaVM *, void **penv, jint version)
+{
+ if (_Jv_ThreadCurrent () == NULL)
+ {
+ *penv = NULL;
+ return JNI_EDETACHED;
+ }
+
+ // FIXME: do we really want to support 1.1?
+ if (version != JNI_VERSION_1_2 && version != JNI_VERSION_1_1)
+ {
+ *penv = NULL;
+ return JNI_EVERSION;
+ }
+
+ *penv = (void *) _Jv_GetCurrentJNIEnv ();
+ return 0;
+}
+
+jint
+JNI_GetDefaultJavaVMInitArgs (void *args)
+{
+ jint version = * (jint *) args;
+ // Here we only support 1.2.
+ if (version != JNI_VERSION_1_2)
+ return JNI_EVERSION;
+
+ JavaVMInitArgs *ia = reinterpret_cast<JavaVMInitArgs *> (args);
+ ia->version = JNI_VERSION_1_2;
+ ia->nOptions = 0;
+ ia->options = NULL;
+ ia->ignoreUnrecognized = true;
+
+ return 0;
+}
+
+jint
+JNI_CreateJavaVM (JavaVM **vm, void **penv, void *args)
+{
+ JvAssert (! the_vm);
+ // FIXME: synchronize
+ JavaVM *nvm = (JavaVM *) _Jv_MallocUnchecked (sizeof (JavaVM));
+ if (nvm == NULL)
+ return JNI_ERR;
+ nvm->functions = &_Jv_JNI_InvokeFunctions;
+
+ // Parse the arguments.
+ if (args != NULL)
+ {
+ jint version = * (jint *) args;
+ // We only support 1.2.
+ if (version != JNI_VERSION_1_2)
+ return JNI_EVERSION;
+ JavaVMInitArgs *ia = reinterpret_cast<JavaVMInitArgs *> (args);
+ for (int i = 0; i < ia->nOptions; ++i)
+ {
+ if (! strcmp (ia->options[i].optionString, "vfprintf")
+ || ! strcmp (ia->options[i].optionString, "exit")
+ || ! strcmp (ia->options[i].optionString, "abort"))
+ {
+ // We are required to recognize these, but for now we
+ // don't handle them in any way. FIXME.
+ continue;
+ }
+ else if (! strncmp (ia->options[i].optionString,
+ "-verbose", sizeof ("-verbose") - 1))
+ {
+ // We don't do anything with this option either. We
+ // might want to make sure the argument is valid, but we
+ // don't really care all that much for now.
+ continue;
+ }
+ else if (! strncmp (ia->options[i].optionString, "-D", 2))
+ {
+ // FIXME.
+ continue;
+ }
+ else if (ia->ignoreUnrecognized)
+ {
+ if (ia->options[i].optionString[0] == '_'
+ || ! strncmp (ia->options[i].optionString, "-X", 2))
+ continue;
+ }
+
+ return JNI_ERR;
+ }
+ }
+
+ jint r =_Jv_JNI_AttachCurrentThread (nvm, penv, NULL);
+ if (r < 0)
+ return r;
+
+ the_vm = nvm;
+ *vm = the_vm;
+ return 0;
+}
+
+jint
+JNI_GetCreatedJavaVMs (JavaVM **vm_buffer, jsize buf_len, jsize *n_vms)
+{
+ JvAssert (buf_len > 0);
+ // We only support a single VM.
+ if (the_vm != NULL)
+ {
+ vm_buffer[0] = the_vm;
+ *n_vms = 1;
+ }
+ else
+ *n_vms = 0;
+ return 0;
+}
+
+jint
+_Jv_JNI_GetJavaVM (JNIEnv *, JavaVM **vm)
+{
+ // FIXME: synchronize
+ if (! the_vm)
+ {
+ JavaVM *nvm = (JavaVM *) _Jv_MallocUnchecked (sizeof (JavaVM));
+ if (nvm == NULL)
+ return JNI_ERR;
+ nvm->functions = &_Jv_JNI_InvokeFunctions;
+ the_vm = nvm;
+ }
+
+ *vm = the_vm;
+ return 0;
+}
+
+
+
#define NOT_IMPL NULL
#define RESERVED NULL
@@ -1614,7 +1855,7 @@ struct JNINativeInterface _Jv_JNIFunctions =
NOT_IMPL /* UnregisterNatives */,
_Jv_JNI_MonitorEnter,
_Jv_JNI_MonitorExit,
- NOT_IMPL /* GetJavaVM */,
+ _Jv_JNI_GetJavaVM,
_Jv_JNI_GetStringRegion,
_Jv_JNI_GetStringUTFRegion,
@@ -1628,3 +1869,15 @@ struct JNINativeInterface _Jv_JNIFunctions =
_Jv_JNI_ExceptionCheck
};
+
+struct JNIInvokeInterface _Jv_JNI_InvokeFunctions =
+{
+ RESERVED,
+ RESERVED,
+ RESERVED,
+
+ _Jv_JNI_DestroyJavaVM,
+ _Jv_JNI_AttachCurrentThread,
+ _Jv_JNI_DetachCurrentThread,
+ _Jv_JNI_GetEnv
+};