diff options
Diffstat (limited to 'libjava/java/lang/natVMClassLoader.cc')
-rw-r--r-- | libjava/java/lang/natVMClassLoader.cc | 99 |
1 files changed, 91 insertions, 8 deletions
diff --git a/libjava/java/lang/natVMClassLoader.cc b/libjava/java/lang/natVMClassLoader.cc index 1da79497154..182b8d72743 100644 --- a/libjava/java/lang/natVMClassLoader.cc +++ b/libjava/java/lang/natVMClassLoader.cc @@ -23,13 +23,17 @@ details. */ #include <java/lang/VMClassLoader.h> #include <java/lang/VMCompiler.h> -#include <gnu/gcj/runtime/VMClassLoader.h> +#include <gnu/gcj/runtime/ExtensionClassLoader.h> #include <gnu/gcj/runtime/SystemClassLoader.h> +#include <gnu/gcj/runtime/BootClassLoader.h> #include <java/lang/ClassLoader.h> #include <java/lang/Class.h> #include <java/lang/Throwable.h> #include <java/security/ProtectionDomain.h> #include <java/lang/ClassFormatError.h> +#include <java/lang/StringBuffer.h> +#include <java/lang/Runtime.h> +#include <java/util/HashSet.h> void java::lang::VMClassLoader::resolveClass (jclass klass) @@ -66,9 +70,9 @@ java::lang::VMClassLoader::defineClass (java::lang::ClassLoader *loader, // 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()) + // Record the defining loader. For the bootstrap class loader, + // we record NULL. + if (loader != bootLoader) klass->loader = loader; if (name != 0) @@ -109,8 +113,8 @@ java::lang::VMClassLoader::defineClass (java::lang::ClassLoader *loader, java::lang::ClassLoader * java::lang::VMClassLoader::getSystemClassLoaderInternal() { - _Jv_InitClass (&gnu::gcj::runtime::VMClassLoader::class$); - return gnu::gcj::runtime::VMClassLoader::system_instance; + _Jv_InitClass (&gnu::gcj::runtime::ExtensionClassLoader::class$); + return gnu::gcj::runtime::ExtensionClassLoader::system_instance; } jclass @@ -119,14 +123,93 @@ java::lang::VMClassLoader::getPrimitiveClass (jchar type) char sig[2]; sig[0] = (char) type; sig[1] = '\0'; + // Note: this cannot return NULL, since the input is always correct. return _Jv_FindClassFromSignature (sig, NULL); } +void +java::lang::VMClassLoader::initBootLoader(jstring libdir) +{ + bootLoader = new gnu::gcj::runtime::BootClassLoader(libdir); +} + +jclass +java::lang::VMClassLoader::nativeFindClass (jstring name) +{ + jclass klass = NULL; + + if (lib_control != LIB_NEVER) + { + // Turn `gnu.pkg.quux' into `lib-gnu-pkg-quux'. Then search for + // a module named (eg, on Linux) `lib-gnu-pkg-quux.so', followed + // by `lib-gnu-pkg.so' and `lib-gnu.so'. If loading one of + // these causes the class to appear in the cache, then use it. + java::lang::StringBuffer *sb + = new java::lang::StringBuffer (JvNewStringLatin1("lib-")); + // Skip inner classes + jstring cn; + jint ci = name->indexOf('$'); + if (ci == -1) + cn = name; + else + cn = name->substring (0, ci); + jstring so_base_name + = (sb->append (cn)->toString ())->replace ('.', '-'); + + using namespace ::java::lang; + Runtime *rt = Runtime::getRuntime(); + + _Jv_Utf8Const *name_u = NULL; + + // Compare against `3' because that is the length of "lib". + while (! klass && so_base_name && so_base_name->length() > 3) + { + if (lib_control == LIB_CACHE) + { + // If we've already tried this name, we're done. + if (tried_libraries->contains(so_base_name)) + break; + tried_libraries->add(so_base_name); + } + + jboolean loaded = rt->loadLibraryInternal (so_base_name); + + jint nd = so_base_name->lastIndexOf ('-'); + if (nd == -1) + so_base_name = NULL; + else + so_base_name = so_base_name->substring (0, nd); + + if (loaded) + { + if (name_u == NULL) + name_u = _Jv_makeUtf8Const (name); + klass = _Jv_FindClassInCache (name_u); + } + } + } + + if (klass) + definePackageForNative(name); + + return klass; +} + jclass java::lang::VMClassLoader::loadClass(jstring name, jboolean resolve) { - _Jv_Utf8Const *utf = _Jv_makeUtf8Const (name); - jclass klass = _Jv_FindClassInCache (utf); + // We try the boot loader first, so that the endorsed directory + // overrides compiled-in classes. + jclass klass = NULL; + if (bootLoader) + klass = bootLoader->bootLoadClass(name); + if (! klass) + { + _Jv_Utf8Const *utf = _Jv_makeUtf8Const (name); + klass = _Jv_FindClassInCache (utf); + } + if (! klass) + klass = nativeFindClass(name); if (klass) { // We never want to return a class without its supers linked. |