natClassLoader.cc (_Jv_PrepareCompiledClass): Call _Jv_PushClass.
2002-12-03 Andrew Haley <aph@redhat.com> * java/lang/natClassLoader.cc (_Jv_PrepareCompiledClass): Call _Jv_PushClass. (_Jv_InitNewClassFields): Set protectionDomain and chain = NULL. (_Jv_PopClass): New. (_Jv_PushClass): New. * java/lang/natClass.cc (forName (jstring)): Use a StackTrace to discover the ClassLoader of our caller. (_Jv_CheckArrayStore): Don't check that a class is assignment compatible with Object. * java/lang/natVMTHrowable.cc: Delete. * gnu/gcj/runtime/StackTrace.java: New, partly copied from java.lang.VMThrowable. (StackTrace(), StackTrace(int)): New constructors. (classAt, methodAt, update, methodAtAddress): New methods. (map): New field. * java/lang/VMThrowable.java: Use StackTrace instead of natVMTHrowable. * java/lang/Class.h (getClassLoaderInternal): New. (class Class): Be friendly with _Jv_PopClass and _Jv_PushClass. Be friendly with gnu::gcj::runtime::StackTrace. (Object.chain): New field. * include/java-interp.h (class _Jv_InterpMethod): Be friendly with gnu::gcj::runtime::StackTrace. * prims.cc (_Jv_NewObjectArray): Use getClassLoaderInternal() instead of getClassLoader(). * verify.cc (class _Jv_BytecodeVerifier): Likewise. java::lang::VMThrowable. * Makefile.am (core_java_source_files): Add MethodRef.java, StackTrace.java. (nat_source_files): Remove natVMThrowable.cc; add natStackTrace.cc. * Makefile.in: Rebuild. 2002-12-03 Andrew Haley <aph@redhat.com> * class.c (make_class_data): New field, "chain". * decl.c (java_init_decl_processing): Likewise. From-SVN: r59769
This commit is contained in:
parent
ee7ecb2924
commit
421f9e6091
12 changed files with 131 additions and 39 deletions
|
@ -20,6 +20,7 @@ details. */
|
|||
#include <java/lang/reflect/Modifier.h>
|
||||
#include <java/security/ProtectionDomain.h>
|
||||
#include <java/lang/Package.h>
|
||||
#include <gnu/gcj/runtime/StackTrace.h>
|
||||
|
||||
// We declare these here to avoid including gcj/cni.h.
|
||||
extern "C" void _Jv_InitClass (jclass klass);
|
||||
|
@ -138,6 +139,13 @@ public:
|
|||
|
||||
java::lang::ClassLoader *getClassLoader (void);
|
||||
|
||||
// This is an internal method that circumvents the usual security
|
||||
// checks when getting the class loader.
|
||||
java::lang::ClassLoader *getClassLoaderInternal (void)
|
||||
{
|
||||
return loader;
|
||||
}
|
||||
|
||||
java::lang::reflect::Constructor *getConstructor (JArray<jclass> *);
|
||||
JArray<java::lang::reflect::Constructor *> *getConstructors (void);
|
||||
java::lang::reflect::Constructor *getDeclaredConstructor (JArray<jclass> *);
|
||||
|
@ -296,6 +304,8 @@ private:
|
|||
java::lang::ClassLoader *loader);
|
||||
friend jclass _Jv_FindClassInCache (_Jv_Utf8Const *name,
|
||||
java::lang::ClassLoader *loader);
|
||||
friend jclass _Jv_PopClass (void);
|
||||
friend void _Jv_PushClass (jclass k);
|
||||
friend void _Jv_NewArrayClass (jclass element,
|
||||
java::lang::ClassLoader *loader,
|
||||
_Jv_VTable *array_vtable = 0);
|
||||
|
@ -349,6 +359,7 @@ private:
|
|||
#endif
|
||||
|
||||
friend class _Jv_BytecodeVerifier;
|
||||
friend class gnu::gcj::runtime::StackTrace;
|
||||
|
||||
// Chain for class pool.
|
||||
jclass next;
|
||||
|
@ -403,6 +414,8 @@ private:
|
|||
jclass arrayclass;
|
||||
// Security Domain to which this class belongs (or null).
|
||||
java::security::ProtectionDomain *protectionDomain;
|
||||
// Used by Jv_PopClass and _Jv_PushClass to communicate with StackTrace.
|
||||
jclass chain;
|
||||
};
|
||||
|
||||
#endif /* __JAVA_LANG_CLASS_H__ */
|
||||
|
|
|
@ -38,9 +38,10 @@ exception statement from your version. */
|
|||
package java.lang;
|
||||
|
||||
import gnu.gcj.runtime.NameFinder;
|
||||
import gnu.gcj.runtime.StackTrace;
|
||||
|
||||
/**
|
||||
* VM dependant state and support methods Throwabele.
|
||||
* VM dependent state and support methods Throwable.
|
||||
* It is deliberately package local and final and should only be accessed
|
||||
* by the Throwable class.
|
||||
* <p>
|
||||
|
@ -50,8 +51,7 @@ import gnu.gcj.runtime.NameFinder;
|
|||
*/
|
||||
final class VMThrowable
|
||||
{
|
||||
private gnu.gcj.RawData stackTraceAddrs;
|
||||
private int length;
|
||||
private gnu.gcj.runtime.StackTrace trace;
|
||||
|
||||
/**
|
||||
* Private contructor, create VMThrowables with fillInStackTrace();
|
||||
|
@ -67,7 +67,20 @@ final class VMThrowable
|
|||
* @return a new VMThrowable containing the current execution stack trace.
|
||||
* @see Throwable#fillInStackTrace()
|
||||
*/
|
||||
static native VMThrowable fillInStackTrace(Throwable t);
|
||||
static VMThrowable fillInStackTrace(Throwable t)
|
||||
{
|
||||
VMThrowable state = null;
|
||||
|
||||
/* FIXME: size of the stack trace is limited to 128 elements.
|
||||
It's undoubtedly sensible to limit the stack trace, but 128 is
|
||||
rather arbitrary. It may be better to configure this. */
|
||||
if (trace_enabled)
|
||||
{
|
||||
state = new VMThrowable ();
|
||||
state.trace = new gnu.gcj.runtime.StackTrace(128);
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an <code>StackTraceElement</code> array based on the execution
|
||||
|
@ -80,10 +93,11 @@ final class VMThrowable
|
|||
StackTraceElement[] getStackTrace(Throwable t)
|
||||
{
|
||||
StackTraceElement[] result;
|
||||
if (stackTraceAddrs != null)
|
||||
if (trace != null)
|
||||
{
|
||||
NameFinder nameFinder = new NameFinder();
|
||||
result = nameFinder.lookup(t, stackTraceAddrs, length);
|
||||
result = nameFinder.lookup(t, trace.stackTraceAddrs(),
|
||||
trace.length());
|
||||
nameFinder.close();
|
||||
}
|
||||
else
|
||||
|
|
|
@ -36,6 +36,7 @@ details. */
|
|||
#include <java/lang/IllegalAccessError.h>
|
||||
#include <java/lang/IllegalArgumentException.h>
|
||||
#include <java/lang/IncompatibleClassChangeError.h>
|
||||
#include <java/lang/ArrayIndexOutOfBoundsException.h>
|
||||
#include <java/lang/InstantiationException.h>
|
||||
#include <java/lang/NoClassDefFoundError.h>
|
||||
#include <java/lang/NoSuchFieldException.h>
|
||||
|
@ -47,7 +48,10 @@ details. */
|
|||
#include <java/lang/System.h>
|
||||
#include <java/lang/SecurityManager.h>
|
||||
#include <java/lang/StringBuffer.h>
|
||||
#include <gnu/gcj/runtime/StackTrace.h>
|
||||
#include <gcj/method.h>
|
||||
#include <gnu/gcj/runtime/MethodRef.h>
|
||||
#include <gnu/gcj/RawData.h>
|
||||
|
||||
#include <java-cpool.h>
|
||||
|
||||
|
@ -71,7 +75,6 @@ java::lang::Class::forName (jstring className, jboolean initialize,
|
|||
if (! _Jv_VerifyClassName (name))
|
||||
throw new java::lang::ClassNotFoundException (className);
|
||||
|
||||
// FIXME: should use bootstrap class loader if loader is null.
|
||||
jclass klass = (buffer[0] == '['
|
||||
? _Jv_FindClassFromSignature (name->data, loader)
|
||||
: _Jv_FindClass (name, loader));
|
||||
|
@ -88,8 +91,23 @@ java::lang::Class::forName (jstring className, jboolean initialize,
|
|||
jclass
|
||||
java::lang::Class::forName (jstring className)
|
||||
{
|
||||
// FIXME: should use class loader from calling method.
|
||||
return forName (className, true, NULL);
|
||||
java::lang::ClassLoader *loader = NULL;
|
||||
gnu::gcj::runtime::StackTrace *t
|
||||
= new gnu::gcj::runtime::StackTrace(4);
|
||||
java::lang::Class *klass = NULL;
|
||||
try
|
||||
{
|
||||
for (int i=1; !klass; i++)
|
||||
{
|
||||
klass = t->classAt (i);
|
||||
}
|
||||
loader = klass->getClassLoader();
|
||||
}
|
||||
catch (::java::lang::ArrayIndexOutOfBoundsException *e)
|
||||
{
|
||||
}
|
||||
|
||||
return forName (className, true, loader);
|
||||
}
|
||||
|
||||
java::lang::ClassLoader *
|
||||
|
@ -1040,6 +1058,8 @@ _Jv_CheckArrayStore (jobject arr, jobject obj)
|
|||
{
|
||||
JvAssert (arr != NULL);
|
||||
jclass elt_class = (JV_CLASS (arr))->getComponentType();
|
||||
if (elt_class == &java::lang::Object::class$)
|
||||
return;
|
||||
jclass obj_class = JV_CLASS (obj);
|
||||
if (__builtin_expect
|
||||
(! _Jv_IsAssignableFrom (elt_class, obj_class), false))
|
||||
|
|
|
@ -326,6 +326,8 @@ _Jv_PrepareCompiledClass (jclass klass)
|
|||
_Jv_LinkOffsetTable(klass);
|
||||
|
||||
klass->notifyAll ();
|
||||
|
||||
_Jv_PushClass (klass);
|
||||
}
|
||||
|
||||
|
||||
|
@ -587,6 +589,8 @@ _Jv_InitNewClassFields (jclass ret)
|
|||
ret->ancestors = NULL;
|
||||
ret->idt = NULL;
|
||||
ret->arrayclass = NULL;
|
||||
ret->protectionDomain = NULL;
|
||||
ret->chain = NULL;
|
||||
}
|
||||
|
||||
jclass
|
||||
|
@ -732,3 +736,31 @@ _Jv_NewArrayClass (jclass element, java::lang::ClassLoader *loader,
|
|||
|
||||
element->arrayclass = array_class;
|
||||
}
|
||||
|
||||
static jclass stack_head;
|
||||
|
||||
// These two functions form a stack of classes. When a class is loaded
|
||||
// it is pushed onto the stack by the class loader; this is so that
|
||||
// StackTrace can quickly determine which classes have been loaded.
|
||||
|
||||
jclass
|
||||
_Jv_PopClass (void)
|
||||
{
|
||||
JvSynchronize sync (&java::lang::Class::class$);
|
||||
if (stack_head)
|
||||
{
|
||||
jclass tmp = stack_head;
|
||||
stack_head = tmp->chain;
|
||||
return tmp;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
_Jv_PushClass (jclass k)
|
||||
{
|
||||
JvSynchronize sync (&java::lang::Class::class$);
|
||||
jclass tmp = stack_head;
|
||||
stack_head = k;
|
||||
k->chain = tmp;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue