natClassLoader.cc (_Jv_PrepareCompiledClass): Renamed from _Jv_InternClassStrings.
* java/lang/natClassLoader.cc (_Jv_PrepareCompiledClass): Renamed from _Jv_InternClassStrings. * prims.cc (_Jv_RunMain): New function. (JvRunMain): Remove gij-support. * gij.cc (main): Use _Jv_RunMain. * java/util/zip/ZipFile.java: Call readDirectory in constructor. * interpret.cc (PUSHA, PUSHI, PUSHF, PUSHL, PUSHD): Don't store argument in temp variable. (continue1): For all op_x2y insns, use temp variable for intermediate value. Also remove some comments. * java/lang/natClass.cc (newInstance): Call _Jv_InitClass. (forName): Don't call _Jv_InitClass. * java/lang/Class.java (getResource,getResourceAsStream): Implement. * java/util/zip/ZipEntry.java (ZipEntry(ZipEntry)): New construcor. * java/util/jar/JarInputStream.java: New file. * java/util/jar/JarEntry.java: New file. * java/util/jar/JarFile.java: New file. * java/net/URLClassLoader.java: New file. * java/net/JarURLConnection.java: New file. * gnu/gcj/protocol/jar/Handler.java: New file. * gnu/gcj/protocol/jar/Connection.java: New file. * java/security/SecureClassLoader.java: New file. * java/lang/ClassLoader.java (parent): New variable. (ClassLoader (ClassLoader)): new constructor. (findClass): New method. (loadClass): Add default 1.2 implementation. (getSystemResourceAsBytes, getResourceAsBytes): Removed. (readfully): Removed. * gnu/gcj/runtime/VMClassLoader.java: Moved from java/lang. (findSystemClass): New method. (VMClassLoader): Constructor rewritten. (init): New method. All other methods removed. * java/lang/natClassLoader.cc: Change use of java::lang::VMClassLoader to gnu::gcj::runtime::VMClassLoader. (_Jv_InternClassStrings): Use _Jv_ResolvePoolEntry. Also handle class entries. (VMClassLoader::findSystemClass): renamed from findBootClass. * Makefile.am: Add new files. (FirstThread.h, ThreadGroup.h): Add _Jv_Main friend. * Makefile.in: Rebuilt. From-SVN: r28748
This commit is contained in:
committed by
Kresten Krab Thorup
parent
312f625598
commit
eb4534a636
@@ -16,6 +16,7 @@ details. */
|
||||
|
||||
#include <java/lang/Object.h>
|
||||
#include <java/lang/String.h>
|
||||
#include <java/net/URL.h>
|
||||
|
||||
// We declare these here to avoid including cni.h.
|
||||
extern "C" void _Jv_InitClass (jclass klass);
|
||||
@@ -108,6 +109,7 @@ public:
|
||||
|
||||
jstring getName (void);
|
||||
|
||||
java::net::URL *getResource (jstring resourceName);
|
||||
java::io::InputStream *getResourceAsStream (jstring resourceName);
|
||||
JArray<jobject> *getSigners (void);
|
||||
|
||||
@@ -182,7 +184,7 @@ private:
|
||||
friend jclass _Jv_NewClass (_Jv_Utf8Const *name, jclass superclass,
|
||||
java::lang::ClassLoader *loader);
|
||||
|
||||
friend void _Jv_InternClassStrings (jclass);
|
||||
friend void _Jv_PrepareCompiledClass (jclass);
|
||||
|
||||
#ifdef INTERPRETER
|
||||
friend jboolean _Jv_IsInterpretedClass (jclass);
|
||||
|
||||
@@ -80,13 +80,41 @@ public final class Class implements Serializable
|
||||
public native int getModifiers ();
|
||||
public native String getName ();
|
||||
|
||||
// FIXME: can't implement this until we have java.net.
|
||||
// public URL getResource (String resourceName);
|
||||
|
||||
// FIXME: implement.
|
||||
public InputStream getResourceAsStream (String resourceName)
|
||||
public java.net.URL getResource (String resourceName)
|
||||
{
|
||||
return null;
|
||||
String name = resourcePath (resourceName);
|
||||
ClassLoader loader = getClassLoader ();
|
||||
if (loader == null)
|
||||
return ClassLoader.getSystemResource (name);
|
||||
else
|
||||
return loader.getResource (name);
|
||||
}
|
||||
|
||||
public java.io.InputStream getResourceAsStream (String resourceName)
|
||||
{
|
||||
String name = resourcePath (resourceName);
|
||||
ClassLoader loader = getClassLoader ();
|
||||
if (loader == null)
|
||||
return ClassLoader.getSystemResourceAsStream (name);
|
||||
else
|
||||
return loader.getResourceAsStream (name);
|
||||
}
|
||||
|
||||
private String resourcePath (String resourceName)
|
||||
{
|
||||
if (resourceName.startsWith ("/"))
|
||||
return resourceName.substring (1);
|
||||
|
||||
Class c = this;
|
||||
while (c.isArray ())
|
||||
c = c.getComponentType ();
|
||||
|
||||
String packageName = c.getName ().replace ('.', '/');
|
||||
int end = packageName.lastIndexOf ('/');
|
||||
if (end == -1)
|
||||
return resourceName;
|
||||
else
|
||||
return packageName.substring (0, end+1) + resourceName;
|
||||
}
|
||||
|
||||
// FIXME: implement. Requires java.security.
|
||||
|
||||
@@ -26,6 +26,13 @@ import java.util.Stack;
|
||||
public abstract class ClassLoader {
|
||||
|
||||
static private ClassLoader system;
|
||||
private ClassLoader parent;
|
||||
|
||||
public ClassLoader getParent ()
|
||||
{
|
||||
/* FIXME: security */
|
||||
return parent;
|
||||
}
|
||||
|
||||
private static native ClassLoader getVMClassLoader0 ();
|
||||
|
||||
@@ -36,17 +43,29 @@ public abstract class ClassLoader {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a <code>ClassLoader</code>. The only thing this
|
||||
* Creates a <code>ClassLoader</code> with no parent.
|
||||
* @exception java.lang.SecurityException if not allowed
|
||||
*/
|
||||
protected ClassLoader()
|
||||
{
|
||||
this (null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a <code>ClassLoader</code> with the given parent.
|
||||
* The parent may be <code>null</code>.
|
||||
* The only thing this
|
||||
* constructor does, is to call
|
||||
* <code>checkCreateClassLoader</code> on the current
|
||||
* security manager.
|
||||
* @exception java.lang.SecurityException if not allowed
|
||||
*/
|
||||
protected ClassLoader()
|
||||
protected ClassLoader(ClassLoader parent)
|
||||
{
|
||||
SecurityManager security = System.getSecurityManager ();
|
||||
if (security != null)
|
||||
security.checkCreateClassLoader ();
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -59,22 +78,68 @@ public abstract class ClassLoader {
|
||||
public Class loadClass(String name)
|
||||
throws java.lang.ClassNotFoundException, java.lang.LinkageError
|
||||
{
|
||||
return loadClass (name, true);
|
||||
return loadClass (name, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the class by the given name.
|
||||
* As per java 1.1, this has been deprecated. Use
|
||||
* <code>loadClass(String)</code>
|
||||
* instead.
|
||||
* Loads the class by the given name. The default implementation
|
||||
* will search for the class in the following order (similar to jdk 1.2)
|
||||
* <ul>
|
||||
* <li> First <code>findLoadedClass</code>.
|
||||
* <li> If parent is non-null, <code>parent.loadClass</code>;
|
||||
* otherwise <code>findSystemClass</code>.
|
||||
* <li> <code>findClass</code>.
|
||||
* </ul>
|
||||
* If <code>link</code> is true, <code>resolveClass</code> is then
|
||||
* called. <p> Normally, this need not be overridden; override
|
||||
* <code>findClass</code> instead.
|
||||
* @param name the name of the class.
|
||||
* @param link if the class should be linked.
|
||||
* @return the class loaded.
|
||||
* @exception java.lang.ClassNotFoundException
|
||||
* @deprecated
|
||||
*/
|
||||
protected abstract Class loadClass(String name, boolean link)
|
||||
throws java.lang.ClassNotFoundException, java.lang.LinkageError;
|
||||
protected Class loadClass(String name, boolean link)
|
||||
throws java.lang.ClassNotFoundException, java.lang.LinkageError
|
||||
{
|
||||
Class c = findLoadedClass (name);
|
||||
|
||||
if (c == null)
|
||||
{
|
||||
try {
|
||||
if (parent != null)
|
||||
return parent.loadClass (name, link);
|
||||
else
|
||||
c = findSystemClass (name);
|
||||
} catch (ClassNotFoundException ex) {
|
||||
/* ignore, we'll try findClass */;
|
||||
}
|
||||
}
|
||||
|
||||
if (c == null)
|
||||
c = findClass (name);
|
||||
|
||||
if (c == null)
|
||||
throw new ClassNotFoundException (name);
|
||||
|
||||
if (link)
|
||||
resolveClass (c);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
/** Find a class. This should be overridden by subclasses; the
|
||||
* default implementation throws ClassNotFoundException.
|
||||
*
|
||||
* @param name Name of the class to find.
|
||||
* @return The class found.
|
||||
* @exception java.lang.ClassNotFoundException
|
||||
*/
|
||||
protected Class findClass (String name)
|
||||
throws ClassNotFoundException
|
||||
{
|
||||
throw new ClassNotFoundException ();
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines a class, given the class-data. According to the JVM, this
|
||||
@@ -251,7 +316,7 @@ public abstract class ClassLoader {
|
||||
}
|
||||
|
||||
/** Internal method. Calls _Jv_PrepareClass and
|
||||
* _Jv_InternClassStrings. This is only called from resolveClass. */
|
||||
* _Jv_PrepareCompiledClass. This is only called from resolveClass. */
|
||||
private static native void linkClass0(Class clazz)
|
||||
throws java.lang.LinkageError;
|
||||
|
||||
@@ -263,15 +328,19 @@ public abstract class ClassLoader {
|
||||
|
||||
/**
|
||||
* Returns a class found in a system-specific way, typically
|
||||
* via the <code>java.class.path</code> system property.
|
||||
* via the <code>java.class.path</code> system property. Loads the
|
||||
* class if necessary.
|
||||
*
|
||||
* @param name the class to resolve.
|
||||
* @return the class loaded.
|
||||
* @exception java.lang.LinkageError
|
||||
* @exception java.lang.ClassNotFoundException
|
||||
*/
|
||||
protected native Class findSystemClass(String name)
|
||||
throws java.lang.ClassNotFoundException, java.lang.LinkageError;
|
||||
protected Class findSystemClass(String name)
|
||||
throws java.lang.ClassNotFoundException, java.lang.LinkageError
|
||||
{
|
||||
return getSystemClassLoader ().loadClass (name);
|
||||
}
|
||||
|
||||
/*
|
||||
* Does currently nothing.
|
||||
@@ -280,10 +349,11 @@ public abstract class ClassLoader {
|
||||
/* claz.setSigners (signers); */
|
||||
}
|
||||
|
||||
/*
|
||||
/**
|
||||
* If a class named <code>name</code> was previously loaded using
|
||||
* this <code>ClassLoader</code>, then it is returned. Otherwise
|
||||
* it returns <code>null</code>.
|
||||
* it returns <code>null</code>. (Unlike the JDK this is native,
|
||||
* since we implement the class table internally.)
|
||||
* @param name class to find.
|
||||
* @return the class loaded, or null.
|
||||
*/
|
||||
@@ -297,10 +367,6 @@ public abstract class ClassLoader {
|
||||
return system.getResource (name);
|
||||
}
|
||||
|
||||
public static final byte[] getSystemResourceAsBytes(String name) {
|
||||
return system.getResourceAsBytes (name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an InputStream representing the resource name.
|
||||
* This is essentially like
|
||||
@@ -309,7 +375,6 @@ public abstract class ClassLoader {
|
||||
* @param name resource to load
|
||||
* @return an InputStream, or null
|
||||
* @see java.lang.ClassLoader#getResource(String)
|
||||
* @see java.lang.ClassLoader#getResourceAsBytes(String)
|
||||
* @see java.io.InputStream
|
||||
*/
|
||||
public InputStream getResourceAsStream(String name)
|
||||
@@ -323,42 +388,9 @@ public abstract class ClassLoader {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a byte array <code>byte[]</code> representing the
|
||||
* resouce <code>name</code>. This only works for resources
|
||||
* that have a known <code>content-length</code>, and
|
||||
* it will block while loading the resource. Returns null
|
||||
* for error conditions.<p>
|
||||
* Since it is synchroneous, this is only convenient for
|
||||
* resources that are "readily" available. System resources
|
||||
* can conveniently be loaded this way, and the runtime
|
||||
* system uses this to load class files. <p>
|
||||
* To find the class data for a given class, use
|
||||
* something like the following:
|
||||
* <ul><code>
|
||||
* String res = clazz.getName().replace ('.', '/')) + ".class";<br>
|
||||
* byte[] data = getResourceAsBytes (res);
|
||||
* </code></ul>
|
||||
* @param name resource to load
|
||||
* @return a byte array, or null
|
||||
* @see java.lang.ClassLoader#getResource(String)
|
||||
* @see java.lang.ClassLoader#getResourceAsStream(String)
|
||||
*/
|
||||
public byte[] getResourceAsBytes(String name) {
|
||||
try {
|
||||
URL res = getResource (name);
|
||||
if (res == null) return null;
|
||||
URLConnection conn = res.openConnection ();
|
||||
int len = conn.getContentLength ();
|
||||
if (len == -1) return null;
|
||||
return readbytes (conn.getInputStream (), len);
|
||||
} catch (java.io.IOException x) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an java.io.URL representing the resouce <code>name</code>.
|
||||
* The default implementation just returns <code>null</code>.
|
||||
* @param name resource to load
|
||||
* @return a URL, or null if there is no such resource.
|
||||
* @see java.lang.ClassLoader#getResourceAsBytes(String)
|
||||
@@ -369,31 +401,5 @@ public abstract class ClassLoader {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility routine to read a resource fully, even if the given
|
||||
* InputStream only provides partial results.
|
||||
*/
|
||||
private static byte[] readbytes (InputStream is, int length)
|
||||
{
|
||||
try {
|
||||
|
||||
byte[] data = new byte[length];
|
||||
int read;
|
||||
int off = 0;
|
||||
|
||||
while (off != length)
|
||||
{
|
||||
read = is.read (data, off, (int) (length-off));
|
||||
|
||||
if (read == -1)
|
||||
return null;
|
||||
|
||||
off += read;
|
||||
}
|
||||
|
||||
return data;
|
||||
} catch (java.io.IOException x) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,117 +0,0 @@
|
||||
/* Copyright (C) 1999 Cygnus Solutions
|
||||
|
||||
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 java.lang;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.URL;
|
||||
import gnu.gcj.util.path.SearchPath;
|
||||
|
||||
final class VMClassLoader extends java.lang.ClassLoader
|
||||
{
|
||||
private SearchPath path;
|
||||
private final String path_seperator;
|
||||
private final String file_seperator;
|
||||
private final char file_seperator_char;
|
||||
|
||||
private VMClassLoader () {
|
||||
path_seperator = System.getProperty ("path.separator", ":");
|
||||
file_seperator = System.getProperty ("file.separator", "/");
|
||||
|
||||
file_seperator_char = file_seperator.charAt (0);
|
||||
|
||||
String class_path = System.getProperty ("java.class.path", ".");
|
||||
path = new SearchPath (class_path);
|
||||
}
|
||||
|
||||
protected Class loadClass(String name,
|
||||
boolean resolve)
|
||||
throws java.lang.ClassNotFoundException, java.lang.LinkageError
|
||||
{
|
||||
return loadClassInternal (name, resolve, false);
|
||||
}
|
||||
|
||||
/** I'm a little in doubt here, if this method is
|
||||
actually supposed to throw a LinkageError, or not.
|
||||
The spec, 20.14.3, is a little unclear. It says:
|
||||
|
||||
`` The general contract of loadClass is that, given the name
|
||||
of a class, it either returns the Class object for the class
|
||||
or throws a ClassNotFoundException.''
|
||||
|
||||
However, by making LinkageError a checked exception,
|
||||
i.e., mention it directly in the throws clause,
|
||||
we'll force caller to consider that case as well.
|
||||
**/
|
||||
|
||||
protected Class loadClassInternal(String name,
|
||||
boolean resolve,
|
||||
boolean fromBootLoader)
|
||||
throws java.lang.ClassNotFoundException, java.lang.LinkageError
|
||||
{
|
||||
Class clazz;
|
||||
|
||||
/** TODO: call _Jv_VerifyClassName **/
|
||||
if ( (name.indexOf ('/') != -1)
|
||||
|| (name.charAt (0) == '.')
|
||||
|| (name.indexOf (file_seperator) != -1)
|
||||
|| (name.indexOf ("..") != -1))
|
||||
{
|
||||
throw new IllegalArgumentException (name);
|
||||
}
|
||||
|
||||
// already loaded?
|
||||
clazz = findLoadedClass (name);
|
||||
|
||||
// we need access to the boot class loader here
|
||||
if (clazz == null && !fromBootLoader)
|
||||
clazz = findBootClass (name);
|
||||
|
||||
if (clazz == null)
|
||||
{
|
||||
StringBuffer res = new StringBuffer ();
|
||||
|
||||
// here we do actually replace .'s with /'s because
|
||||
// we're going to find something in the file system.
|
||||
res.append (name.replace ('.', file_seperator_char));
|
||||
res.append (".class");
|
||||
|
||||
byte[] data = getResourceAsBytes (res.toString ());
|
||||
|
||||
if (data == null)
|
||||
throw new ClassNotFoundException (name);
|
||||
|
||||
clazz = defineClass (name, data, 0, data.length);
|
||||
|
||||
}
|
||||
|
||||
if (resolve && clazz != null)
|
||||
resolveClass (clazz);
|
||||
|
||||
return clazz;
|
||||
}
|
||||
|
||||
private native Class findBootClass (String name);
|
||||
|
||||
public InputStream getResourceAsStream(String name)
|
||||
{
|
||||
return path.getStream (name);
|
||||
}
|
||||
|
||||
public URL getResource(String name)
|
||||
{
|
||||
return path.getURL (name);
|
||||
}
|
||||
|
||||
public byte[] getResourceAsBytes(String name)
|
||||
{
|
||||
return path.getBytes (name);
|
||||
}
|
||||
}
|
||||
@@ -92,8 +92,6 @@ java::lang::Class::forName (jstring className)
|
||||
if (! klass)
|
||||
JvThrow (new java::lang::ClassNotFoundException (className));
|
||||
|
||||
_Jv_InitClass (klass);
|
||||
|
||||
return klass;
|
||||
}
|
||||
|
||||
@@ -354,6 +352,8 @@ java::lang::Class::newInstance (void)
|
||||
|| java::lang::reflect::Modifier::isAbstract(accflags))
|
||||
JvThrow (new java::lang::InstantiationException);
|
||||
|
||||
_Jv_InitClass (this);
|
||||
|
||||
_Jv_Method *meth = _Jv_GetMethodLocal (this, init_name, void_signature);
|
||||
if (! meth)
|
||||
JvThrow (new java::lang::NoSuchMethodException);
|
||||
@@ -408,7 +408,7 @@ java::lang::Class::initializeClass (void)
|
||||
{
|
||||
// Step 1.
|
||||
_Jv_MonitorEnter (this);
|
||||
_Jv_InternClassStrings (this);
|
||||
_Jv_PrepareCompiledClass (this);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -20,8 +20,9 @@ details. */
|
||||
#include <java/lang/Character.h>
|
||||
#include <java/lang/Thread.h>
|
||||
#include <java/lang/ClassLoader.h>
|
||||
#include <java/lang/VMClassLoader.h>
|
||||
#include <gnu/gcj/runtime/VMClassLoader.h>
|
||||
#include <java/lang/InternalError.h>
|
||||
#include <java/lang/IllegalAccessError.h>
|
||||
#include <java/lang/LinkageError.h>
|
||||
#include <java/lang/ClassFormatError.h>
|
||||
#include <java/lang/NoClassDefFoundError.h>
|
||||
@@ -46,7 +47,7 @@ extern java::lang::Class ClassLoaderClass;
|
||||
/////////// java.lang.ClassLoader native methods ////////////
|
||||
|
||||
#ifdef INTERPRETER
|
||||
java::lang::VMClassLoader *redirect = 0;
|
||||
gnu::gcj::runtime::VMClassLoader *redirect = 0;
|
||||
#endif
|
||||
|
||||
java::lang::ClassLoader*
|
||||
@@ -54,7 +55,7 @@ java::lang::ClassLoader::getVMClassLoader0 ()
|
||||
{
|
||||
#ifdef INTERPRETER
|
||||
if (redirect == 0)
|
||||
redirect = new java::lang::VMClassLoader;
|
||||
redirect = new gnu::gcj::runtime::VMClassLoader;
|
||||
return redirect;
|
||||
#else
|
||||
return 0;
|
||||
@@ -144,7 +145,7 @@ _Jv_WaitForState (jclass klass, int state)
|
||||
if (state == JV_STATE_LINKED)
|
||||
{
|
||||
_Jv_MonitorExit (klass);
|
||||
_Jv_InternClassStrings (klass);
|
||||
_Jv_PrepareCompiledClass (klass);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -179,7 +180,7 @@ java::lang::ClassLoader::linkClass0 (java::lang::Class *klass)
|
||||
}
|
||||
#endif
|
||||
|
||||
_Jv_InternClassStrings (klass);
|
||||
_Jv_PrepareCompiledClass (klass);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -193,7 +194,7 @@ java::lang::ClassLoader::markClassErrorState0 (java::lang::Class *klass)
|
||||
/** this is the only native method in VMClassLoader, so
|
||||
we define it here. */
|
||||
jclass
|
||||
java::lang::VMClassLoader::findBootClass (jstring name)
|
||||
gnu::gcj::runtime::VMClassLoader::findSystemClass (jstring name)
|
||||
{
|
||||
return _Jv_FindClassInCache (_Jv_makeUtf8Const (name), 0);
|
||||
}
|
||||
@@ -204,22 +205,27 @@ java::lang::ClassLoader::findLoadedClass (jstring name)
|
||||
return _Jv_FindClassInCache (_Jv_makeUtf8Const (name), this);
|
||||
}
|
||||
|
||||
jclass
|
||||
java::lang::ClassLoader::findSystemClass (jstring name)
|
||||
{
|
||||
return _Jv_FindClass (_Jv_makeUtf8Const (name), 0);
|
||||
}
|
||||
static const int PUBLIC = 0x001;
|
||||
static const int PRIVATE = 0x002;
|
||||
static const int PROTECTED = 0x004;
|
||||
static const int STATIC = 0x008;
|
||||
static const int FINAL = 0x010;
|
||||
static const int SYNCHRONIZED = 0x020;
|
||||
static const int VOLATILE = 0x040;
|
||||
static const int TRANSIENT = 0x080;
|
||||
static const int NATIVE = 0x100;
|
||||
static const int INTERFACE = 0x200;
|
||||
static const int ABSTRACT = 0x400;
|
||||
static const int ALL_FLAGS = 0x7FF;
|
||||
|
||||
|
||||
/* This is the final step of linking, internalizing the constant strings
|
||||
* of a class. This is called for both compiled and interpreted
|
||||
* classes, and it is *only* called from ClassLoader::linkClass0,
|
||||
* which is always in a context where the current thread has a lock on
|
||||
* the class in question. We define it here, and not in resolve.cc, so that
|
||||
* the entire resolve.cc can be #ifdef'ed away when not using the
|
||||
* interpreter. */
|
||||
/** This function does class-preparation for compiled classes.
|
||||
NOTE: This function replicates functionality from
|
||||
_Jv_ResolvePoolEntry, and this is intentional, since that function
|
||||
is
|
||||
*/
|
||||
void
|
||||
_Jv_InternClassStrings(jclass klass)
|
||||
_Jv_PrepareCompiledClass(jclass klass)
|
||||
{
|
||||
if (klass->state >= JV_STATE_LINKED)
|
||||
return;
|
||||
@@ -228,14 +234,44 @@ _Jv_InternClassStrings(jclass klass)
|
||||
klass->state = JV_STATE_LINKED;
|
||||
|
||||
_Jv_Constants *pool = &klass->constants;
|
||||
for (int i = 1; i < pool->size; ++i)
|
||||
for (int index = 1; index < pool->size; ++index)
|
||||
{
|
||||
if (pool->tags[i] == JV_CONSTANT_String)
|
||||
if (pool->tags[index] == JV_CONSTANT_Class)
|
||||
{
|
||||
_Jv_Utf8Const *name = pool->data[index].utf8;
|
||||
|
||||
jclass found;
|
||||
if (name->data[0] == '[')
|
||||
found = _Jv_FindClassFromSignature (&name->data[0],
|
||||
klass->loader);
|
||||
else
|
||||
found = _Jv_FindClass (name, klass->loader);
|
||||
|
||||
if (! found)
|
||||
{
|
||||
jstring str = _Jv_NewStringUTF (name->data);
|
||||
JvThrow (new java::lang::ClassNotFoundException (str));
|
||||
}
|
||||
|
||||
if ((found->accflags & PUBLIC) == PUBLIC
|
||||
|| (_Jv_ClassNameSamePackage (found->name,
|
||||
klass->name)))
|
||||
{
|
||||
pool->data[index].clazz = found;
|
||||
pool->tags[index] |= JV_CONSTANT_ResolvedFlag;
|
||||
}
|
||||
else
|
||||
{
|
||||
JvThrow (new java::lang::IllegalAccessError (found->getName()));
|
||||
}
|
||||
}
|
||||
|
||||
else if (pool->tags[index] == JV_CONSTANT_String)
|
||||
{
|
||||
jstring str;
|
||||
str = _Jv_NewStringUtf8Const (pool->data[i].utf8);
|
||||
pool->data[i].string = str;
|
||||
pool->tags[i] |= JV_CONSTANT_ResolvedFlag;
|
||||
str = _Jv_NewStringUtf8Const (pool->data[index].utf8);
|
||||
pool->data[index].o = str;
|
||||
pool->tags[index] |= JV_CONSTANT_ResolvedFlag;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -443,7 +479,7 @@ jclass _Jv_FindClass (_Jv_Utf8Const *name,
|
||||
}
|
||||
|
||||
// Load using the bootstrap loader jmspec 5.3.1
|
||||
klass = redirect -> loadClassInternal (sname, false, true);
|
||||
klass = redirect -> loadClass (sname, false);
|
||||
|
||||
// register that we're an initiating loader
|
||||
if (klass)
|
||||
|
||||
Reference in New Issue
Block a user