java-interp.h: Don't include MethodInvocation.h.

* include/java-interp.h: Don't include MethodInvocation.h.
	(class _Jv_InterpMethod): Don't make MethodInvocation a friend.
	* Makefile.in: Rebuilt.
	* Makefile.am (gnu/gcj/runtime/MethodInvocation.h): Removed.
	(ordinary_java_source_files): Don't mention
	MethodInvocation.java.
	* gnu/gcj/runtime/MethodInvocation.java: Removed.
	* interpret.cc (MethodInvocation::continue1): Removed.
	(run): Handle exceptions here.
	* java/lang/ClassLoader.java (defineClass1, defineClass2):
	Removed.
	* java/lang/natClassLoader.cc (defineClass0): Catch exceptions
	here.
	(defineClass2): Removed.

	* java/lang/reflect/Method.java (hack_trampoline, hack_call):
	Removed.
	* java/lang/reflect/natMethod.cc (_Jv_CallAnyMethodA): Catch
	exceptions here.
	(hack_call): Removed.

	* java/lang/Class.h (Class): Removed hackRunInitializers,
	hackTrampoline.
	* java/lang/natClass.cc (hackRunInitializers): Removed.
	(initializeClass): Catch exceptions here.
	Include ExceptionInInitializerError.h.
	* java/lang/Class.java (hackTrampoline, hackRunInitializers):
	Removed.

	* java/lang/Object.h (Object): Don't mention hack12_6.
	* java/lang/natObject.cc (_Jv_FinalizeObject): Catch exceptions
	here.
	* java/lang/Object.java (hack12_6): Removed.

	* java/lang/natThread.cc (run_): Renamed.  Catch exceptions here.
	(start): Use run_, not run__.
	* java/lang/Thread.java (run_): Renamed from run__; old run_
	removed.

	* jni.cc (_Jv_JNI_FindClass): Handle exceptions.
	(_Jv_JNI_EnsureLocalCapacity): Likewise.
	(_Jv_JNI_DefineClass): Likewise.
	(_Jv_JNI_ThrowNew): Likewise.
	(_Jv_JNI_AllocObject): Likewise.
	(_Jv_JNI_GetAnyMethodID): Likewise.
	(_Jv_JNI_CallAnyMethodV): Likewise.
	(_Jv_JNI_CallAnyMethodA): Likewise.
	(_Jv_JNI_CallAnyVoidMethodV): Likewise.
	(_Jv_JNI_CallAnyVoidMethodA): Likewise.
	(_Jv_JNI_GetAnyFieldID): Likewise.
	(_Jv_JNI_NewString): Likewise.
	(_Jv_JNI_NewStringUTF): Likewise.
	(_Jv_JNI_GetStringUTFChars): Likewise.
	(_Jv_JNI_NewObjectArray): Likewise.
	(_Jv_JNI_NewPrimitiveArray): Likewise.
	(_Jv_JNI_GetPrimitiveArrayRegion): Likewise.
	(_Jv_JNI_GetStringRegion): Likewise.
	(_Jv_JNI_GetStringUTFRegion): Likewise.
	(_Jv_JNI_SetPrimitiveArrayRegion): Likewise.
	(_Jv_JNI_MonitorEnter): Likewise.
	(_Jv_JNI_MonitorExit): Likewise.
	(_Jv_JNI_ToReflectedField): Likewise.
	(_Jv_JNI_ToReflectedMethod): Likewise.
	(_Jv_JNI_RegisterNatives): Likewise.
	(_Jv_JNI_AttachCurrentThread): Likewise.
	(_Jv_JNI_DestroyJavaVM): Likewise.

From-SVN: r32294
This commit is contained in:
Tom Tromey 2000-03-02 20:25:20 +00:00 committed by Tom Tromey
parent c45da1ca92
commit b099f07de9
19 changed files with 588 additions and 488 deletions

View file

@ -1,3 +1,72 @@
2000-03-02 Tom Tromey <tromey@cygnus.com>
* include/java-interp.h: Don't include MethodInvocation.h.
(class _Jv_InterpMethod): Don't make MethodInvocation a friend.
* Makefile.in: Rebuilt.
* Makefile.am (gnu/gcj/runtime/MethodInvocation.h): Removed.
(ordinary_java_source_files): Don't mention
MethodInvocation.java.
* gnu/gcj/runtime/MethodInvocation.java: Removed.
* interpret.cc (MethodInvocation::continue1): Removed.
(run): Handle exceptions here.
* java/lang/ClassLoader.java (defineClass1, defineClass2):
Removed.
* java/lang/natClassLoader.cc (defineClass0): Catch exceptions
here.
(defineClass2): Removed.
* java/lang/reflect/Method.java (hack_trampoline, hack_call):
Removed.
* java/lang/reflect/natMethod.cc (_Jv_CallAnyMethodA): Catch
exceptions here.
(hack_call): Removed.
* java/lang/Class.h (Class): Removed hackRunInitializers,
hackTrampoline.
* java/lang/natClass.cc (hackRunInitializers): Removed.
(initializeClass): Catch exceptions here.
Include ExceptionInInitializerError.h.
* java/lang/Class.java (hackTrampoline, hackRunInitializers):
Removed.
* java/lang/Object.h (Object): Don't mention hack12_6.
* java/lang/natObject.cc (_Jv_FinalizeObject): Catch exceptions
here.
* java/lang/Object.java (hack12_6): Removed.
* java/lang/natThread.cc (run_): Renamed. Catch exceptions here.
(start): Use run_, not run__.
* java/lang/Thread.java (run_): Renamed from run__; old run_
removed.
* jni.cc (_Jv_JNI_FindClass): Handle exceptions.
(_Jv_JNI_EnsureLocalCapacity): Likewise.
(_Jv_JNI_DefineClass): Likewise.
(_Jv_JNI_ThrowNew): Likewise.
(_Jv_JNI_AllocObject): Likewise.
(_Jv_JNI_GetAnyMethodID): Likewise.
(_Jv_JNI_CallAnyMethodV): Likewise.
(_Jv_JNI_CallAnyMethodA): Likewise.
(_Jv_JNI_CallAnyVoidMethodV): Likewise.
(_Jv_JNI_CallAnyVoidMethodA): Likewise.
(_Jv_JNI_GetAnyFieldID): Likewise.
(_Jv_JNI_NewString): Likewise.
(_Jv_JNI_NewStringUTF): Likewise.
(_Jv_JNI_GetStringUTFChars): Likewise.
(_Jv_JNI_NewObjectArray): Likewise.
(_Jv_JNI_NewPrimitiveArray): Likewise.
(_Jv_JNI_GetPrimitiveArrayRegion): Likewise.
(_Jv_JNI_GetStringRegion): Likewise.
(_Jv_JNI_GetStringUTFRegion): Likewise.
(_Jv_JNI_SetPrimitiveArrayRegion): Likewise.
(_Jv_JNI_MonitorEnter): Likewise.
(_Jv_JNI_MonitorExit): Likewise.
(_Jv_JNI_ToReflectedField): Likewise.
(_Jv_JNI_ToReflectedMethod): Likewise.
(_Jv_JNI_RegisterNatives): Likewise.
(_Jv_JNI_AttachCurrentThread): Likewise.
(_Jv_JNI_DestroyJavaVM): Likewise.
2000-02-28 Mo DeJong <mdejong@cygnus.com> 2000-02-28 Mo DeJong <mdejong@cygnus.com>
* java/util/zip/ZipOutputStream.java(closeEntry) : Fixed * java/util/zip/ZipOutputStream.java(closeEntry) : Fixed

View file

@ -267,11 +267,6 @@ gnu/gcj/runtime/VMClassLoader.h: gnu/gcj/runtime/VMClassLoader.class libgcj.zip
-friend 'java::lang::ClassLoader;' \ -friend 'java::lang::ClassLoader;' \
$(basename $<) $(basename $<)
gnu/gcj/runtime/MethodInvocation.h: gnu/gcj/runtime/MethodInvocation.class libgcj.zip
$(GCJH) -classpath $(top_builddir) \
-friend 'class _Jv_InterpMethod;' \
$(basename $<)
## Headers we maintain by hand and which we want to install. ## Headers we maintain by hand and which we want to install.
extra_headers = java/lang/Object.h java/lang/Class.h extra_headers = java/lang/Object.h java/lang/Class.h
@ -525,7 +520,6 @@ ordinary_java_source_files = $(convert_source_files) \
gnu/gcj/io/DefaultMimeTypes.java \ gnu/gcj/io/DefaultMimeTypes.java \
gnu/gcj/io/MimeTypes.java \ gnu/gcj/io/MimeTypes.java \
gnu/gcj/jni/NativeThread.java \ gnu/gcj/jni/NativeThread.java \
gnu/gcj/runtime/MethodInvocation.java \
gnu/gcj/runtime/VMClassLoader.java \ gnu/gcj/runtime/VMClassLoader.java \
gnu/gcj/text/BaseBreakIterator.java \ gnu/gcj/text/BaseBreakIterator.java \
gnu/gcj/text/CharacterBreakIterator.java \ gnu/gcj/text/CharacterBreakIterator.java \

View file

@ -329,7 +329,6 @@ ordinary_java_source_files = $(convert_source_files) \
gnu/gcj/io/DefaultMimeTypes.java \ gnu/gcj/io/DefaultMimeTypes.java \
gnu/gcj/io/MimeTypes.java \ gnu/gcj/io/MimeTypes.java \
gnu/gcj/jni/NativeThread.java \ gnu/gcj/jni/NativeThread.java \
gnu/gcj/runtime/MethodInvocation.java \
gnu/gcj/runtime/VMClassLoader.java \ gnu/gcj/runtime/VMClassLoader.java \
gnu/gcj/text/BaseBreakIterator.java \ gnu/gcj/text/BaseBreakIterator.java \
gnu/gcj/text/CharacterBreakIterator.java \ gnu/gcj/text/CharacterBreakIterator.java \
@ -739,7 +738,7 @@ THANKS acinclude.m4 aclocal.m4 configure configure.in libgcj.spec.in
DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
TAR = gtar TAR = tar
GZIP_ENV = --best GZIP_ENV = --best
DIST_SUBDIRS = @DIRLTDL@ testsuite gcj include @DIRLTDL@ gcj include DIST_SUBDIRS = @DIRLTDL@ testsuite gcj include @DIRLTDL@ gcj include
DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \
@ -765,7 +764,6 @@ DEP_FILES = .deps/$(srcdir)/$(CONVERT_DIR)/gen-from-JIS.P \
.deps/gnu/gcj/protocol/http/Handler.P \ .deps/gnu/gcj/protocol/http/Handler.P \
.deps/gnu/gcj/protocol/jar/Connection.P \ .deps/gnu/gcj/protocol/jar/Connection.P \
.deps/gnu/gcj/protocol/jar/Handler.P \ .deps/gnu/gcj/protocol/jar/Handler.P \
.deps/gnu/gcj/runtime/MethodInvocation.P \
.deps/gnu/gcj/runtime/VMClassLoader.P \ .deps/gnu/gcj/runtime/VMClassLoader.P \
.deps/gnu/gcj/text/BaseBreakIterator.P \ .deps/gnu/gcj/text/BaseBreakIterator.P \
.deps/gnu/gcj/text/CharacterBreakIterator.P \ .deps/gnu/gcj/text/CharacterBreakIterator.P \
@ -1284,7 +1282,7 @@ distdir: $(DISTFILES)
@for file in $(DISTFILES); do \ @for file in $(DISTFILES); do \
d=$(srcdir); \ d=$(srcdir); \
if test -d $$d/$$file; then \ if test -d $$d/$$file; then \
cp -pr $$d/$$file $(distdir)/$$file; \ cp -pr $$/$$file $(distdir)/$$file; \
else \ else \
test -f $(distdir)/$$file \ test -f $(distdir)/$$file \
|| ln $$d/$$file $(distdir)/$$file 2> /dev/null \ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
@ -1565,11 +1563,6 @@ gnu/gcj/runtime/VMClassLoader.h: gnu/gcj/runtime/VMClassLoader.class libgcj.zip
-friend 'java::lang::ClassLoader;' \ -friend 'java::lang::ClassLoader;' \
$(basename $<) $(basename $<)
gnu/gcj/runtime/MethodInvocation.h: gnu/gcj/runtime/MethodInvocation.class libgcj.zip
$(GCJH) -classpath $(top_builddir) \
-friend 'class _Jv_InterpMethod;' \
$(basename $<)
install-data-local: install-data-local:
$(PRE_INSTALL) $(PRE_INSTALL)
@for f in $(nat_headers) $(extra_headers); do \ @for f in $(nat_headers) $(extra_headers); do \

View file

@ -1,32 +0,0 @@
// MethodInvocation.java - wrapper used by the interpreter.
// (the native method is implemented in interpret.cc)
/* Copyright (C) 1999 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. */
/* Author: Kresten Krab Thorup <krab@gnu.org> */
package gnu.gcj.runtime;
import gnu.gcj.RawData;
final class MethodInvocation {
private static Throwable continue0 (RawData meth, RawData inv)
{
try {
continue1 (meth, inv);
} catch (Throwable ex) {
return ex;
}
return null;
}
private static native void continue1 (RawData meth, RawData inv);
}

View file

@ -20,7 +20,6 @@ details. */
#include <java/lang/Class.h> #include <java/lang/Class.h>
#include <java/lang/ClassLoader.h> #include <java/lang/ClassLoader.h>
#include <gnu/gcj/runtime/MethodInvocation.h>
extern "C" { extern "C" {
#include <ffi.h> #include <ffi.h>
@ -135,7 +134,6 @@ class _Jv_InterpMethod : public _Jv_MethodBase
friend class _Jv_ClassReader; friend class _Jv_ClassReader;
friend class _Jv_InterpMethodInvocation; friend class _Jv_InterpMethodInvocation;
friend class gnu::gcj::runtime::MethodInvocation;
friend void _Jv_PrepareClass(jclass); friend void _Jv_PrepareClass(jclass);
}; };

View file

@ -33,19 +33,7 @@ details. */
#include <java-insns.h> #include <java-insns.h>
#include <java-signal.h> #include <java-signal.h>
#ifndef INTERPRETER #ifdef INTERPRETER
#include <gnu/gcj/runtime/MethodInvocation.h>
/* This should never happen. */
void
gnu::gcj::runtime::MethodInvocation::continue1 (gnu::gcj::RawData *,
gnu::gcj::RawData *)
{
JvFail ("no interpreter");
}
#else
#define ClassError _CL_Q34java4lang5Error #define ClassError _CL_Q34java4lang5Error
extern java::lang::Class ClassError; extern java::lang::Class ClassError;
@ -216,10 +204,17 @@ _Jv_InterpMethod::run (ffi_cif* cif,
memcpy ((void*) locals, (void*) args, args_raw_size); memcpy ((void*) locals, (void*) args, args_raw_size);
next_segment: next_segment:
/* this will call the method _Jv_InterpMethod::continue0, see below */
jobject ex = jobject ex = NULL;
gnu::gcj::runtime::MethodInvocation::continue0
((gnu::gcj::RawData *)this, (gnu::gcj::RawData *)inv); try
{
continue1 (inv);
}
catch (java::lang::Throwable *ex2)
{
ex = ex2;
}
if (ex == 0) // no exception... if (ex == 0) // no exception...
{ {
@ -280,7 +275,6 @@ _Jv_InterpMethod::run (ffi_cif* cif,
default: default:
throw_internal_error ("unknown return type"); throw_internal_error ("unknown return type");
} }
} }
/** handle an exception */ /** handle an exception */
@ -379,16 +373,6 @@ void _Jv_InterpMethod::run_synch_class (ffi_cif* cif,
if (ex != 0) _Jv_Throw (ex); if (ex != 0) _Jv_Throw (ex);
} }
/* this is the exception handler hack, for the interpreter */
void
gnu::gcj::runtime::MethodInvocation::continue1 (gnu::gcj::RawData *meth,
gnu::gcj::RawData *inv)
{
_Jv_InterpMethod *meth0 = (_Jv_InterpMethod*)meth;
_Jv_InterpMethodInvocation *inv0 = (_Jv_InterpMethodInvocation*)inv;
meth0->continue1 (inv0);
}
/* /*
This proceeds execution, as designated in "inv". If an exception This proceeds execution, as designated in "inv". If an exception
happens, then it is simply thrown, and handled in Java. Thus, the pc happens, then it is simply thrown, and handled in Java. Thus, the pc

View file

@ -157,9 +157,6 @@ public:
private: private:
void checkMemberAccess (jint flags); void checkMemberAccess (jint flags);
// Various functions to handle class initialization.
java::lang::Throwable *hackTrampoline (jint, java::lang::Throwable *);
void hackRunInitializers (void);
void initializeClass (void); void initializeClass (void);
// Friend functions implemented in natClass.cc. // Friend functions implemented in natClass.cc.

View file

@ -172,32 +172,6 @@ public final class Class implements Serializable
sm.checkMemberAccess(this, flags); sm.checkMemberAccess(this, flags);
} }
// FIXME: this method exists only because we cannot catch Java
// exceptions from C++ code. This is a helper for initializeClass.
private Throwable hackTrampoline (int what, Throwable old_exception)
{
Throwable new_val = null;
try
{
if (what == 0)
initializeClass ();
else if (what == 1)
hackRunInitializers ();
else if (what == 2)
new_val = new ExceptionInInitializerError (old_exception);
}
catch (Throwable t)
{
new_val = t;
}
return new_val;
}
// FIXME: this is a hack to let us run the class initializers. We
// could do it inline in initializeClass() if we could catch Java
// exceptions from C++.
private native void hackRunInitializers ();
// Initialize the class. // Initialize the class.
private native void initializeClass (); private native void initializeClass ();

View file

@ -1,6 +1,6 @@
// ClassLoader.java - Define policies for loading Java classes. // ClassLoader.java - Define policies for loading Java classes.
/* Copyright (C) 1998, 1999 Red Hat, Inc. /* Copyright (C) 1998, 1999, 2000 Red Hat, Inc.
This file is part of libgcj. This file is part of libgcj.
@ -234,28 +234,6 @@ public abstract class ClassLoader {
throws java.lang.ClassNotFoundException, java.lang.LinkageError; throws java.lang.ClassNotFoundException, java.lang.LinkageError;
/** This is called by defineClass0, once the "raw" and uninitialized
* class object has been created, and handles exceptions generated
* while actually defining the class (_Jv_DefineClass). defineClass0
* holds the lock on the new class object, so it needs to capture
* these exceptions. */
private static Throwable defineClass1 (Class klass, byte[] data,
int offset, int length)
{
try {
defineClass2 (klass, data, offset, length);
} catch (Throwable x) {
return x;
}
return null;
}
/** This is just a wrapper for _Jv_DefineClass */
private static native void defineClass2 (Class klass, byte[] data,
int offset, int length)
throws Throwable;
/** /**
* Link the given class. This will bring the class to a state where * Link the given class. This will bring the class to a state where
* the class initializer can be run. Linking involves the following * the class initializer can be run. Linking involves the following

View file

@ -1,6 +1,6 @@
// Object.h - Header file for java.lang.Object. -*- c++ -*- // Object.h - Header file for java.lang.Object. -*- c++ -*-
/* Copyright (C) 1998, 1999 Red Hat, Inc. /* Copyright (C) 1998, 1999, 2000 Red Hat, Inc.
This file is part of libgcj. This file is part of libgcj.
@ -69,8 +69,6 @@ private:
// Initialize the sync_info field. // Initialize the sync_info field.
void sync_init (void); void sync_init (void);
static void hack12_6 (jobject f);
}; };
#endif /* __JAVA_LANG_OBJECT_H__ */ #endif /* __JAVA_LANG_OBJECT_H__ */

View file

@ -1,6 +1,6 @@
// Object.java - The root of all evil. // Object.java - The root of all evil.
/* Copyright (C) 1998, 1999 Red Hat, Inc. /* Copyright (C) 1998, 1999, 2000 Red Hat, Inc.
This file is part of libgcj. This file is part of libgcj.
@ -66,21 +66,6 @@ public class Object
// completeness (some day we'll be able to auto-generate Object.h). // completeness (some day we'll be able to auto-generate Object.h).
private final native void sync_init (); private final native void sync_init ();
// This exists as a workaround for the fact that we can't catch a
// Java Exception from C++. This is from section 12.6 of the Java
// Language Spec. FIXME: remove this once exception processing
// works.
private static final void hack12_6 (Object f)
{
try
{
f.finalize();
}
catch (Throwable x)
{
}
}
// Note that we don't mention the sync_info field here. If we do, // Note that we don't mention the sync_info field here. If we do,
// jc1 will not work correctly. // jc1 will not work correctly.
} }

View file

@ -116,8 +116,8 @@ public class Thread implements Runnable
public final native void resume (); public final native void resume ();
// This method exists only to avoid a warning from the C++ compiler. // This method exists only to avoid a warning from the C++ compiler.
private static final native void run__ (Object obj); private static final native void run_ (Object obj);
private native final void finish_ (); private final native void finish_ ();
// Convenience method to check and clear the thread's interrupted status. // Convenience method to check and clear the thread's interrupted status.
private boolean isInterrupted_ () private boolean isInterrupted_ ()
@ -127,28 +127,6 @@ public class Thread implements Runnable
return r; return r;
} }
private final void run_ ()
{
try
{
run ();
}
catch (Throwable e)
{
// Uncaught exceptions are forwarded to the ThreadGroup. If
// this results in an uncaught exception, that is ignored.
try
{
group.uncaughtException(this, e);
}
catch (Throwable f)
{
// Nothing.
}
}
finish_ ();
}
public void run () public void run ()
{ {
if (runnable != null) if (runnable != null)

View file

@ -27,6 +27,7 @@ details. */
#include <java/lang/reflect/Constructor.h> #include <java/lang/reflect/Constructor.h>
#include <java/lang/AbstractMethodError.h> #include <java/lang/AbstractMethodError.h>
#include <java/lang/ClassNotFoundException.h> #include <java/lang/ClassNotFoundException.h>
#include <java/lang/ExceptionInInitializerError.h>
#include <java/lang/IllegalAccessException.h> #include <java/lang/IllegalAccessException.h>
#include <java/lang/IllegalAccessError.h> #include <java/lang/IllegalAccessError.h>
#include <java/lang/IncompatibleClassChangeError.h> #include <java/lang/IncompatibleClassChangeError.h>
@ -690,15 +691,6 @@ java::lang::Class::finalize (void)
#endif #endif
} }
// FIXME.
void
java::lang::Class::hackRunInitializers (void)
{
_Jv_Method *meth = _Jv_GetMethodLocal (this, clinit_name, void_signature);
if (meth)
((void (*) (void)) meth->ncode) ();
}
// This implements the initialization process for a class. From Spec // This implements the initialization process for a class. From Spec
// section 12.4.2. // section 12.4.2.
void void
@ -764,46 +756,53 @@ java::lang::Class::initializeClass (void)
// Step 7. // Step 7.
if (! isInterface () && superclass) if (! isInterface () && superclass)
{ {
// FIXME: We can't currently catch a Java exception in C++ code. try
// So instead we call a Java trampoline. It returns an {
// exception, or null. superclass->initializeClass ();
jobject except = superclass->hackTrampoline(0, NULL); }
if (except) catch (java::lang::Throwable *except)
{ {
// Caught an exception. // Caught an exception.
_Jv_MonitorEnter (this); _Jv_MonitorEnter (this);
state = JV_STATE_ERROR; state = JV_STATE_ERROR;
notifyAll (); notifyAll ();
_Jv_MonitorExit (this); _Jv_MonitorExit (this);
JvThrow (except); throw except;
} }
} }
// Step 8. // Steps 8, 9, 10, 11.
// FIXME: once again we have to go through a trampoline. try
java::lang::Throwable *except = hackTrampoline (1, NULL);
// Steps 9, 10, 11.
if (! except)
{ {
_Jv_MonitorEnter (this); _Jv_Method *meth = _Jv_GetMethodLocal (this, clinit_name,
state = JV_STATE_DONE; void_signature);
if (meth)
((void (*) (void)) meth->ncode) ();
} }
else catch (java::lang::Throwable *except)
{ {
if (! ErrorClass.isInstance(except)) if (! ErrorClass.isInstance(except))
{ {
// Once again we must use the trampoline. In this case we try
// have to detect an OutOfMemoryError. {
except = hackTrampoline(2, except); except = new ExceptionInInitializerError (except);
}
catch (java::lang::Throwable *t)
{
except = t;
}
} }
_Jv_MonitorEnter (this); _Jv_MonitorEnter (this);
state = JV_STATE_ERROR; state = JV_STATE_ERROR;
notifyAll ();
_Jv_MonitorExit (this);
JvThrow (except);
} }
_Jv_MonitorEnter (this);
state = JV_STATE_DONE;
notifyAll (); notifyAll ();
_Jv_MonitorExit (this); _Jv_MonitorExit (this);
if (except)
JvThrow (except);
} }

View file

@ -58,15 +58,6 @@ java::lang::ClassLoader::getSystemClassLoader (void)
return system; return system;
} }
void
java::lang::ClassLoader::defineClass2 (jclass klass, jbyteArray data,
jint offset, jint length)
{
#ifdef INTERPRETER
_Jv_DefineClass (klass, data, offset, length);
#endif
}
java::lang::Class * java::lang::Class *
java::lang::ClassLoader::defineClass0 (jstring name, java::lang::ClassLoader::defineClass0 (jstring name,
jbyteArray data, jbyteArray data,
@ -94,11 +85,11 @@ java::lang::ClassLoader::defineClass0 (jstring name,
klass->name = name2; klass->name = name2;
} }
// this will do the magic. loadInto also operates try
// as an exception trampoline for now... {
Throwable *ex = defineClass1 (klass, data, offset, length); _Jv_DefineClass (klass, data, offset, length);
}
if (ex) // we failed to load it catch (java::lang::Throwable *ex)
{ {
klass->state = JV_STATE_ERROR; klass->state = JV_STATE_ERROR;
klass->notifyAll (); klass->notifyAll ();
@ -106,15 +97,15 @@ java::lang::ClassLoader::defineClass0 (jstring name,
_Jv_UnregisterClass (klass); _Jv_UnregisterClass (klass);
_Jv_MonitorExit (klass); _Jv_MonitorExit (klass);
// FIXME: Here we may want to test that EX does // FIXME: Here we may want to test that EX does
// indeed represent a valid exception. That is, // indeed represent a valid exception. That is,
// anything but ClassNotFoundException, // anything but ClassNotFoundException,
// or some kind of Error. // or some kind of Error.
JvThrow (ex); JvThrow (ex);
} }
// if everything proceeded sucessfully, we're loaded. // if everything proceeded sucessfully, we're loaded.
JvAssert (klass->state == JV_STATE_LOADED); JvAssert (klass->state == JV_STATE_LOADED);

View file

@ -1,6 +1,6 @@
// natObject.cc - Implementation of the Object class. // natObject.cc - Implementation of the Object class.
/* Copyright (C) 1998, 1999 Red Hat, Inc. /* Copyright (C) 1998, 1999, 2000 Red Hat, Inc.
This file is part of libgcj. This file is part of libgcj.
@ -242,5 +242,13 @@ _Jv_MonitorExit (jobject obj)
void void
_Jv_FinalizeObject (jobject obj) _Jv_FinalizeObject (jobject obj)
{ {
java::lang::Object::hack12_6(obj); // Ignore exceptions. From section 12.6 of the Java Language Spec.
try
{
obj->finalize ();
}
catch (java::lang::Throwable *t)
{
// Ignore.
}
} }

View file

@ -263,9 +263,9 @@ java::lang::Thread::sleep (jlong millis, jint nanos)
} }
void void
java::lang::Thread::finish_ (void) java::lang::Thread::finish_ ()
{ {
// Notify all threads waiting to join this thread. // Notify all threads waiting to join this this.
_Jv_MonitorEnter (this); _Jv_MonitorEnter (this);
alive_flag = false; alive_flag = false;
@ -285,10 +285,28 @@ java::lang::Thread::finish_ (void)
} }
void void
java::lang::Thread::run__ (jobject obj) java::lang::Thread::run_ (jobject obj)
{ {
java::lang::Thread *thread = (java::lang::Thread *) obj; java::lang::Thread *thread = (java::lang::Thread *) obj;
thread->run_ (); try
{
thread->run ();
}
catch (java::lang::Throwable *t)
{
// Uncaught exceptions are forwarded to the ThreadGroup. If
// this results in an uncaught exception, that is ignored.
try
{
thread->group->uncaughtException (thread, t);
}
catch (java::lang::Throwable *f)
{
// Nothing.
}
}
thread->finish_ ();
} }
void void
@ -301,7 +319,7 @@ java::lang::Thread::start (void)
alive_flag = true; alive_flag = true;
natThread *nt = (natThread *) data; natThread *nt = (natThread *) data;
_Jv_ThreadStart (this, nt->thread, (_Jv_ThreadStartFunc *) &run__); _Jv_ThreadStart (this, nt->thread, (_Jv_ThreadStartFunc *) &run_);
} }
void void

View file

@ -1,6 +1,6 @@
// Method.java - Represent method of class or interface. // Method.java - Represent method of class or interface.
/* Copyright (C) 1998, 1999 Red Hat, Inc. /* Copyright (C) 1998, 1999, 2000 Red Hat, Inc.
This file is part of libgcj. This file is part of libgcj.
@ -68,30 +68,6 @@ public final class Method extends AccessibleObject implements Member
return name.hashCode() + declaringClass.getName().hashCode(); return name.hashCode() + declaringClass.getName().hashCode();
} }
// This is used to perform an actual method call via ffi.
private static final native void hack_call (RawData cif,
RawData method,
RawData ret_value,
RawData values);
// Perform an ffi call while capturing exceptions. We have to do
// this because we can't catch Java exceptions from C++.
static final Throwable hack_trampoline (RawData cif,
RawData method,
RawData ret_value,
RawData values)
{
try
{
hack_call (cif, method, ret_value, values);
}
catch (Throwable x)
{
return x;
}
return null;
}
public native Object invoke (Object obj, Object[] args) public native Object invoke (Object obj, Object[] args)
throws IllegalAccessException, IllegalArgumentException, throws IllegalAccessException, IllegalArgumentException,
InvocationTargetException; InvocationTargetException;

View file

@ -152,21 +152,6 @@ get_ffi_type (jclass klass)
return r; return r;
} }
// Actually perform an FFI call.
void
java::lang::reflect::Method::hack_call (gnu::gcj::RawData *rcif,
gnu::gcj::RawData *rmethod,
gnu::gcj::RawData *rret_value,
gnu::gcj::RawData *rvalues)
{
ffi_cif *cif = (ffi_cif *) rcif;
void (*method) (...) = (void (*) (...)) rmethod;
void *ret_value = (void *) rret_value;
void **values = (void **) rvalues;
ffi_call (cif, method, ret_value, values);
}
jobject jobject
java::lang::reflect::Method::invoke (jobject obj, jobjectArray args) java::lang::reflect::Method::invoke (jobject obj, jobjectArray args)
{ {
@ -419,19 +404,23 @@ _Jv_CallAnyMethodA (jobject obj,
// FIXME: initialize class here. // FIXME: initialize class here.
java::lang::Throwable *ex;
using namespace java::lang; using namespace java::lang;
using namespace java::lang::reflect; using namespace java::lang::reflect;
ex = Method::hack_trampoline ((gnu::gcj::RawData *) &cif,
(gnu::gcj::RawData *) meth->ncode,
(gnu::gcj::RawData *) result,
(gnu::gcj::RawData *) values);
if (ex) Throwable *ex = NULL;
// FIXME: this is wrong for JNI. But if we just return the
// exception, then the non-JNI cases won't be able to distinguish try
// it from exceptions we might generate ourselves. Sigh. {
ex = new InvocationTargetException (ex); ffi_call (&cif, (void (*) (...)) meth->ncode, result, values);
}
catch (Throwable *ex2)
{
// FIXME: this is wrong for JNI. But if we just return the
// exception, then the non-JNI cases won't be able to
// distinguish it from exceptions we might generate ourselves.
// Sigh.
ex = new InvocationTargetException (ex2);
}
if (is_constructor) if (is_constructor)
result->l = obj; result->l = obj;

View file

@ -115,6 +115,7 @@ mark_for_gc (jobject obj)
using namespace java::lang; using namespace java::lang;
Integer *refcount = (Integer *) ref_table->get (obj); Integer *refcount = (Integer *) ref_table->get (obj);
jint val = (refcount == NULL) ? 0 : refcount->intValue (); jint val = (refcount == NULL) ? 0 : refcount->intValue ();
// FIXME: what about out of memory error?
ref_table->put (obj, new Integer (val + 1)); ref_table->put (obj, new Integer (val + 1));
} }
@ -131,6 +132,7 @@ unmark_for_gc (jobject obj)
if (val == 0) if (val == 0)
ref_table->remove (obj); ref_table->remove (obj);
else else
// FIXME: what about out of memory error?
ref_table->put (obj, new Integer (val)); ref_table->put (obj, new Integer (val));
} }
@ -180,13 +182,15 @@ _Jv_JNI_EnsureLocalCapacity (JNIEnv *env, jint size)
// size. This isn't the most efficient thing, but for now we don't // size. This isn't the most efficient thing, but for now we don't
// care. Note that _Jv_JNI_PushLocalFrame relies on this right now. // care. Note that _Jv_JNI_PushLocalFrame relies on this right now.
_Jv_JNI_LocalFrame *frame _Jv_JNI_LocalFrame *frame;
= (_Jv_JNI_LocalFrame *) _Jv_MallocUnchecked (sizeof (_Jv_JNI_LocalFrame) try
+ size * sizeof (jobject));
if (frame == NULL)
{ {
// FIXME: exception processing. frame = (_Jv_JNI_LocalFrame *) _Jv_Malloc (sizeof (_Jv_JNI_LocalFrame)
env->ex = new java::lang::OutOfMemoryError; + size * sizeof (jobject));
}
catch (jthrowable t)
{
env->ex = t;
return JNI_ERR; return JNI_ERR;
} }
@ -304,16 +308,24 @@ static jclass
_Jv_JNI_DefineClass (JNIEnv *env, jobject loader, _Jv_JNI_DefineClass (JNIEnv *env, jobject loader,
const jbyte *buf, jsize bufLen) const jbyte *buf, jsize bufLen)
{ {
jbyteArray bytes = JvNewByteArray (bufLen); try
jbyte *elts = elements (bytes); {
memcpy (elts, buf, bufLen * sizeof (jbyte)); jbyteArray bytes = JvNewByteArray (bufLen);
java::lang::ClassLoader *l jbyte *elts = elements (bytes);
= reinterpret_cast<java::lang::ClassLoader *> (loader); memcpy (elts, buf, bufLen * sizeof (jbyte));
// FIXME: exception processing. java::lang::ClassLoader *l
jclass result = l->defineClass (bytes, 0, bufLen); = reinterpret_cast<java::lang::ClassLoader *> (loader);
return (jclass) wrap_value (env, result);
jclass result = l->defineClass (bytes, 0, bufLen);
return (jclass) wrap_value (env, result);
}
catch (jthrowable t)
{
env->ex = t;
return NULL;
}
} }
static jclass static jclass
@ -324,20 +336,29 @@ _Jv_JNI_FindClass (JNIEnv *env, const char *name)
char s[len + 1]; char s[len + 1];
for (int i = 0; i <= len; ++i) for (int i = 0; i <= len; ++i)
s[i] = (name[i] == '/') ? '.' : name[i]; s[i] = (name[i] == '/') ? '.' : name[i];
jstring n = JvNewStringUTF (s);
java::lang::ClassLoader *loader; jclass r = NULL;
if (env->klass == NULL) try
{ {
// FIXME: should use getBaseClassLoader, but we don't have that // This might throw an out of memory exception.
// yet. jstring n = JvNewStringUTF (s);
loader = java::lang::ClassLoader::getSystemClassLoader ();
}
else
loader = env->klass->getClassLoader ();
// FIXME: exception processing. java::lang::ClassLoader *loader;
jclass r = loader->loadClass (n); if (env->klass == NULL)
{
// FIXME: should use getBaseClassLoader, but we don't have that
// yet.
loader = java::lang::ClassLoader::getSystemClassLoader ();
}
else
loader = env->klass->getClassLoader ();
r = loader->loadClass (n);
}
catch (jthrowable t)
{
env->ex = t;
}
return (jclass) wrap_value (env, r); return (jclass) wrap_value (env, r);
} }
@ -370,24 +391,32 @@ _Jv_JNI_ThrowNew (JNIEnv *env, jclass clazz, const char *message)
JvAssert ((&ThrowableClass)->isAssignableFrom (clazz)); JvAssert ((&ThrowableClass)->isAssignableFrom (clazz));
JArray<jclass> *argtypes int r = JNI_OK;
= (JArray<jclass> *) JvNewObjectArray (1, &ClassClass, NULL); try
{
JArray<jclass> *argtypes
= (JArray<jclass> *) JvNewObjectArray (1, &ClassClass, NULL);
jclass *elts = elements (argtypes); jclass *elts = elements (argtypes);
elts[0] = &StringClass; elts[0] = &StringClass;
// FIXME: exception processing. Constructor *cons = clazz->getConstructor (argtypes);
Constructor *cons = clazz->getConstructor (argtypes);
jobjectArray values = JvNewObjectArray (1, &StringClass, NULL); jobjectArray values = JvNewObjectArray (1, &StringClass, NULL);
jobject *velts = elements (values); jobject *velts = elements (values);
velts[0] = JvNewStringUTF (message); velts[0] = JvNewStringUTF (message);
// FIXME: exception processing. jobject obj = cons->newInstance (values);
jobject obj = cons->newInstance (values);
env->ex = reinterpret_cast<jthrowable> (obj); env->ex = reinterpret_cast<jthrowable> (obj);
return 0; }
catch (jthrowable t)
{
env->ex = t;
r = JNI_ERR;
}
return r;
} }
static jthrowable static jthrowable
@ -435,14 +464,20 @@ _Jv_JNI_AllocObject (JNIEnv *env, jclass clazz)
jobject obj = NULL; jobject obj = NULL;
using namespace java::lang::reflect; using namespace java::lang::reflect;
JvAssert (clazz && ! clazz->isArray ()); try
if (clazz->isInterface() || Modifier::isAbstract(clazz->getModifiers()))
env->ex = new java::lang::InstantiationException ();
else
{ {
// FIXME: exception processing. JvAssert (clazz && ! clazz->isArray ());
// FIXME: will this work for String? if (clazz->isInterface() || Modifier::isAbstract(clazz->getModifiers()))
obj = JvAllocObject (clazz); env->ex = new java::lang::InstantiationException ();
else
{
// FIXME: will this work for String?
obj = JvAllocObject (clazz);
}
}
catch (jthrowable t)
{
env->ex = t;
} }
return wrap_value (env, obj); return wrap_value (env, obj);
@ -472,36 +507,43 @@ static jmethodID
_Jv_JNI_GetAnyMethodID (JNIEnv *env, jclass clazz, _Jv_JNI_GetAnyMethodID (JNIEnv *env, jclass clazz,
const char *name, const char *sig) const char *name, const char *sig)
{ {
// FIXME: exception processing. try
_Jv_InitClass (clazz);
_Jv_Utf8Const *name_u = _Jv_makeUtf8Const ((char *) name, -1);
_Jv_Utf8Const *sig_u = _Jv_makeUtf8Const ((char *) sig, -1);
JvAssert (! clazz->isPrimitive());
using namespace java::lang::reflect;
while (clazz != NULL)
{ {
jint count = JvNumMethods (clazz); _Jv_InitClass (clazz);
jmethodID meth = JvGetFirstMethod (clazz);
for (jint i = 0; i < count; ++i) _Jv_Utf8Const *name_u = _Jv_makeUtf8Const ((char *) name, -1);
_Jv_Utf8Const *sig_u = _Jv_makeUtf8Const ((char *) sig, -1);
JvAssert (! clazz->isPrimitive());
using namespace java::lang::reflect;
while (clazz != NULL)
{ {
if (((is_static && Modifier::isStatic (meth->accflags)) jint count = JvNumMethods (clazz);
|| (! is_static && ! Modifier::isStatic (meth->accflags))) jmethodID meth = JvGetFirstMethod (clazz);
&& _Jv_equalUtf8Consts (meth->name, name_u)
&& _Jv_equalUtf8Consts (meth->signature, sig_u))
return meth;
meth = meth->getNextMethod(); for (jint i = 0; i < count; ++i)
{
if (((is_static && Modifier::isStatic (meth->accflags))
|| (! is_static && ! Modifier::isStatic (meth->accflags)))
&& _Jv_equalUtf8Consts (meth->name, name_u)
&& _Jv_equalUtf8Consts (meth->signature, sig_u))
return meth;
meth = meth->getNextMethod();
}
clazz = clazz->getSuperclass ();
} }
clazz = clazz->getSuperclass (); env->ex = new java::lang::NoSuchMethodError ();
}
catch (jthrowable t)
{
env->ex = t;
} }
env->ex = new java::lang::NoSuchMethodError ();
return NULL; return NULL;
} }
@ -553,27 +595,36 @@ _Jv_JNI_CallAnyMethodV (JNIEnv *env, jobject obj, jclass klass,
jclass return_type; jclass return_type;
JArray<jclass> *arg_types; JArray<jclass> *arg_types;
// FIXME: exception processing.
_Jv_GetTypesFromSignature (id, decl_class,
&arg_types, &return_type);
jvalue args[arg_types->length]; try
array_from_valist (args, arg_types, vargs); {
_Jv_GetTypesFromSignature (id, decl_class,
&arg_types, &return_type);
// For constructors we need to pass the Class we are instantiating. jvalue args[arg_types->length];
if (style == constructor) array_from_valist (args, arg_types, vargs);
return_type = klass;
jvalue result; // For constructors we need to pass the Class we are instantiating.
jthrowable ex = _Jv_CallAnyMethodA (obj, return_type, id, if (style == constructor)
style == constructor, return_type = klass;
arg_types, args, &result);
if (ex != NULL) jvalue result;
env->ex = ex; jthrowable ex = _Jv_CallAnyMethodA (obj, return_type, id,
style == constructor,
arg_types, args, &result);
// We cheat a little here. FIXME. if (ex != NULL)
return wrap_value (env, * (T *) &result); env->ex = ex;
// We cheat a little here. FIXME.
return wrap_value (env, * (T *) &result);
}
catch (jthrowable t)
{
env->ex = t;
}
return wrap_value (env, (T) 0);
} }
template<typename T, invocation_type style> template<typename T, invocation_type style>
@ -604,24 +655,32 @@ _Jv_JNI_CallAnyMethodA (JNIEnv *env, jobject obj, jclass klass,
jclass return_type; jclass return_type;
JArray<jclass> *arg_types; JArray<jclass> *arg_types;
// FIXME: exception processing. try
_Jv_GetTypesFromSignature (id, decl_class, {
&arg_types, &return_type); _Jv_GetTypesFromSignature (id, decl_class,
&arg_types, &return_type);
// For constructors we need to pass the Class we are instantiating. // For constructors we need to pass the Class we are instantiating.
if (style == constructor) if (style == constructor)
return_type = klass; return_type = klass;
jvalue result; jvalue result;
jthrowable ex = _Jv_CallAnyMethodA (obj, return_type, id, jthrowable ex = _Jv_CallAnyMethodA (obj, return_type, id,
style == constructor, style == constructor,
arg_types, args, &result); arg_types, args, &result);
if (ex != NULL) if (ex != NULL)
env->ex = ex; env->ex = ex;
// We cheat a little here. FIXME. // We cheat a little here. FIXME.
return wrap_value (env, * (T *) &result); return wrap_value (env, * (T *) &result);
}
catch (jthrowable t)
{
env->ex = t;
}
return wrap_value (env, (T) 0);
} }
template<invocation_type style> template<invocation_type style>
@ -637,23 +696,29 @@ _Jv_JNI_CallAnyVoidMethodV (JNIEnv *env, jobject obj, jclass klass,
jclass return_type; jclass return_type;
JArray<jclass> *arg_types; JArray<jclass> *arg_types;
// FIXME: exception processing. try
_Jv_GetTypesFromSignature (id, decl_class, {
&arg_types, &return_type); _Jv_GetTypesFromSignature (id, decl_class,
&arg_types, &return_type);
jvalue args[arg_types->length]; jvalue args[arg_types->length];
array_from_valist (args, arg_types, vargs); array_from_valist (args, arg_types, vargs);
// For constructors we need to pass the Class we are instantiating. // For constructors we need to pass the Class we are instantiating.
if (style == constructor) if (style == constructor)
return_type = klass; return_type = klass;
jthrowable ex = _Jv_CallAnyMethodA (obj, return_type, id, jthrowable ex = _Jv_CallAnyMethodA (obj, return_type, id,
style == constructor, style == constructor,
arg_types, args, NULL); arg_types, args, NULL);
if (ex != NULL) if (ex != NULL)
env->ex = ex; env->ex = ex;
}
catch (jthrowable t)
{
env->ex = t;
}
} }
template<invocation_type style> template<invocation_type style>
@ -681,16 +746,22 @@ _Jv_JNI_CallAnyVoidMethodA (JNIEnv *env, jobject obj, jclass klass,
jclass return_type; jclass return_type;
JArray<jclass> *arg_types; JArray<jclass> *arg_types;
// FIXME: exception processing. try
_Jv_GetTypesFromSignature (id, decl_class, {
&arg_types, &return_type); _Jv_GetTypesFromSignature (id, decl_class,
&arg_types, &return_type);
jthrowable ex = _Jv_CallAnyMethodA (obj, return_type, id, jthrowable ex = _Jv_CallAnyMethodA (obj, return_type, id,
style == constructor, style == constructor,
arg_types, args, NULL); arg_types, args, NULL);
if (ex != NULL) if (ex != NULL)
env->ex = ex; env->ex = ex;
}
catch (jthrowable t)
{
env->ex = t;
}
} }
// Functions with this signature are used to implement functions in // Functions with this signature are used to implement functions in
@ -895,49 +966,55 @@ static jfieldID
_Jv_JNI_GetAnyFieldID (JNIEnv *env, jclass clazz, _Jv_JNI_GetAnyFieldID (JNIEnv *env, jclass clazz,
const char *name, const char *sig) const char *name, const char *sig)
{ {
// FIXME: exception processing. try
_Jv_InitClass (clazz);
_Jv_Utf8Const *a_name = _Jv_makeUtf8Const ((char *) name, -1);
jclass field_class = NULL;
if (sig[0] == '[')
field_class = _Jv_FindClassFromSignature ((char *) sig, NULL);
else
{ {
_Jv_Utf8Const *sig_u = _Jv_makeUtf8Const ((char *) sig, -1); _Jv_InitClass (clazz);
field_class = _Jv_FindClass (sig_u, NULL);
}
// FIXME: what if field_class == NULL? _Jv_Utf8Const *a_name = _Jv_makeUtf8Const ((char *) name, -1);
while (clazz != NULL) jclass field_class = NULL;
{ if (sig[0] == '[')
jint count = (is_static field_class = _Jv_FindClassFromSignature ((char *) sig, NULL);
? JvNumStaticFields (clazz) else
: JvNumInstanceFields (clazz));
jfieldID field = (is_static
? JvGetFirstStaticField (clazz)
: JvGetFirstInstanceField (clazz));
for (jint i = 0; i < count; ++i)
{ {
// The field is resolved as a side effect of class _Jv_Utf8Const *sig_u = _Jv_makeUtf8Const ((char *) sig, -1);
// initialization. field_class = _Jv_FindClass (sig_u, NULL);
JvAssert (field->isResolved ());
_Jv_Utf8Const *f_name = field->getNameUtf8Const(clazz);
if (_Jv_equalUtf8Consts (f_name, a_name)
&& field->getClass() == field_class)
return field;
field = field->getNextField ();
} }
clazz = clazz->getSuperclass (); // FIXME: what if field_class == NULL?
}
env->ex = new java::lang::NoSuchFieldError (); while (clazz != NULL)
{
jint count = (is_static
? JvNumStaticFields (clazz)
: JvNumInstanceFields (clazz));
jfieldID field = (is_static
? JvGetFirstStaticField (clazz)
: JvGetFirstInstanceField (clazz));
for (jint i = 0; i < count; ++i)
{
// The field is resolved as a side effect of class
// initialization.
JvAssert (field->isResolved ());
_Jv_Utf8Const *f_name = field->getNameUtf8Const(clazz);
if (_Jv_equalUtf8Consts (f_name, a_name)
&& field->getClass() == field_class)
return field;
field = field->getNextField ();
}
clazz = clazz->getSuperclass ();
}
env->ex = new java::lang::NoSuchFieldError ();
}
catch (jthrowable t)
{
env->ex = t;
}
return NULL; return NULL;
} }
@ -960,9 +1037,16 @@ _Jv_JNI_SetStaticField (JNIEnv *, jclass, jfieldID field, T value)
static jstring static jstring
_Jv_JNI_NewString (JNIEnv *env, const jchar *unichars, jsize len) _Jv_JNI_NewString (JNIEnv *env, const jchar *unichars, jsize len)
{ {
// FIXME: exception processing. try
jstring r = _Jv_NewString (unichars, len); {
return (jstring) wrap_value (env, r); jstring r = _Jv_NewString (unichars, len);
return (jstring) wrap_value (env, r);
}
catch (jthrowable t)
{
env->ex = t;
return NULL;
}
} }
static jsize static jsize
@ -990,9 +1074,16 @@ _Jv_JNI_ReleaseStringChars (JNIEnv *, jstring string, const jchar *)
static jstring static jstring
_Jv_JNI_NewStringUTF (JNIEnv *env, const char *bytes) _Jv_JNI_NewStringUTF (JNIEnv *env, const char *bytes)
{ {
// FIXME: exception processing. try
jstring result = JvNewStringUTF (bytes); {
return (jstring) wrap_value (env, result); jstring result = JvNewStringUTF (bytes);
return (jstring) wrap_value (env, result);
}
catch (jthrowable t)
{
env->ex = t;
return NULL;
}
} }
static jsize static jsize
@ -1002,18 +1093,25 @@ _Jv_JNI_GetStringUTFLength (JNIEnv *, jstring string)
} }
static const char * static const char *
_Jv_JNI_GetStringUTFChars (JNIEnv *, jstring string, jboolean *isCopy) _Jv_JNI_GetStringUTFChars (JNIEnv *env, jstring string, jboolean *isCopy)
{ {
jsize len = JvGetStringUTFLength (string); jsize len = JvGetStringUTFLength (string);
// FIXME: exception processing. try
char *r = (char *) _Jv_Malloc (len + 1); {
JvGetStringUTFRegion (string, 0, len, r); char *r = (char *) _Jv_Malloc (len + 1);
r[len] = '\0'; JvGetStringUTFRegion (string, 0, len, r);
r[len] = '\0';
if (isCopy) if (isCopy)
*isCopy = true; *isCopy = true;
return (const char *) r; return (const char *) r;
}
catch (jthrowable t)
{
env->ex = t;
return NULL;
}
} }
static void static void
@ -1029,7 +1127,16 @@ _Jv_JNI_GetStringRegion (JNIEnv *env, jstring string, jsize start, jsize len,
jchar *result = _Jv_GetStringChars (string); jchar *result = _Jv_GetStringChars (string);
if (start < 0 || start > string->length () if (start < 0 || start > string->length ()
|| len < 0 || start + len > string->length ()) || len < 0 || start + len > string->length ())
env->ex = new java::lang::StringIndexOutOfBoundsException (); {
try
{
env->ex = new java::lang::StringIndexOutOfBoundsException ();
}
catch (jthrowable t)
{
env->ex = t;
}
}
else else
memcpy (buf, &result[start], len * sizeof (jchar)); memcpy (buf, &result[start], len * sizeof (jchar));
} }
@ -1040,7 +1147,16 @@ _Jv_JNI_GetStringUTFRegion (JNIEnv *env, jstring str, jsize start,
{ {
if (start < 0 || start > str->length () if (start < 0 || start > str->length ()
|| len < 0 || start + len > str->length ()) || len < 0 || start + len > str->length ())
env->ex = new java::lang::StringIndexOutOfBoundsException (); {
try
{
env->ex = new java::lang::StringIndexOutOfBoundsException ();
}
catch (jthrowable t)
{
env->ex = t;
}
}
else else
_Jv_GetStringUTFRegion (str, start, len, buf); _Jv_GetStringUTFRegion (str, start, len, buf);
} }
@ -1070,9 +1186,16 @@ static jarray
_Jv_JNI_NewObjectArray (JNIEnv *env, jsize length, jclass elementClass, _Jv_JNI_NewObjectArray (JNIEnv *env, jsize length, jclass elementClass,
jobject init) jobject init)
{ {
// FIXME: exception processing. try
jarray result = JvNewObjectArray (length, elementClass, init); {
return (jarray) wrap_value (env, result); jarray result = JvNewObjectArray (length, elementClass, init);
return (jarray) wrap_value (env, result);
}
catch (jthrowable t)
{
env->ex = t;
return NULL;
}
} }
static jobject static jobject
@ -1083,21 +1206,34 @@ _Jv_JNI_GetObjectArrayElement (JNIEnv *env, jobjectArray array, jsize index)
} }
static void static void
_Jv_JNI_SetObjectArrayElement (JNIEnv *, jobjectArray array, jsize index, _Jv_JNI_SetObjectArrayElement (JNIEnv *env, jobjectArray array, jsize index,
jobject value) jobject value)
{ {
// FIXME: exception processing. try
_Jv_CheckArrayStore (array, value); {
jobject *elts = elements (array); _Jv_CheckArrayStore (array, value);
elts[index] = value; jobject *elts = elements (array);
elts[index] = value;
}
catch (jthrowable t)
{
env->ex = t;
}
} }
template<typename T, jclass K> template<typename T, jclass K>
static JArray<T> * static JArray<T> *
_Jv_JNI_NewPrimitiveArray (JNIEnv *env, jsize length) _Jv_JNI_NewPrimitiveArray (JNIEnv *env, jsize length)
{ {
// FIXME: exception processing. try
return (JArray<T> *) wrap_value (env, _Jv_NewPrimArray (K, length)); {
return (JArray<T> *) wrap_value (env, _Jv_NewPrimArray (K, length));
}
catch (jthrowable t)
{
env->ex = t;
return NULL;
}
} }
template<typename T> template<typename T>
@ -1134,8 +1270,16 @@ _Jv_JNI_GetPrimitiveArrayRegion (JNIEnv *env, JArray<T> *array,
{ {
if (start < 0 || len >= array->length || start + len >= array->length) if (start < 0 || len >= array->length || start + len >= array->length)
{ {
// FIXME: index. try
env->ex = new java::lang::ArrayIndexOutOfBoundsException (); {
// FIXME: index.
env->ex = new java::lang::ArrayIndexOutOfBoundsException ();
}
catch (jthrowable t)
{
// Could have thown out of memory error.
env->ex = t;
}
} }
else else
{ {
@ -1151,8 +1295,15 @@ _Jv_JNI_SetPrimitiveArrayRegion (JNIEnv *env, JArray<T> *array,
{ {
if (start < 0 || len >= array->length || start + len >= array->length) if (start < 0 || len >= array->length || start + len >= array->length)
{ {
// FIXME: index. try
env->ex = new java::lang::ArrayIndexOutOfBoundsException (); {
// FIXME: index.
env->ex = new java::lang::ArrayIndexOutOfBoundsException ();
}
catch (jthrowable t)
{
env->ex = t;
}
} }
else else
{ {
@ -1181,19 +1332,31 @@ _Jv_JNI_ReleasePrimitiveArrayCritical (JNIEnv *, jarray, void *, jint)
} }
static jint static jint
_Jv_JNI_MonitorEnter (JNIEnv *, jobject obj) _Jv_JNI_MonitorEnter (JNIEnv *env, jobject obj)
{ {
// FIXME: exception processing. try
jint r = _Jv_MonitorEnter (obj); {
return r; return _Jv_MonitorEnter (obj);
}
catch (jthrowable t)
{
env->ex = t;
}
return JNI_ERR;
} }
static jint static jint
_Jv_JNI_MonitorExit (JNIEnv *, jobject obj) _Jv_JNI_MonitorExit (JNIEnv *env, jobject obj)
{ {
// FIXME: exception processing. try
jint r = _Jv_MonitorExit (obj); {
return r; return _Jv_MonitorExit (obj);
}
catch (jthrowable t)
{
env->ex = t;
}
return JNI_ERR;
} }
// JDK 1.2 // JDK 1.2
@ -1201,12 +1364,19 @@ jobject
_Jv_JNI_ToReflectedField (JNIEnv *env, jclass cls, jfieldID fieldID, _Jv_JNI_ToReflectedField (JNIEnv *env, jclass cls, jfieldID fieldID,
jboolean) jboolean)
{ {
// FIXME: exception processing. try
java::lang::reflect::Field *field = new java::lang::reflect::Field(); {
field->declaringClass = cls; java::lang::reflect::Field *field = new java::lang::reflect::Field();
field->offset = (char*) fieldID - (char *) cls->fields; field->declaringClass = cls;
field->name = _Jv_NewStringUtf8Const (fieldID->getNameUtf8Const (cls)); field->offset = (char*) fieldID - (char *) cls->fields;
return wrap_value (env, field); field->name = _Jv_NewStringUtf8Const (fieldID->getNameUtf8Const (cls));
return wrap_value (env, field);
}
catch (jthrowable t)
{
env->ex = t;
}
return NULL;
} }
// JDK 1.2 // JDK 1.2
@ -1228,21 +1398,29 @@ _Jv_JNI_ToReflectedMethod (JNIEnv *env, jclass klass, jmethodID id,
// FIXME. // FIXME.
static _Jv_Utf8Const *init_name = _Jv_makeUtf8Const ("<init>", 6); static _Jv_Utf8Const *init_name = _Jv_makeUtf8Const ("<init>", 6);
jobject result; jobject result = NULL;
if (_Jv_equalUtf8Consts (id->name, init_name))
try
{ {
// A constructor. if (_Jv_equalUtf8Consts (id->name, init_name))
Constructor *cons = new Constructor (); {
cons->offset = (char *) id - (char *) &klass->methods; // A constructor.
cons->declaringClass = klass; Constructor *cons = new Constructor ();
result = cons; cons->offset = (char *) id - (char *) &klass->methods;
cons->declaringClass = klass;
result = cons;
}
else
{
Method *meth = new Method ();
meth->offset = (char *) id - (char *) &klass->methods;
meth->declaringClass = klass;
result = meth;
}
} }
else catch (jthrowable t)
{ {
Method *meth = new Method (); env->ex = t;
meth->offset = (char *) id - (char *) &klass->methods;
meth->declaringClass = klass;
result = meth;
} }
return wrap_value (env, result); return wrap_value (env, result);
@ -1302,7 +1480,14 @@ _Jv_JNI_RegisterNatives (JNIEnv *env, jclass k,
if (! found) if (! found)
{ {
jstring m = JvNewStringUTF (methods[j].name); jstring m = JvNewStringUTF (methods[j].name);
_Jv_JNI_Throw (env, new java::lang::NoSuchMethodError (m)); try
{
env->ex =new java::lang::NoSuchMethodError (m);
}
catch (jthrowable t)
{
env->ex = t;
}
return JNI_ERR; return JNI_ERR;
} }
} }
@ -1545,7 +1730,14 @@ _Jv_JNI_AttachCurrentThread (JavaVM *, jstring name, void **penv, void *args)
// have been called simply to set the new JNIEnv. // have been called simply to set the new JNIEnv.
if (_Jv_ThreadCurrent () == NULL) if (_Jv_ThreadCurrent () == NULL)
{ {
(void) new gnu::gcj::jni::NativeThread (group, name); try
{
(void) new gnu::gcj::jni::NativeThread (group, name);
}
catch (jthrowable t)
{
return JNI_ERR;
}
} }
_Jv_SetCurrentJNIEnv (env); _Jv_SetCurrentJNIEnv (env);
@ -1567,8 +1759,19 @@ _Jv_JNI_DestroyJavaVM (JavaVM *vm)
JNIEnv *env; JNIEnv *env;
if (_Jv_ThreadCurrent () != NULL) if (_Jv_ThreadCurrent () != NULL)
{ {
jstring main_name;
// This sucks.
try
{
main_name = JvNewStringLatin1 ("main");
}
catch (jthrowable t)
{
return JNI_ERR;
}
jint r = _Jv_JNI_AttachCurrentThread (vm, jint r = _Jv_JNI_AttachCurrentThread (vm,
JvNewStringLatin1 ("main"), main_name,
reinterpret_cast<void **> (&env), reinterpret_cast<void **> (&env),
NULL); NULL);
if (r < 0) if (r < 0)