* Merged gcj-abi-2-dev-branch to trunk.
(Actual changes too large to list in the commit message; see ChangeLog.) From-SVN: r91270
This commit is contained in:
parent
ec0641f612
commit
367390404d
70 changed files with 11301 additions and 3355 deletions
|
@ -121,15 +121,15 @@ public class ObjectInputStream extends InputStream
|
|||
*/
|
||||
public final Object readObject() throws ClassNotFoundException, IOException
|
||||
{
|
||||
if (callersClassLoader == null)
|
||||
{
|
||||
callersClassLoader = getCallersClassLoader ();
|
||||
if (Configuration.DEBUG && dump)
|
||||
{
|
||||
dumpElementln ("CallersClassLoader = " + callersClassLoader);
|
||||
}
|
||||
}
|
||||
|
||||
if (callersClassLoader == null)
|
||||
{
|
||||
callersClassLoader = getCallersClassLoader ();
|
||||
if (Configuration.DEBUG && dump)
|
||||
{
|
||||
dumpElementln ("CallersClassLoader = " + callersClassLoader);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.useSubclassMethod)
|
||||
return readObjectOverride();
|
||||
|
||||
|
@ -271,7 +271,7 @@ public class ObjectInputStream extends InputStream
|
|||
readArrayElements(array, componentType);
|
||||
if(dump)
|
||||
for (int i = 0, len = Array.getLength(array); i < len; i++)
|
||||
dumpElementln(" ELEMENT[" + i + "]=" + Array.get(array, i));
|
||||
dumpElementln(" ELEMENT[" + i + "]=" + Array.get(array, i));
|
||||
ret_val = processResolution(null, array, handle);
|
||||
break;
|
||||
}
|
||||
|
@ -398,6 +398,8 @@ public class ObjectInputStream extends InputStream
|
|||
setBlockDataMode(old_mode);
|
||||
|
||||
this.isDeserializing = was_deserializing;
|
||||
|
||||
depth -= 2;
|
||||
|
||||
depth -= 2;
|
||||
|
||||
|
@ -1806,6 +1808,7 @@ public class ObjectInputStream extends InputStream
|
|||
* @param sm SecurityManager instance which should be called.
|
||||
* @return The current class loader in the calling stack.
|
||||
*/
|
||||
|
||||
private static native ClassLoader currentClassLoader (SecurityManager sm);
|
||||
|
||||
private native ClassLoader getCallersClassLoader();
|
||||
|
@ -1875,7 +1878,7 @@ public class ObjectInputStream extends InputStream
|
|||
private int depth = 0;
|
||||
|
||||
private void dumpElement (String msg)
|
||||
{
|
||||
{
|
||||
System.out.print(msg);
|
||||
}
|
||||
|
||||
|
|
|
@ -347,8 +347,8 @@ public class ObjectOutputStream extends OutputStream
|
|||
fieldsAlreadyWritten = false;
|
||||
if (currentObjectStreamClass.hasWriteMethod())
|
||||
{
|
||||
if (dump)
|
||||
dumpElementln ("WRITE METHOD CALLED FOR: " + obj);
|
||||
if (dump)
|
||||
dumpElementln ("WRITE METHOD CALLED FOR: " + obj);
|
||||
setBlockDataMode(true);
|
||||
callWriteMethod(obj, currentObjectStreamClass);
|
||||
setBlockDataMode(false);
|
||||
|
@ -358,10 +358,10 @@ public class ObjectOutputStream extends OutputStream
|
|||
}
|
||||
else
|
||||
{
|
||||
if (dump)
|
||||
dumpElementln ("WRITE FIELDS CALLED FOR: " + obj);
|
||||
writeFields(obj, currentObjectStreamClass);
|
||||
}
|
||||
if (dump)
|
||||
dumpElementln ("WRITE FIELDS CALLED FOR: " + obj);
|
||||
writeFields(obj, currentObjectStreamClass);
|
||||
}
|
||||
}
|
||||
|
||||
this.currentObject = prevObject;
|
||||
|
|
|
@ -42,13 +42,15 @@ enum
|
|||
|
||||
JV_STATE_PRELOADING = 1, // Can do _Jv_FindClass.
|
||||
JV_STATE_LOADING = 3, // Has super installed.
|
||||
JV_STATE_COMPILED = 5, // This was a compiled class.
|
||||
JV_STATE_READ = 4, // Has been completely defined.
|
||||
JV_STATE_LOADED = 5, // Has Miranda methods defined.
|
||||
|
||||
JV_STATE_COMPILED = 6, // This was a compiled class.
|
||||
|
||||
JV_STATE_LOADED = 6, // Is complete.
|
||||
JV_STATE_PREPARED = 7, // Layout & static init done.
|
||||
JV_STATE_LINKED = 9, // Strings interned.
|
||||
|
||||
JV_STATE_IN_PROGRESS = 10, // <Clinit> running.
|
||||
JV_STATE_IN_PROGRESS = 10, // <clinit> running.
|
||||
|
||||
JV_STATE_ERROR = 12,
|
||||
|
||||
|
@ -59,6 +61,9 @@ struct _Jv_Field;
|
|||
struct _Jv_VTable;
|
||||
union _Jv_word;
|
||||
struct _Jv_ArrayVTable;
|
||||
class _Jv_ExecutionEngine;
|
||||
class _Jv_CompiledEngine;
|
||||
class _Jv_InterpreterEngine;
|
||||
|
||||
struct _Jv_Constants
|
||||
{
|
||||
|
@ -106,7 +111,7 @@ union _Jv_IDispatchTable
|
|||
} iface;
|
||||
};
|
||||
|
||||
// Used by _Jv_GetInterfaces ()
|
||||
// Used by _Jv_Linker::get_interfaces ()
|
||||
struct _Jv_ifaces
|
||||
{
|
||||
jclass *list;
|
||||
|
@ -139,6 +144,23 @@ struct _Jv_CatchClass
|
|||
_Jv_Utf8Const *classname;
|
||||
};
|
||||
|
||||
// Possible values for the assertion_code field in the type assertion table.
|
||||
enum
|
||||
{
|
||||
JV_ASSERT_END_OF_TABLE = 0,
|
||||
JV_ASSERT_TYPES_COMPATIBLE = 1,
|
||||
JV_ASSERT_IS_INSTANTIABLE = 2
|
||||
};
|
||||
|
||||
// Entry in the type assertion table, used to validate type constraints
|
||||
// for binary compatibility.
|
||||
struct _Jv_TypeAssertion
|
||||
{
|
||||
jint assertion_code;
|
||||
_Jv_Utf8Const *op1;
|
||||
_Jv_Utf8Const *op2;
|
||||
};
|
||||
|
||||
#define JV_PRIMITIVE_VTABLE ((_Jv_VTable *) -1)
|
||||
|
||||
#define JV_CLASS(Obj) ((jclass) (*(_Jv_VTable **) Obj)->clas)
|
||||
|
@ -149,11 +171,11 @@ struct _Jv_CatchClass
|
|||
_Jv_Method *_Jv_GetMethodLocal (jclass klass, _Jv_Utf8Const *name,
|
||||
_Jv_Utf8Const *signature);
|
||||
jboolean _Jv_IsAssignableFrom (jclass, jclass);
|
||||
jboolean _Jv_IsAssignableFromSlow (jclass, jclass);
|
||||
jboolean _Jv_InterfaceAssignableFrom (jclass, jclass);
|
||||
void _Jv_InitClass (jclass klass);
|
||||
|
||||
_Jv_Method* _Jv_LookupDeclaredMethod (jclass, _Jv_Utf8Const *,
|
||||
_Jv_Utf8Const*);
|
||||
_Jv_Utf8Const*, jclass * = NULL);
|
||||
jfieldID JvGetFirstInstanceField (jclass);
|
||||
jint JvNumInstanceFields (jclass);
|
||||
jfieldID JvGetFirstStaticField (jclass);
|
||||
|
@ -183,10 +205,6 @@ class java::io::ObjectOutputStream;
|
|||
class java::io::ObjectInputStream;
|
||||
class java::io::ObjectStreamClass;
|
||||
|
||||
void _Jv_WaitForState (jclass, int);
|
||||
void _Jv_RegisterClasses (const jclass *classes);
|
||||
void _Jv_RegisterClasses_Counted (const jclass *classes,
|
||||
size_t count);
|
||||
void _Jv_RegisterClassHookDefault (jclass klass);
|
||||
void _Jv_RegisterInitiatingLoader (jclass,java::lang::ClassLoader*);
|
||||
void _Jv_UnregisterClass (jclass);
|
||||
|
@ -205,19 +223,7 @@ void _Jv_InitNewClassFields (jclass klass);
|
|||
|
||||
// Friend functions and classes in prims.cc
|
||||
void _Jv_InitPrimClass (jclass, char *, char, int);
|
||||
void _Jv_PrepareCompiledClass (jclass);
|
||||
void _Jv_PrepareConstantTimeTables (jclass);
|
||||
jshort _Jv_GetInterfaces (jclass, _Jv_ifaces *);
|
||||
void _Jv_GenerateITable (jclass, _Jv_ifaces *, jshort *);
|
||||
jstring _Jv_GetMethodString (jclass, _Jv_Utf8Const *);
|
||||
jshort _Jv_AppendPartialITable (jclass, jclass, void **, jshort);
|
||||
jshort _Jv_FindIIndex (jclass *, jshort *, jshort);
|
||||
void _Jv_LinkSymbolTable (jclass);
|
||||
void _Jv_LayoutInterfaceMethods (jclass);
|
||||
void _Jv_LayoutVTableMethods (jclass klass);
|
||||
void _Jv_SetVTableEntries (jclass, _Jv_VTable *, jboolean *);
|
||||
void _Jv_MakeVTable (jclass);
|
||||
void _Jv_linkExceptionClassTable (jclass);
|
||||
|
||||
jboolean _Jv_CheckAccess (jclass self_klass, jclass other_klass,
|
||||
jint flags);
|
||||
|
@ -225,25 +231,14 @@ jclass _Jv_GetArrayClass (jclass klass, java::lang::ClassLoader *loader);
|
|||
|
||||
#ifdef INTERPRETER
|
||||
jboolean _Jv_IsInterpretedClass (jclass);
|
||||
void _Jv_InitField (jobject, jclass, _Jv_Field*);
|
||||
void _Jv_InitField (jobject, jclass, int);
|
||||
_Jv_word _Jv_ResolvePoolEntry (jclass, int);
|
||||
_Jv_Method *_Jv_SearchMethodInClass (jclass cls, jclass klass,
|
||||
_Jv_Utf8Const *method_name,
|
||||
_Jv_Utf8Const *method_signature);
|
||||
|
||||
void _Jv_PrepareClass (jclass);
|
||||
void _Jv_PrepareMissingMethods (jclass base, jclass iface_class);
|
||||
|
||||
void _Jv_Defer_Resolution (void *cl, _Jv_Method *meth, void **);
|
||||
|
||||
class _Jv_ClassReader;
|
||||
class _Jv_InterpClass;
|
||||
class _Jv_InterpMethod;
|
||||
#endif
|
||||
|
||||
class _Jv_BytecodeVerifier;
|
||||
class _Jv_StackTrace;
|
||||
class gnu::gcj::runtime::StackTrace;
|
||||
class java::io::VMObjectStreamClass;
|
||||
|
||||
|
@ -316,9 +311,14 @@ public:
|
|||
void setSigners(JArray<jobject> *);
|
||||
|
||||
inline jclass getSuperclass (void)
|
||||
{
|
||||
return superclass;
|
||||
}
|
||||
{
|
||||
return superclass;
|
||||
}
|
||||
|
||||
inline jclass getInterface (jint n)
|
||||
{
|
||||
return interfaces[n];
|
||||
}
|
||||
|
||||
inline jboolean isArray (void)
|
||||
{
|
||||
|
@ -351,9 +351,16 @@ public:
|
|||
|
||||
// FIXME: this probably shouldn't be public.
|
||||
jint size (void)
|
||||
{
|
||||
return size_in_bytes;
|
||||
}
|
||||
{
|
||||
return size_in_bytes;
|
||||
}
|
||||
|
||||
// The index of the first method we declare ourself (as opposed to
|
||||
// inheriting).
|
||||
inline jint firstMethodIndex (void)
|
||||
{
|
||||
return vtable_method_count - method_count;
|
||||
}
|
||||
|
||||
// finalization
|
||||
void finalize ();
|
||||
|
@ -372,10 +379,17 @@ private:
|
|||
|
||||
static jstring getPackagePortion (jstring);
|
||||
|
||||
void set_state (jint nstate)
|
||||
{
|
||||
state = nstate;
|
||||
notifyAll ();
|
||||
}
|
||||
|
||||
// Friend functions implemented in natClass.cc.
|
||||
friend _Jv_Method *::_Jv_GetMethodLocal (jclass klass, _Jv_Utf8Const *name,
|
||||
_Jv_Utf8Const *signature);
|
||||
friend jboolean (::_Jv_IsAssignableFrom) (jclass, jclass);
|
||||
friend jboolean (::_Jv_IsAssignableFromSlow) (jclass, jclass);
|
||||
friend jboolean (::_Jv_InterfaceAssignableFrom) (jclass, jclass);
|
||||
friend void *::_Jv_LookupInterfaceMethodIdx (jclass klass, jclass iface,
|
||||
int method_idx);
|
||||
|
@ -383,7 +397,7 @@ private:
|
|||
friend void ::_Jv_InitClass (jclass klass);
|
||||
|
||||
friend _Jv_Method* ::_Jv_LookupDeclaredMethod (jclass, _Jv_Utf8Const *,
|
||||
_Jv_Utf8Const*);
|
||||
_Jv_Utf8Const*, jclass *);
|
||||
friend jfieldID (::JvGetFirstInstanceField) (jclass);
|
||||
friend jint (::JvNumInstanceFields) (jclass);
|
||||
friend jfieldID (::JvGetFirstStaticField) (jclass);
|
||||
|
@ -413,7 +427,6 @@ private:
|
|||
friend class java::io::ObjectInputStream;
|
||||
friend class java::io::ObjectStreamClass;
|
||||
|
||||
friend void ::_Jv_WaitForState (jclass, int);
|
||||
friend void ::_Jv_RegisterClasses (const jclass *classes);
|
||||
friend void ::_Jv_RegisterClasses_Counted (const jclass *classes,
|
||||
size_t count);
|
||||
|
@ -436,40 +449,22 @@ private:
|
|||
// in prims.cc
|
||||
friend void ::_Jv_InitPrimClass (jclass, char *, char, int);
|
||||
|
||||
friend void ::_Jv_PrepareCompiledClass (jclass);
|
||||
friend void ::_Jv_PrepareConstantTimeTables (jclass);
|
||||
friend jshort (::_Jv_GetInterfaces) (jclass, _Jv_ifaces *);
|
||||
friend void ::_Jv_GenerateITable (jclass, _Jv_ifaces *, jshort *);
|
||||
friend jstring (::_Jv_GetMethodString) (jclass, _Jv_Utf8Const *);
|
||||
friend jshort (::_Jv_AppendPartialITable) (jclass, jclass, void **, jshort);
|
||||
friend jshort (::_Jv_FindIIndex) (jclass *, jshort *, jshort);
|
||||
friend void ::_Jv_LinkSymbolTable (jclass);
|
||||
friend void ::_Jv_LayoutInterfaceMethods (jclass);
|
||||
friend void ::_Jv_LayoutVTableMethods (jclass klass);
|
||||
friend void ::_Jv_SetVTableEntries (jclass, _Jv_VTable *, jboolean *);
|
||||
friend void ::_Jv_MakeVTable (jclass);
|
||||
friend void ::_Jv_linkExceptionClassTable (jclass);
|
||||
|
||||
friend jboolean (::_Jv_CheckAccess) (jclass self_klass, jclass other_klass,
|
||||
jint flags);
|
||||
|
||||
friend bool _Jv_getInterfaceMethod(jclass, jclass&, int&,
|
||||
const _Jv_Utf8Const*,
|
||||
const _Jv_Utf8Const*);
|
||||
|
||||
friend jclass (::_Jv_GetArrayClass) (jclass klass,
|
||||
java::lang::ClassLoader *loader);
|
||||
|
||||
#ifdef INTERPRETER
|
||||
friend jboolean (::_Jv_IsInterpretedClass) (jclass);
|
||||
friend void ::_Jv_InitField (jobject, jclass, _Jv_Field*);
|
||||
friend void ::_Jv_InitField (jobject, jclass, int);
|
||||
friend _Jv_word (::_Jv_ResolvePoolEntry) (jclass, int);
|
||||
friend _Jv_Method *::_Jv_SearchMethodInClass (jclass cls, jclass klass,
|
||||
_Jv_Utf8Const *method_name,
|
||||
_Jv_Utf8Const *method_signature);
|
||||
|
||||
friend void ::_Jv_PrepareClass (jclass);
|
||||
friend void ::_Jv_PrepareMissingMethods (jclass base, jclass iface_class);
|
||||
|
||||
friend void ::_Jv_Defer_Resolution (void *cl, _Jv_Method *meth, void **);
|
||||
|
||||
friend class ::_Jv_ClassReader;
|
||||
friend class ::_Jv_InterpClass;
|
||||
friend class ::_Jv_InterpMethod;
|
||||
|
@ -480,10 +475,14 @@ private:
|
|||
#endif
|
||||
|
||||
friend class ::_Jv_BytecodeVerifier;
|
||||
friend class ::_Jv_StackTrace;
|
||||
friend class gnu::gcj::runtime::StackTrace;
|
||||
friend class java::io::VMObjectStreamClass;
|
||||
|
||||
friend class _Jv_Linker;
|
||||
friend class _Jv_ExecutionEngine;
|
||||
friend class _Jv_CompiledEngine;
|
||||
friend class _Jv_InterpreterEngine;
|
||||
|
||||
friend void ::_Jv_sharedlib_register_hook (jclass klass);
|
||||
|
||||
// Chain for class pool.
|
||||
|
@ -518,8 +517,12 @@ private:
|
|||
_Jv_OffsetTable *otable;
|
||||
// Offset table symbols.
|
||||
_Jv_MethodSymbol *otable_syms;
|
||||
// Address table
|
||||
_Jv_AddressTable *atable;
|
||||
_Jv_MethodSymbol *atable_syms;
|
||||
// Interface table
|
||||
_Jv_AddressTable *itable;
|
||||
_Jv_MethodSymbol *itable_syms;
|
||||
_Jv_CatchClass *catch_classes;
|
||||
// Interfaces implemented by this class.
|
||||
jclass *interfaces;
|
||||
|
@ -542,13 +545,17 @@ private:
|
|||
jclass arrayclass;
|
||||
// Security Domain to which this class belongs (or null).
|
||||
java::security::ProtectionDomain *protectionDomain;
|
||||
// Pointer to the type assertion table for this class.
|
||||
_Jv_TypeAssertion *assertion_table;
|
||||
// Signers of this class (or null).
|
||||
JArray<jobject> *hack_signers;
|
||||
// Used by Jv_PopClass and _Jv_PushClass to communicate with StackTrace.
|
||||
jclass chain;
|
||||
// Additional data, specific to the generator (JIT, native, interpreter) of this
|
||||
// class.
|
||||
// Additional data, specific to the generator (JIT, native,
|
||||
// interpreter) of this class.
|
||||
void *aux_info;
|
||||
// Execution engine.
|
||||
_Jv_ExecutionEngine *engine;
|
||||
};
|
||||
|
||||
// Inline functions that are friends of java::lang::Class
|
||||
|
|
|
@ -288,6 +288,8 @@ public abstract class ClassLoader
|
|||
if (c != null)
|
||||
return c;
|
||||
|
||||
ClassNotFoundException ex = null;
|
||||
|
||||
// Can the class be loaded by a parent?
|
||||
try
|
||||
{
|
||||
|
@ -304,9 +306,20 @@ public abstract class ClassLoader
|
|||
}
|
||||
catch (ClassNotFoundException e)
|
||||
{
|
||||
ex = e;
|
||||
}
|
||||
// Still not found, we have to do it ourself.
|
||||
c = findClass(name);
|
||||
try
|
||||
{
|
||||
c = findClass(name);
|
||||
}
|
||||
catch (ClassNotFoundException cause)
|
||||
{
|
||||
if (ex != null)
|
||||
throw new ClassNotFoundException(ex.toString(), cause);
|
||||
else
|
||||
throw cause;
|
||||
}
|
||||
if (resolve)
|
||||
resolveClass(c);
|
||||
return c;
|
||||
|
@ -435,8 +448,9 @@ public abstract class ClassLoader
|
|||
domain = defaultProtectionDomain;
|
||||
if (! initialized)
|
||||
throw new SecurityException("attempt to define class from uninitialized class loader");
|
||||
|
||||
Class retval = VMClassLoader.defineClass(this, name, data,
|
||||
offset, len, domain);
|
||||
offset, len, domain);
|
||||
loadedClasses.put(retval.getName(), retval);
|
||||
return retval;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* Compiler.java -- placeholder for Java-to-native runtime compilers
|
||||
Copyright (C) 1998, 1999, 2001, 2002 Free Software Foundation, Inc.
|
||||
Copyright (C) 1998, 1999, 2001, 2002, 2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
|
@ -76,8 +76,7 @@ public final class Compiler
|
|||
*/
|
||||
public static boolean compileClass(Class oneClass)
|
||||
{
|
||||
// Never succeed.
|
||||
return false;
|
||||
return VMCompiler.compileClass(oneClass);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -90,8 +89,7 @@ public final class Compiler
|
|||
*/
|
||||
public static boolean compileClasses(String classNames)
|
||||
{
|
||||
// Note the incredibly lame interface. Always fail.
|
||||
return false;
|
||||
return VMCompiler.compileClasses(classNames);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -105,8 +103,7 @@ public final class Compiler
|
|||
*/
|
||||
public static Object command(Object arg)
|
||||
{
|
||||
// Our implementation defines this to a no-op.
|
||||
return null;
|
||||
return VMCompiler.command(arg);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -116,6 +113,7 @@ public final class Compiler
|
|||
*/
|
||||
public static void enable()
|
||||
{
|
||||
VMCompiler.enable();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -124,5 +122,6 @@ public final class Compiler
|
|||
*/
|
||||
public static void disable()
|
||||
{
|
||||
VMCompiler.disable();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -324,7 +324,7 @@ public class SecurityManager
|
|||
public void checkPermission(Permission perm)
|
||||
{
|
||||
// XXX Should be: AccessController.checkPermission(perm);
|
||||
throw new SecurityException("Operation not allowed");
|
||||
//.throw new SecurityException("Operation not allowed");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -553,7 +553,7 @@ public class SecurityManager
|
|||
// throw new SecurityException("Missing context");
|
||||
// AccessControlContext ac = (AccessControlContext) context;
|
||||
// ac.checkPermission(new FilePermission(filename, "read"));
|
||||
throw new SecurityException("Cannot read files via file names.");
|
||||
// throw new SecurityException("Cannot read files via file names.");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -677,7 +677,7 @@ public class SecurityManager
|
|||
// // Use the toString() hack to do the null check.
|
||||
// ac.checkPermission(new SocketPermission(host.toString + ":" +port,
|
||||
// "connect"));
|
||||
throw new SecurityException("Cannot make network connections.");
|
||||
// throw new SecurityException("Cannot make network connections.");
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -97,44 +97,31 @@ final class VMClassLoader
|
|||
ProtectionDomain pd)
|
||||
throws ClassFormatError;
|
||||
|
||||
static final native void linkClass0 (Class klass);
|
||||
static final native void markClassErrorState0 (Class klass);
|
||||
|
||||
/**
|
||||
* Helper to resolve all references to other classes from this class.
|
||||
*
|
||||
* @param c the class to resolve
|
||||
*/
|
||||
static final void resolveClass(Class clazz)
|
||||
{
|
||||
synchronized (clazz)
|
||||
{
|
||||
try
|
||||
{
|
||||
linkClass0 (clazz);
|
||||
}
|
||||
catch (Throwable x)
|
||||
{
|
||||
markClassErrorState0 (clazz);
|
||||
static final native void resolveClass(Class clazz);
|
||||
|
||||
LinkageError e;
|
||||
if (x instanceof LinkageError)
|
||||
e = (LinkageError) x;
|
||||
else if (x instanceof ClassNotFoundException)
|
||||
{
|
||||
e = new NoClassDefFoundError("while resolving class: "
|
||||
+ clazz.getName());
|
||||
e.initCause (x);
|
||||
}
|
||||
else
|
||||
{
|
||||
e = new LinkageError ("unexpected exception during linking: "
|
||||
+ clazz.getName());
|
||||
e.initCause (x);
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
static final void transformException(Class clazz, Throwable x)
|
||||
{
|
||||
LinkageError e;
|
||||
if (x instanceof LinkageError)
|
||||
e = (LinkageError) x;
|
||||
else if (x instanceof ClassNotFoundException)
|
||||
{
|
||||
e = new NoClassDefFoundError("while resolving class: "
|
||||
+ clazz.getName());
|
||||
e.initCause (x);
|
||||
}
|
||||
else
|
||||
{
|
||||
e = new LinkageError ("unexpected exception during linking: "
|
||||
+ clazz.getName());
|
||||
e.initCause (x);
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
332
libjava/java/lang/VMCompiler.java
Normal file
332
libjava/java/lang/VMCompiler.java
Normal file
|
@ -0,0 +1,332 @@
|
|||
/* VMClassLoader.java -- Reference implementation of compiler interface
|
||||
Copyright (C) 2004 Free Software Foundation
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||
02111-1307 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
package java.lang;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.ProtectionDomain;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.WeakHashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Enumeration;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.Vector;
|
||||
import gnu.gcj.runtime.SharedLibHelper;
|
||||
import gnu.gcj.runtime.PersistentByteMap;
|
||||
|
||||
/**
|
||||
* This class is just a per-VM reflection of java.lang.Compiler.
|
||||
* All methods are defined identically.
|
||||
*/
|
||||
final class VMCompiler
|
||||
{
|
||||
// True if we want to use gcj-jit.
|
||||
public static boolean useCompiler = true;
|
||||
|
||||
// True if we're able to use gcj-jit.
|
||||
public static final boolean canUseCompiler;
|
||||
|
||||
// Compiler to use.
|
||||
public static String gcjJitCompiler;
|
||||
|
||||
// Compiler options.
|
||||
public static String gcjJitCompilerOptions;
|
||||
|
||||
// Temporary directory to use.
|
||||
public static String gcjJitTmpdir;
|
||||
|
||||
// This maps a ClassLoader to a set of SharedLibHelper objects that
|
||||
// it has used. We do things this way to ensure that a
|
||||
// SharedLibHelper is collected if and only if the ClassLoader is.
|
||||
private static WeakHashMap sharedHelperMap = new WeakHashMap();
|
||||
|
||||
private static Vector precompiledMapFiles;
|
||||
|
||||
static
|
||||
{
|
||||
gcjJitCompiler = System.getProperty("gnu.gcj.jit.compiler");
|
||||
if (gcjJitCompiler == null)
|
||||
canUseCompiler = false;
|
||||
else
|
||||
{
|
||||
gcjJitCompilerOptions = System.getProperty("gnu.gcj.jit.options",
|
||||
"-g");
|
||||
gcjJitTmpdir = System.getProperty("gnu.gcj.jit.cachedir");
|
||||
// Note that we *don't* choose java.io.tmpdir as a default --
|
||||
// that would allow easy attacks against the VM.
|
||||
if (gcjJitTmpdir == null)
|
||||
canUseCompiler = false;
|
||||
else
|
||||
canUseCompiler = true;
|
||||
}
|
||||
|
||||
String prop = System.getProperty ("gnu.gcj.precompiled.db.path");
|
||||
if (prop != null)
|
||||
{
|
||||
precompiledMapFiles = new Vector();
|
||||
// Add the
|
||||
StringTokenizer st
|
||||
= new StringTokenizer (prop,
|
||||
System.getProperty ("path.separator", ":"));
|
||||
{
|
||||
while (st.hasMoreElements ())
|
||||
{
|
||||
String e = st.nextToken ();
|
||||
try
|
||||
{
|
||||
PersistentByteMap map
|
||||
= new PersistentByteMap
|
||||
(e, PersistentByteMap.AccessMode.READ_ONLY);
|
||||
precompiledMapFiles.add(map);
|
||||
}
|
||||
catch (IllegalArgumentException _)
|
||||
{
|
||||
// Not a map file
|
||||
}
|
||||
catch (java.io.IOException _)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Don't allow new `Compiler's to be made.
|
||||
*/
|
||||
private VMCompiler()
|
||||
{
|
||||
}
|
||||
|
||||
private static Class loadSharedLibrary(ClassLoader loader,
|
||||
String fileName,
|
||||
ProtectionDomain domain,
|
||||
String className)
|
||||
{
|
||||
Class c = null;
|
||||
SharedLibHelper helper
|
||||
= SharedLibHelper.findHelper (loader, fileName, domain.getCodeSource());
|
||||
c = helper.findClass (className);
|
||||
if (c != null)
|
||||
{
|
||||
HashSet hs = (HashSet) sharedHelperMap.get(loader);
|
||||
if (hs == null)
|
||||
{
|
||||
hs = new HashSet();
|
||||
sharedHelperMap.put(loader, hs);
|
||||
}
|
||||
hs.add(helper);
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile a class given the bytes for it. Returns the Class, or
|
||||
* null if compilation failed or otherwise could not be done.
|
||||
*/
|
||||
public static Class compileClass(ClassLoader loader,
|
||||
String name, byte[] data,
|
||||
int offset, int len,
|
||||
ProtectionDomain domain)
|
||||
{
|
||||
if (precompiledMapFiles == null
|
||||
&& (! useCompiler || ! canUseCompiler))
|
||||
return null;
|
||||
|
||||
byte digest[];
|
||||
|
||||
try
|
||||
{
|
||||
MessageDigest md = MessageDigest.getInstance("MD5");
|
||||
digest = md.digest(data);
|
||||
}
|
||||
catch (NoSuchAlgorithmException _)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// We use lookaside cache files to determine whether these bytes
|
||||
// correspond to a class file that is part of a precompiled DSO.
|
||||
if (precompiledMapFiles != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
Enumeration elements = precompiledMapFiles.elements();
|
||||
while (elements.hasMoreElements())
|
||||
{
|
||||
PersistentByteMap map = (PersistentByteMap)elements.nextElement();
|
||||
byte[] soName = map.get(digest);
|
||||
if (soName != null)
|
||||
return loadSharedLibrary(loader,
|
||||
new String(soName),
|
||||
domain, name);
|
||||
}
|
||||
}
|
||||
catch (Exception _)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
if (! useCompiler || ! canUseCompiler)
|
||||
return null;
|
||||
|
||||
try
|
||||
{
|
||||
// FIXME: Make sure that the class represented by the
|
||||
// bytes in DATA really is the class named in NAME. Make
|
||||
// sure it's not "java.*".
|
||||
StringBuffer hexBytes = new StringBuffer(gcjJitTmpdir);
|
||||
hexBytes.append(File.separatorChar);
|
||||
int digestLength = digest.length;
|
||||
for (int i = 0; i < digestLength; ++i)
|
||||
hexBytes.append(Integer.toHexString(digest[i] & 0xff));
|
||||
|
||||
// FIXME: use System.mapLibraryName?
|
||||
// I'm thinking we should use that, plus a class specified
|
||||
// via a property that determines lookup policy.
|
||||
File soFile = new File(hexBytes + ".so");
|
||||
if (soFile.isFile())
|
||||
return loadSharedLibrary (loader, soFile.toString(), domain,
|
||||
name);
|
||||
|
||||
File classFile = new File(hexBytes + ".class");
|
||||
classFile.delete();
|
||||
if (classFile.createNewFile() != true)
|
||||
return null;
|
||||
|
||||
FileOutputStream f = new FileOutputStream (classFile);
|
||||
// FIXME: race condition if bytes change... ?
|
||||
f.write(data, offset, len);
|
||||
|
||||
// Invoke the compiler.
|
||||
StringBuffer command = new StringBuffer(gcjJitCompiler);
|
||||
command.append(" ");
|
||||
command.append(classFile);
|
||||
command.append(" ");
|
||||
command.append(gcjJitCompilerOptions);
|
||||
// These options are required.
|
||||
command.append(" -findirect-dispatch -fjni -shared -fPIC -o ");
|
||||
command.append(soFile);
|
||||
Process p = Runtime.getRuntime().exec(command.toString());
|
||||
|
||||
// Read the process' stderr into a string.
|
||||
StringBuffer err = new StringBuffer();
|
||||
InputStreamReader stderr = new InputStreamReader (p.getErrorStream());
|
||||
char[] inBuf = new char[500];
|
||||
int bytesRead;
|
||||
while ((bytesRead = stderr.read (inBuf)) != -1)
|
||||
err.append(inBuf, 0, bytesRead);
|
||||
|
||||
if (p.waitFor() != 0)
|
||||
{
|
||||
// FIXME: we could log err.toString() somewhere...
|
||||
return null;
|
||||
}
|
||||
|
||||
return loadSharedLibrary(loader, soFile.toString(), domain, name);
|
||||
}
|
||||
catch (Exception _)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the class named by <code>oneClass</code>.
|
||||
*
|
||||
* @param oneClass the class to compile
|
||||
* @return <code>false</code> if no compiler is available or
|
||||
* compilation failed, <code>true</code> if compilation succeeded
|
||||
* @throws NullPointerException if oneClass is null
|
||||
*/
|
||||
public static boolean compileClass(Class oneClass)
|
||||
{
|
||||
// Never succeed.
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile the classes whose name matches <code>classNames</code>.
|
||||
*
|
||||
* @param classNames the name of classes to compile
|
||||
* @return <code>false</code> if no compiler is available or
|
||||
* compilation failed, <code>true</code> if compilation succeeded
|
||||
* @throws NullPointerException if classNames is null
|
||||
*/
|
||||
public static boolean compileClasses(String classNames)
|
||||
{
|
||||
// Note the incredibly lame interface. Always fail.
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method examines the argument and performs an operation
|
||||
* according to the compilers documentation. No specific operation
|
||||
* is required.
|
||||
*
|
||||
* @param arg a compiler-specific argument
|
||||
* @return a compiler-specific value, including null
|
||||
* @throws NullPointerException if the compiler doesn't like a null arg
|
||||
*/
|
||||
public static Object command(Object arg)
|
||||
{
|
||||
// Our implementation defines this to a no-op.
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calling <code>Compiler.enable()</code> will cause the compiler
|
||||
* to resume operation if it was previously disabled; provided that a
|
||||
* compiler even exists.
|
||||
*/
|
||||
public static void enable()
|
||||
{
|
||||
useCompiler = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calling <code>Compiler.disable()</code> will cause the compiler
|
||||
* to be suspended; provided that a compiler even exists.
|
||||
*/
|
||||
public static void disable()
|
||||
{
|
||||
useCompiler = false;
|
||||
}
|
||||
}
|
|
@ -54,11 +54,12 @@ class VMSecurityManager
|
|||
// The docs above are wrong. See the online docs.
|
||||
// FIXME this implementation is a bit wrong too -- the docs say we
|
||||
// must also consider ancestors of the system class loader.
|
||||
ClassLoader systemClassLoader = VMClassLoader.getSystemClassLoader();
|
||||
Class[] classStack = getClassContext ();
|
||||
for (int i = 0; i < classStack.length; i++)
|
||||
{
|
||||
ClassLoader loader = classStack[i].getClassLoader();
|
||||
if (loader != null)
|
||||
if (loader != null && loader != systemClassLoader)
|
||||
return loader;
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -18,6 +18,7 @@ details. */
|
|||
|
||||
#include <gcj/cni.h>
|
||||
#include <jvm.h>
|
||||
#include <execution.h>
|
||||
|
||||
#include <java-threads.h>
|
||||
#include <java-interp.h>
|
||||
|
@ -33,6 +34,7 @@ details. */
|
|||
#include <java/lang/ClassNotFoundException.h>
|
||||
#include <java/lang/ClassCircularityError.h>
|
||||
#include <java/lang/IncompatibleClassChangeError.h>
|
||||
#include <java/lang/ClassFormatError.h>
|
||||
#include <java/lang/VirtualMachineError.h>
|
||||
#include <java/lang/VMClassLoader.h>
|
||||
#include <java/lang/reflect/Modifier.h>
|
||||
|
@ -41,156 +43,6 @@ details. */
|
|||
#include <java/io/Serializable.h>
|
||||
#include <java/lang/Cloneable.h>
|
||||
|
||||
void
|
||||
_Jv_WaitForState (jclass klass, int state)
|
||||
{
|
||||
if (klass->state >= state)
|
||||
return;
|
||||
|
||||
_Jv_MonitorEnter (klass) ;
|
||||
|
||||
if (klass->state == JV_STATE_COMPILED)
|
||||
{
|
||||
klass->state = JV_STATE_LOADED;
|
||||
if (gcj::verbose_class_flag)
|
||||
fprintf (stderr, "[Loaded (pre-compiled) %s]\n", klass->name->chars());
|
||||
}
|
||||
if (state == JV_STATE_LINKED)
|
||||
{
|
||||
// Must call _Jv_PrepareCompiledClass while holding the class
|
||||
// mutex.
|
||||
#ifdef INTERPRETER
|
||||
if (_Jv_IsInterpretedClass (klass))
|
||||
_Jv_PrepareClass (klass);
|
||||
#endif
|
||||
_Jv_PrepareCompiledClass (klass);
|
||||
_Jv_MonitorExit (klass);
|
||||
return;
|
||||
}
|
||||
|
||||
java::lang::Thread *self = java::lang::Thread::currentThread();
|
||||
|
||||
// this is similar to the strategy for class initialization.
|
||||
// if we already hold the lock, just leave.
|
||||
while (klass->state <= state
|
||||
&& klass->thread
|
||||
&& klass->thread != self)
|
||||
klass->wait ();
|
||||
|
||||
_Jv_MonitorExit (klass);
|
||||
|
||||
if (klass->state == JV_STATE_ERROR)
|
||||
throw new java::lang::LinkageError;
|
||||
}
|
||||
|
||||
typedef unsigned int uaddr __attribute__ ((mode (pointer)));
|
||||
|
||||
/** This function does class-preparation for compiled classes.
|
||||
NOTE: It contains replicated functionality from
|
||||
_Jv_ResolvePoolEntry, and this is intentional, since that function
|
||||
lives in resolve.cc which is entirely conditionally compiled.
|
||||
*/
|
||||
void
|
||||
_Jv_PrepareCompiledClass (jclass klass)
|
||||
{
|
||||
jint state = klass->state;
|
||||
if (state >= JV_STATE_LINKED)
|
||||
return;
|
||||
|
||||
// Short-circuit, so that mutually dependent classes are ok.
|
||||
klass->state = JV_STATE_LINKED;
|
||||
|
||||
_Jv_Constants *pool = &klass->constants;
|
||||
|
||||
// Resolve class constants first, since other constant pool
|
||||
// entries may rely on these.
|
||||
for (int index = 1; index < pool->size; ++index)
|
||||
{
|
||||
if (pool->tags[index] == JV_CONSTANT_Class)
|
||||
{
|
||||
_Jv_Utf8Const *name = pool->data[index].utf8;
|
||||
|
||||
jclass found;
|
||||
if (name->first() == '[')
|
||||
found = _Jv_FindClassFromSignature (name->chars(),
|
||||
klass->loader);
|
||||
else
|
||||
found = _Jv_FindClass (name, klass->loader);
|
||||
|
||||
if (! found)
|
||||
{
|
||||
jstring str = name->toString();
|
||||
throw new java::lang::NoClassDefFoundError (str);
|
||||
}
|
||||
|
||||
pool->data[index].clazz = found;
|
||||
pool->tags[index] |= JV_CONSTANT_ResolvedFlag;
|
||||
}
|
||||
}
|
||||
|
||||
// If superclass looks like a constant pool entry,
|
||||
// resolve it now.
|
||||
if ((uaddr) klass->superclass < pool->size)
|
||||
klass->superclass = pool->data[(uaddr) klass->superclass].clazz;
|
||||
|
||||
// Likewise for interfaces.
|
||||
for (int i = 0; i < klass->interface_count; i++)
|
||||
if ((uaddr) klass->interfaces[i] < pool->size)
|
||||
klass->interfaces[i] = pool->data[(uaddr) klass->interfaces[i]].clazz;
|
||||
|
||||
// Resolve the remaining constant pool entries.
|
||||
for (int index = 1; index < pool->size; ++index)
|
||||
{
|
||||
if (pool->tags[index] == JV_CONSTANT_String)
|
||||
{
|
||||
jstring str;
|
||||
|
||||
str = _Jv_NewStringUtf8Const (pool->data[index].utf8);
|
||||
pool->data[index].o = str;
|
||||
pool->tags[index] |= JV_CONSTANT_ResolvedFlag;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef INTERPRETER
|
||||
// FIXME: although the comment up top says that this function is
|
||||
// only called for compiled classes, it is actually called for every
|
||||
// class.
|
||||
if (! _Jv_IsInterpretedClass (klass))
|
||||
{
|
||||
#endif /* INTERPRETER */
|
||||
jfieldID f = JvGetFirstStaticField (klass);
|
||||
for (int n = JvNumStaticFields (klass); n > 0; --n)
|
||||
{
|
||||
int mod = f->getModifiers ();
|
||||
// If we have a static String field with a non-null initial
|
||||
// value, we know it points to a Utf8Const.
|
||||
_Jv_ResolveField(f, klass->loader);
|
||||
if (f->getClass () == &java::lang::String::class$
|
||||
&& java::lang::reflect::Modifier::isStatic (mod))
|
||||
{
|
||||
jstring *strp = (jstring *) f->u.addr;
|
||||
if (*strp)
|
||||
*strp = _Jv_NewStringUtf8Const ((_Jv_Utf8Const *) *strp);
|
||||
}
|
||||
f = f->getNextField ();
|
||||
}
|
||||
#ifdef INTERPRETER
|
||||
}
|
||||
#endif /* INTERPRETER */
|
||||
|
||||
if (klass->isInterface ())
|
||||
_Jv_LayoutInterfaceMethods (klass);
|
||||
|
||||
if (state == JV_STATE_COMPILED && gcj::verbose_class_flag)
|
||||
fprintf (stderr, "[Loaded (pre-compiled) %s]\n",
|
||||
klass->name->chars());
|
||||
|
||||
klass->notifyAll ();
|
||||
|
||||
_Jv_PushClass (klass);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// A single class can have many "initiating" class loaders,
|
||||
// and a single "defining" class loader. The Defining
|
||||
|
@ -221,6 +73,8 @@ static _Jv_LoaderInfo *initiated_classes[HASH_LEN];
|
|||
static jclass loaded_classes[HASH_LEN];
|
||||
|
||||
// This is the root of a linked list of classes
|
||||
static jclass stack_head;
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -323,11 +177,6 @@ _Jv_RegisterClasses (const jclass *classes)
|
|||
jclass klass = *classes;
|
||||
|
||||
(*_Jv_RegisterClassHook) (klass);
|
||||
|
||||
// registering a compiled class causes
|
||||
// it to be immediately "prepared".
|
||||
if (klass->state == JV_STATE_NOTHING)
|
||||
klass->state = JV_STATE_COMPILED;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -341,11 +190,6 @@ _Jv_RegisterClasses_Counted (const jclass * classes, size_t count)
|
|||
jclass klass = classes[i];
|
||||
|
||||
(*_Jv_RegisterClassHook) (klass);
|
||||
|
||||
// registering a compiled class causes
|
||||
// it to be immediately "prepared".
|
||||
if (klass->state == JV_STATE_NOTHING)
|
||||
klass->state = JV_STATE_COMPILED;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -354,8 +198,10 @@ _Jv_RegisterClassHookDefault (jclass klass)
|
|||
{
|
||||
jint hash = HASH_UTF (klass->name);
|
||||
|
||||
jclass check_class = loaded_classes[hash];
|
||||
|
||||
// The BC ABI makes this check unnecessary: we always resolve all
|
||||
// data references via the appropriate class loader, so the kludge
|
||||
// that required this check has gone.
|
||||
#if 0
|
||||
// If the class is already registered, don't re-register it.
|
||||
while (check_class != NULL)
|
||||
{
|
||||
|
@ -381,7 +227,11 @@ _Jv_RegisterClassHookDefault (jclass klass)
|
|||
|
||||
check_class = check_class->next;
|
||||
}
|
||||
#endif
|
||||
|
||||
// FIXME: this is really bogus!
|
||||
if (! klass->engine)
|
||||
klass->engine = &_Jv_soleCompiledEngine;
|
||||
klass->next = loaded_classes[hash];
|
||||
loaded_classes[hash] = klass;
|
||||
}
|
||||
|
@ -442,7 +292,7 @@ _Jv_FindClass (_Jv_Utf8Const *name, java::lang::ClassLoader *loader)
|
|||
{
|
||||
// we need classes to be in the hash while
|
||||
// we're loading, so that they can refer to themselves.
|
||||
_Jv_WaitForState (klass, JV_STATE_LOADED);
|
||||
_Jv_Linker::wait_for_state (klass, JV_STATE_LOADED);
|
||||
}
|
||||
|
||||
return klass;
|
||||
|
@ -555,7 +405,7 @@ _Jv_NewArrayClass (jclass element, java::lang::ClassLoader *loader,
|
|||
// cache one and reuse it. It is not necessary to synchronize this.
|
||||
if (!array_idt)
|
||||
{
|
||||
_Jv_PrepareConstantTimeTables (array_class);
|
||||
_Jv_Linker::wait_for_state(array_class, JV_STATE_PREPARED);
|
||||
array_idt = array_class->idt;
|
||||
array_depth = array_class->depth;
|
||||
array_ancestors = array_class->ancestors;
|
||||
|
@ -569,19 +419,19 @@ _Jv_NewArrayClass (jclass element, java::lang::ClassLoader *loader,
|
|||
|
||||
using namespace java::lang::reflect;
|
||||
{
|
||||
// Array classes are "abstract final"...
|
||||
_Jv_ushort accflags = Modifier::FINAL | Modifier::ABSTRACT;
|
||||
// ... and inherit accessibility from element type, per vmspec 5.3.3.2
|
||||
accflags |= (element->accflags & Modifier::PUBLIC);
|
||||
accflags |= (element->accflags & Modifier::PROTECTED);
|
||||
accflags |= (element->accflags & Modifier::PRIVATE);
|
||||
// Array classes are "abstract final" and inherit accessibility
|
||||
// from element type, per vmspec 5.3.3.2
|
||||
_Jv_ushort accflags = (Modifier::FINAL | Modifier::ABSTRACT
|
||||
| (element->accflags
|
||||
& (Modifier::PUBLIC | Modifier::PROTECTED
|
||||
| Modifier::PRIVATE)));
|
||||
array_class->accflags = accflags;
|
||||
}
|
||||
|
||||
// An array class has no visible instance fields. "length" is invisible to
|
||||
// reflection.
|
||||
|
||||
// say this class is initialized and ready to go!
|
||||
// Say this class is initialized and ready to go!
|
||||
array_class->state = JV_STATE_DONE;
|
||||
|
||||
// vmspec, section 5.3.3 describes this
|
||||
|
@ -591,8 +441,6 @@ _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.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// natRuntime.cc - Implementation of native side of Runtime class.
|
||||
|
||||
/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation
|
||||
/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation
|
||||
|
||||
This file is part of libgcj.
|
||||
|
||||
|
@ -388,8 +388,11 @@ java::lang::Runtime::insertSystemProperties (java::util::Properties *newprops)
|
|||
newprops->put(JvNewStringLatin1 (Prop), JvNewStringLatin1 (Val))
|
||||
|
||||
// A mixture of the Java Product Versioning Specification
|
||||
// (introduced in 1.2), and earlier versioning properties.
|
||||
SET ("java.version", GCJVERSION);
|
||||
// (introduced in 1.2), and earlier versioning properties. Some
|
||||
// programs rely on seeing values that they expect, so we claim to
|
||||
// be a 1.4-ish VM for their sake.
|
||||
SET ("java.version", "1.4.2");
|
||||
SET ("java.runtime.version", "1.4.2");
|
||||
SET ("java.vendor", "Free Software Foundation, Inc.");
|
||||
SET ("java.vendor.url", "http://gcc.gnu.org/java/");
|
||||
SET ("java.class.version", "46.0");
|
||||
|
@ -399,7 +402,7 @@ java::lang::Runtime::insertSystemProperties (java::util::Properties *newprops)
|
|||
SET ("java.vm.version", __VERSION__);
|
||||
SET ("java.vm.vendor", "Free Software Foundation, Inc.");
|
||||
SET ("java.vm.name", "GNU libgcj");
|
||||
SET ("java.specification.version", "1.3");
|
||||
SET ("java.specification.version", "1.4");
|
||||
SET ("java.specification.name", "Java(tm) Platform API Specification");
|
||||
SET ("java.specification.vendor", "Sun Microsystems Inc.");
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
// natString.cc - Implementation of java.lang.String native methods.
|
||||
|
||||
/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004
|
||||
Free Software Foundation
|
||||
/* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation
|
||||
|
||||
This file is part of libgcj.
|
||||
|
||||
|
@ -57,7 +56,7 @@ static int strhash_size = 0; /* Number of slots available in strhash.
|
|||
jstring*
|
||||
_Jv_StringFindSlot (jchar* data, jint len, jint hash)
|
||||
{
|
||||
JvSynchronize sync (&StringClass);
|
||||
JvSynchronize sync (&java::lang::String::class$);
|
||||
|
||||
int start_index = hash & (strhash_size - 1);
|
||||
int deleted_index = -1;
|
||||
|
@ -120,7 +119,7 @@ _Jv_StringGetSlot (jstring str)
|
|||
static void
|
||||
rehash ()
|
||||
{
|
||||
JvSynchronize sync (&StringClass);
|
||||
JvSynchronize sync (&java::lang::String::class$);
|
||||
|
||||
if (strhash == NULL)
|
||||
{
|
||||
|
@ -167,7 +166,7 @@ rehash ()
|
|||
jstring
|
||||
java::lang::String::intern()
|
||||
{
|
||||
JvSynchronize sync (&StringClass);
|
||||
JvSynchronize sync (&java::lang::String::class$);
|
||||
if (3 * strhash_count >= 2 * strhash_size)
|
||||
rehash();
|
||||
jstring* ptr = _Jv_StringGetSlot(this);
|
||||
|
@ -194,7 +193,7 @@ java::lang::String::intern()
|
|||
void
|
||||
_Jv_FinalizeString (jobject obj)
|
||||
{
|
||||
JvSynchronize sync (&StringClass);
|
||||
JvSynchronize sync (&java::lang::String::class$);
|
||||
|
||||
// We might not actually have intern()d any strings at all, if
|
||||
// we're being called from Reference.
|
||||
|
@ -286,9 +285,9 @@ _Jv_NewStringUtf8Const (Utf8Const* str)
|
|||
}
|
||||
chrs -= length;
|
||||
|
||||
JvSynchronize sync (&StringClass);
|
||||
JvSynchronize sync (&java::lang::String::class$);
|
||||
if (3 * strhash_count >= 2 * strhash_size)
|
||||
rehash ();
|
||||
rehash();
|
||||
jstring* ptr = _Jv_StringFindSlot (chrs, length, hash);
|
||||
if (*ptr != NULL && *ptr != DELETED_STRING)
|
||||
return (jstring) UNMASK_PTR (*ptr);
|
||||
|
@ -527,7 +526,7 @@ java::lang::String::equals(jobject anObject)
|
|||
return false;
|
||||
if (anObject == this)
|
||||
return true;
|
||||
if (anObject->getClass() != &StringClass)
|
||||
if (anObject->getClass() != &java::lang::String::class$)
|
||||
return false;
|
||||
jstring other = (jstring) anObject;
|
||||
if (count != other->count)
|
||||
|
|
|
@ -22,6 +22,7 @@ details. */
|
|||
#include <java-interp.h>
|
||||
|
||||
#include <java/lang/VMClassLoader.h>
|
||||
#include <java/lang/VMCompiler.h>
|
||||
#include <gnu/gcj/runtime/VMClassLoader.h>
|
||||
#include <java/lang/ClassLoader.h>
|
||||
#include <java/lang/Class.h>
|
||||
|
@ -29,6 +30,21 @@ details. */
|
|||
#include <java/security/ProtectionDomain.h>
|
||||
#include <java/lang/ClassFormatError.h>
|
||||
|
||||
void
|
||||
java::lang::VMClassLoader::resolveClass (jclass klass)
|
||||
{
|
||||
JvSynchronize sync (klass);
|
||||
try
|
||||
{
|
||||
_Jv_Linker::wait_for_state (klass, JV_STATE_LINKED);
|
||||
}
|
||||
catch (java::lang::Throwable *x)
|
||||
{
|
||||
klass->set_state(JV_STATE_ERROR);
|
||||
transformException(klass, x);
|
||||
}
|
||||
}
|
||||
|
||||
java::lang::Class *
|
||||
java::lang::VMClassLoader::defineClass (java::lang::ClassLoader *loader,
|
||||
jstring name,
|
||||
|
@ -37,72 +53,61 @@ java::lang::VMClassLoader::defineClass (java::lang::ClassLoader *loader,
|
|||
jint length,
|
||||
java::security::ProtectionDomain *pd)
|
||||
{
|
||||
jclass klass = VMCompiler::compileClass(loader, name, data,
|
||||
offset, length, pd);
|
||||
|
||||
if (klass != NULL)
|
||||
{
|
||||
JvSynchronize sync (&java::lang::Class::class$);
|
||||
_Jv_RegisterClass (klass);
|
||||
}
|
||||
#ifdef INTERPRETER
|
||||
jclass klass;
|
||||
klass = new java::lang::Class ();
|
||||
klass->aux_info = (void *) _Jv_AllocBytes (sizeof (_Jv_InterpClass));
|
||||
|
||||
// Synchronize on the class, so that it is not attempted initialized
|
||||
// until we're done loading.
|
||||
JvSynchronize sync (klass);
|
||||
|
||||
// Record the defining loader. For the system class loader, we
|
||||
// record NULL.
|
||||
if (loader != java::lang::ClassLoader::getSystemClassLoader())
|
||||
klass->loader = loader;
|
||||
|
||||
if (name != 0)
|
||||
else
|
||||
{
|
||||
_Jv_Utf8Const *name2 = _Jv_makeUtf8Const (name);
|
||||
klass = new java::lang::Class ();
|
||||
|
||||
if (! _Jv_VerifyClassName (name2))
|
||||
throw new java::lang::ClassFormatError
|
||||
(JvNewStringLatin1 ("erroneous class name"));
|
||||
// Synchronize on the class, so that it is not attempted initialized
|
||||
// until we're done loading.
|
||||
JvSynchronize sync (klass);
|
||||
|
||||
klass->name = name2;
|
||||
// Record the defining loader. For the system class loader, we
|
||||
// record NULL.
|
||||
if (loader != java::lang::ClassLoader::getSystemClassLoader())
|
||||
klass->loader = loader;
|
||||
|
||||
if (name != 0)
|
||||
{
|
||||
_Jv_Utf8Const *name2 = _Jv_makeUtf8Const (name);
|
||||
|
||||
if (! _Jv_VerifyClassName (name2))
|
||||
throw new java::lang::ClassFormatError
|
||||
(JvNewStringLatin1 ("erroneous class name"));
|
||||
|
||||
klass->name = name2;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
_Jv_DefineClass (klass, data, offset, length, pd);
|
||||
}
|
||||
catch (java::lang::Throwable *ex)
|
||||
{
|
||||
klass->state = JV_STATE_ERROR;
|
||||
klass->notifyAll ();
|
||||
|
||||
_Jv_UnregisterClass (klass);
|
||||
|
||||
// If EX is not a ClassNotFoundException, that's ok, because we
|
||||
// account for the possibility in defineClass().
|
||||
throw ex;
|
||||
}
|
||||
|
||||
// if everything proceeded sucessfully, we're loaded.
|
||||
JvAssert (klass->state == JV_STATE_LOADED);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
_Jv_DefineClass (klass, data, offset, length);
|
||||
}
|
||||
catch (java::lang::Throwable *ex)
|
||||
{
|
||||
klass->state = JV_STATE_ERROR;
|
||||
klass->notifyAll ();
|
||||
|
||||
_Jv_UnregisterClass (klass);
|
||||
|
||||
// If EX is not a ClassNotFoundException, that's ok, because we
|
||||
// account for the possibility in defineClass().
|
||||
throw ex;
|
||||
}
|
||||
|
||||
klass->protectionDomain = pd;
|
||||
|
||||
// if everything proceeded sucessfully, we're loaded.
|
||||
JvAssert (klass->state == JV_STATE_LOADED);
|
||||
#endif // INTERPRETER
|
||||
|
||||
return klass;
|
||||
|
||||
#else // INTERPRETER
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Finish linking a class. Only called from ClassLoader::resolveClass.
|
||||
void
|
||||
java::lang::VMClassLoader::linkClass0 (java::lang::Class *klass)
|
||||
{
|
||||
_Jv_WaitForState (klass, JV_STATE_LINKED);
|
||||
}
|
||||
|
||||
void
|
||||
java::lang::VMClassLoader::markClassErrorState0 (java::lang::Class *klass)
|
||||
{
|
||||
klass->state = JV_STATE_ERROR;
|
||||
klass->notifyAll ();
|
||||
}
|
||||
|
||||
java::lang::ClassLoader *
|
||||
|
@ -125,9 +130,16 @@ jclass
|
|||
java::lang::VMClassLoader::loadClass(jstring name, jboolean resolve)
|
||||
{
|
||||
_Jv_Utf8Const *utf = _Jv_makeUtf8Const (name);
|
||||
// FIXME: we culd make _Jv_FindClassFromSignature a template.
|
||||
jclass klass = _Jv_FindClassInCache (utf, NULL);
|
||||
if (klass && resolve)
|
||||
_Jv_InitClass (klass);
|
||||
if (klass)
|
||||
{
|
||||
// We never want to return a class without its supers linked.
|
||||
// It isn't clear from the spec, but this is what other
|
||||
// implementations do in practice.
|
||||
if (resolve)
|
||||
_Jv_InitClass (klass);
|
||||
else
|
||||
_Jv_Linker::wait_for_state (klass, JV_STATE_LOADING);
|
||||
}
|
||||
return klass;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// natField.cc - Implementation of java.lang.reflect.Field native methods.
|
||||
|
||||
/* Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation
|
||||
/* Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004 Free Software Foundation
|
||||
|
||||
This file is part of libgcj.
|
||||
|
||||
|
@ -47,7 +47,7 @@ java::lang::reflect::Field::getType ()
|
|||
{
|
||||
jfieldID fld = _Jv_FromReflectedField (this);
|
||||
JvSynchronize sync (declaringClass);
|
||||
_Jv_ResolveField (fld, declaringClass->getClassLoaderInternal ());
|
||||
_Jv_Linker::resolve_field (fld, declaringClass->getClassLoaderInternal ());
|
||||
return fld->type;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// natMethod.cc - Native code for Method class.
|
||||
|
||||
/* Copyright (C) 1998, 1999, 2000, 2001 , 2002, 2003 Free Software Foundation
|
||||
/* Copyright (C) 1998, 1999, 2000, 2001 , 2002, 2003, 2004 Free Software Foundation
|
||||
|
||||
This file is part of libgcj.
|
||||
|
||||
|
@ -149,7 +149,6 @@ java::lang::reflect::Method::invoke (jobject obj, jobjectArray args)
|
|||
getType ();
|
||||
|
||||
jmethodID meth = _Jv_FromReflectedMethod (this);
|
||||
jclass objClass;
|
||||
|
||||
if (Modifier::isStatic(meth->accflags))
|
||||
{
|
||||
|
@ -157,12 +156,10 @@ java::lang::reflect::Method::invoke (jobject obj, jobjectArray args)
|
|||
// here and not in _Jv_CallAnyMethodA because JNI initializes a
|
||||
// class whenever a method lookup is done.
|
||||
_Jv_InitClass (declaringClass);
|
||||
objClass = declaringClass;
|
||||
}
|
||||
else
|
||||
{
|
||||
objClass = JV_CLASS (obj);
|
||||
|
||||
jclass objClass = JV_CLASS (obj);
|
||||
if (! _Jv_IsAssignableFrom (declaringClass, objClass))
|
||||
throw new java::lang::IllegalArgumentException;
|
||||
}
|
||||
|
@ -184,7 +181,7 @@ java::lang::reflect::Method::invoke (jobject obj, jobjectArray args)
|
|||
{
|
||||
}
|
||||
|
||||
if (! _Jv_CheckAccess(caller, objClass, meth->accflags))
|
||||
if (! _Jv_CheckAccess(caller, declaringClass, meth->accflags))
|
||||
throw new IllegalAccessException;
|
||||
}
|
||||
|
||||
|
|
|
@ -54,6 +54,8 @@ import java.security.SecureClassLoader;
|
|||
import java.security.cert.Certificate;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.Vector;
|
||||
import java.util.jar.Attributes;
|
||||
import java.util.jar.JarEntry;
|
||||
|
@ -144,9 +146,10 @@ public class URLClassLoader extends SecureClassLoader
|
|||
private final Vector urls = new Vector();
|
||||
|
||||
/**
|
||||
* Store pre-parsed information for each url into this vector
|
||||
* each element is a URL loader, corresponding to the URL of
|
||||
* the same index in "urls"
|
||||
* Store pre-parsed information for each url into this vector: each
|
||||
* element is a URL loader. A jar file has its own class-path
|
||||
* attribute which adds to the URLs that will be searched, but this
|
||||
* does not add to the list of urls.
|
||||
*/
|
||||
private final Vector urlinfos = new Vector();
|
||||
|
||||
|
@ -188,10 +191,15 @@ public class URLClassLoader extends SecureClassLoader
|
|||
final CodeSource noCertCodeSource;
|
||||
|
||||
URLLoader(URLClassLoader classloader, URL baseURL)
|
||||
{
|
||||
this(classloader, baseURL, baseURL);
|
||||
}
|
||||
|
||||
URLLoader(URLClassLoader classloader, URL baseURL, URL overrideURL)
|
||||
{
|
||||
this.classloader = classloader;
|
||||
this.baseURL = baseURL;
|
||||
this.noCertCodeSource = new CodeSource(baseURL, null);
|
||||
this.noCertCodeSource = new CodeSource(overrideURL, null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -221,6 +229,11 @@ public class URLClassLoader extends SecureClassLoader
|
|||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
Vector getClassPath()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -290,6 +303,10 @@ public class URLClassLoader extends SecureClassLoader
|
|||
final JarFile jarfile; // The jar file for this url
|
||||
final URL baseJarURL; // Base jar: url for all resources loaded from jar
|
||||
|
||||
Vector classPath; // The "Class-Path" attribute of this Jar's manifest
|
||||
|
||||
SoURLLoader soURLLoader;
|
||||
|
||||
public JarURLLoader(URLClassLoader classloader, URL baseURL)
|
||||
{
|
||||
super(classloader, baseURL);
|
||||
|
@ -302,25 +319,87 @@ public class URLClassLoader extends SecureClassLoader
|
|||
sb.append("!/");
|
||||
String jarURL = sb.toString();
|
||||
|
||||
this.soURLLoader = null;
|
||||
this.classPath = null;
|
||||
URL baseJarURL = null;
|
||||
JarFile jarfile = null;
|
||||
try
|
||||
{
|
||||
baseJarURL =
|
||||
new URL(null, jarURL, classloader.getURLStreamHandler("jar"));
|
||||
{
|
||||
baseJarURL
|
||||
= new URL(null, jarURL, classloader.getURLStreamHandler("jar"));
|
||||
jarfile
|
||||
= ((JarURLConnection) baseJarURL.openConnection()).getJarFile();
|
||||
|
||||
jarfile =
|
||||
((JarURLConnection) baseJarURL.openConnection()).getJarFile();
|
||||
}
|
||||
if (jarfile != null)
|
||||
{
|
||||
String fileName = baseURL.getFile();
|
||||
if (fileName != null)
|
||||
{
|
||||
File f = new File(fileName);
|
||||
String libDirName = f.getCanonicalFile().getParent()
|
||||
+ File.separator + "GCJLIBS";
|
||||
File libDir = new File(libDirName);
|
||||
if (libDir != null && (libDir.isDirectory()))
|
||||
{
|
||||
File soFile = new File (libDirName
|
||||
+ File.separator + f.getName()
|
||||
+ ".so");
|
||||
if (soFile != null && soFile.isFile())
|
||||
this.soURLLoader
|
||||
= new SoURLLoader (classloader, soFile.toURL(),
|
||||
baseURL);
|
||||
}
|
||||
}
|
||||
|
||||
Manifest manifest;
|
||||
Attributes attributes;
|
||||
String classPathString;
|
||||
|
||||
if ((manifest = jarfile.getManifest()) != null
|
||||
&& (attributes = manifest.getMainAttributes()) != null
|
||||
&& ((classPathString
|
||||
= attributes.getValue(Attributes.Name.CLASS_PATH))
|
||||
!= null))
|
||||
{
|
||||
this.classPath = new Vector();
|
||||
|
||||
StringTokenizer st
|
||||
= new StringTokenizer
|
||||
(classPathString,
|
||||
System.getProperty ("path.separator", ":"));
|
||||
|
||||
while (st.hasMoreElements ())
|
||||
{
|
||||
String e = st.nextToken ();
|
||||
try
|
||||
{
|
||||
URL url = new URL(baseURL, e);
|
||||
this.classPath.add(url);
|
||||
}
|
||||
catch (java.net.MalformedURLException xx)
|
||||
{
|
||||
// Give up
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
/* ignored */
|
||||
/* ignored */
|
||||
}
|
||||
|
||||
this.baseJarURL = baseJarURL;
|
||||
this.jarfile = jarfile;
|
||||
}
|
||||
|
||||
Class getClass(String className)
|
||||
{
|
||||
if (soURLLoader != null)
|
||||
return soURLLoader.getClass(className);
|
||||
return null;
|
||||
}
|
||||
|
||||
/** get resource with the name "name" in the jar url */
|
||||
Resource getResource(String name)
|
||||
{
|
||||
|
@ -337,6 +416,11 @@ public class URLClassLoader extends SecureClassLoader
|
|||
return null;
|
||||
}
|
||||
|
||||
public String toString ()
|
||||
{
|
||||
return "jarfile " + jarfile.getName();
|
||||
}
|
||||
|
||||
Manifest getManifest()
|
||||
{
|
||||
try
|
||||
|
@ -348,6 +432,11 @@ public class URLClassLoader extends SecureClassLoader
|
|||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Vector getClassPath()
|
||||
{
|
||||
return classPath;
|
||||
}
|
||||
}
|
||||
|
||||
static final class JarURLResource extends Resource
|
||||
|
@ -486,7 +575,12 @@ public class URLClassLoader extends SecureClassLoader
|
|||
|
||||
SoURLLoader(URLClassLoader classloader, URL url)
|
||||
{
|
||||
super(classloader, url);
|
||||
this(classloader, url, url);
|
||||
}
|
||||
|
||||
SoURLLoader(URLClassLoader classloader, URL url, URL overrideURL)
|
||||
{
|
||||
super(classloader, url, overrideURL);
|
||||
helper = SharedLibHelper.findHelper(classloader, url.getFile(),
|
||||
noCertCodeSource);
|
||||
}
|
||||
|
@ -577,6 +671,11 @@ public class URLClassLoader extends SecureClassLoader
|
|||
return (int) file.length();
|
||||
}
|
||||
|
||||
public String toString ()
|
||||
{
|
||||
return "file " +file.getAbsolutePath();
|
||||
}
|
||||
|
||||
public URL getURL()
|
||||
{
|
||||
try
|
||||
|
@ -729,6 +828,7 @@ public class URLClassLoader extends SecureClassLoader
|
|||
*/
|
||||
protected void addURL(URL newUrl)
|
||||
{
|
||||
urls.add(newUrl);
|
||||
addURLImpl(newUrl);
|
||||
}
|
||||
|
||||
|
@ -761,8 +861,21 @@ public class URLClassLoader extends SecureClassLoader
|
|||
urlloaders.put(newUrl, loader);
|
||||
}
|
||||
|
||||
urls.add(newUrl);
|
||||
urlinfos.add(loader);
|
||||
urlinfos.add(loader);
|
||||
|
||||
Vector extraUrls = loader.getClassPath();
|
||||
if (extraUrls != null)
|
||||
{
|
||||
Iterator it = extraUrls.iterator();
|
||||
while (it.hasNext())
|
||||
{
|
||||
URL url = (URL)it.next();
|
||||
URLLoader extraLoader = (URLLoader) urlloaders.get(url);
|
||||
if (! urlinfos.contains (extraLoader))
|
||||
addURLImpl(url);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -773,7 +886,7 @@ public class URLClassLoader extends SecureClassLoader
|
|||
private void addURLs(URL[] newUrls)
|
||||
{
|
||||
for (int i = 0; i < newUrls.length; i++)
|
||||
addURLImpl(newUrls[i]);
|
||||
addURL(newUrls[i]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -830,7 +943,7 @@ public class URLClassLoader extends SecureClassLoader
|
|||
{
|
||||
// Just try to find the resource by the (almost) same name
|
||||
String resourceName = className.replace('.', '/') + ".class";
|
||||
int max = urls.size();
|
||||
int max = urlinfos.size();
|
||||
Resource resource = null;
|
||||
for (int i = 0; i < max && resource == null; i++)
|
||||
{
|
||||
|
@ -939,7 +1052,7 @@ public class URLClassLoader extends SecureClassLoader
|
|||
*/
|
||||
private Resource findURLResource(String resourceName)
|
||||
{
|
||||
int max = urls.size();
|
||||
int max = urlinfos.size();
|
||||
for (int i = 0; i < max; i++)
|
||||
{
|
||||
URLLoader loader = (URLLoader) urlinfos.elementAt(i);
|
||||
|
@ -1010,7 +1123,7 @@ public class URLClassLoader extends SecureClassLoader
|
|||
throws IOException
|
||||
{
|
||||
Vector resources = new Vector();
|
||||
int max = urls.size();
|
||||
int max = urlinfos.size();
|
||||
for (int i = 0; i < max; i++)
|
||||
{
|
||||
URLLoader loader = (URLLoader) urlinfos.elementAt(i);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue