* ipa-reference.c (analyze_function): Consider also addresses taken
[official-gcc.git] / libjava / java / lang / natVMClassLoader.cc
blob2db2429c92748bd2efe5d33f5c89dc88710ea7e0
1 // natVMClassLoader.cc - VMClassLoader native methods
3 /* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation
5 This file is part of libgcj.
7 This software is copyrighted work licensed under the terms of the
8 Libgcj License. Please consult the file "LIBGCJ_LICENSE" for
9 details. */
11 /* Author: Kresten Krab Thorup <krab@gnu.org> */
13 #include <config.h>
15 #include <stdlib.h>
16 #include <string.h>
18 #include <gcj/cni.h>
19 #include <jvm.h>
21 #include <java-threads.h>
22 #include <java-interp.h>
24 #include <java/lang/VMClassLoader.h>
25 #include <java/lang/VMCompiler.h>
26 #include <gnu/gcj/runtime/ExtensionClassLoader.h>
27 #include <gnu/gcj/runtime/SystemClassLoader.h>
28 #include <gnu/gcj/runtime/BootClassLoader.h>
29 #include <java/lang/ClassLoader.h>
30 #include <java/lang/Class.h>
31 #include <java/lang/Throwable.h>
32 #include <java/security/ProtectionDomain.h>
33 #include <java/lang/ClassFormatError.h>
34 #include <java/lang/StringBuffer.h>
35 #include <java/lang/Runtime.h>
36 #include <java/util/HashSet.h>
37 #include <java/lang/VirtualMachineError.h>
39 java::lang::Class *
40 java::lang::VMClassLoader::defineClass (java::lang::ClassLoader *loader,
41 jstring name,
42 jbyteArray data,
43 jint offset,
44 jint length,
45 java::security::ProtectionDomain *pd)
47 jclass klass = VMCompiler::compileClass(loader, name, data,
48 offset, length, pd);
50 if (klass)
51 _Jv_RegisterInitiatingLoader (klass, klass->loader);
53 #ifdef INTERPRETER
54 if (klass == NULL)
56 klass = new java::lang::Class ();
58 // Synchronize on the class, so that it is not attempted initialized
59 // until we're done loading.
60 JvSynchronize sync (klass);
62 // Record the defining loader. For the bootstrap class loader,
63 // we record NULL.
64 if (loader != bootLoader)
65 klass->loader = loader;
67 if (name != 0)
69 _Jv_Utf8Const *name2 = _Jv_makeUtf8Const (name);
71 if (! _Jv_VerifyClassName (name2))
72 throw new java::lang::ClassFormatError
73 (JvNewStringLatin1 ("erroneous class name"));
75 klass->name = name2;
78 _Jv_Utf8Const *found_name = NULL;
79 try
81 _Jv_DefineClass (klass, data, offset, length, pd, &found_name);
83 catch (java::lang::Throwable *ex)
85 klass->state = JV_STATE_ERROR;
86 klass->notifyAll ();
88 if (found_name != NULL)
89 _Jv_UnregisterInitiatingLoader (klass, klass->loader);
91 // If EX is not a ClassNotFoundException, that's ok, because we
92 // account for the possibility in defineClass().
93 throw ex;
96 // if everything proceeded sucessfully, we're loaded.
97 JvAssert (klass->state == JV_STATE_LOADED);
99 #endif // INTERPRETER
101 if (! klass)
103 StringBuffer *sb = new StringBuffer();
104 if (name)
106 sb->append(JvNewStringLatin1("found class file for class "));
107 sb->append(name);
109 else
110 sb->append(JvNewStringLatin1("found unnamed class file"));
111 sb->append(JvNewStringLatin1(", but no interpreter configured in this libgcj"));
112 throw new VirtualMachineError(sb->toString());
115 return klass;
118 java::lang::ClassLoader *
119 java::lang::VMClassLoader::getSystemClassLoaderInternal()
121 _Jv_InitClass (&gnu::gcj::runtime::ExtensionClassLoader::class$);
122 _Jv_CopyClassesToSystemLoader (gnu::gcj::runtime::ExtensionClassLoader::system_instance);
123 return gnu::gcj::runtime::ExtensionClassLoader::system_instance;
126 jclass
127 java::lang::VMClassLoader::getPrimitiveClass (jchar type)
129 char sig[2];
130 sig[0] = (char) type;
131 sig[1] = '\0';
132 // Note: this cannot return NULL, since the input is always correct.
133 return _Jv_FindClassFromSignature (sig, NULL);
136 void
137 java::lang::VMClassLoader::initBootLoader(jstring libdir)
139 bootLoader = new gnu::gcj::runtime::BootClassLoader(libdir);
142 jclass
143 java::lang::VMClassLoader::nativeFindClass (jstring name)
145 jclass klass = NULL;
147 if (lib_control != LIB_NEVER)
149 // Turn `gnu.pkg.quux' into `lib-gnu-pkg-quux'. Then search for
150 // a module named (eg, on Linux) `lib-gnu-pkg-quux.so', followed
151 // by `lib-gnu-pkg.so' and `lib-gnu.so'. If loading one of
152 // these causes the class to appear in the cache, then use it.
153 java::lang::StringBuffer *sb
154 = new java::lang::StringBuffer (JvNewStringLatin1("lib-"));
155 // Skip inner classes
156 jstring cn;
157 jint ci = name->indexOf('$');
158 if (ci == -1)
159 cn = name;
160 else
161 cn = name->substring (0, ci);
162 jstring so_base_name
163 = (sb->append (cn)->toString ())->replace ('.', '-');
165 using namespace ::java::lang;
166 Runtime *rt = Runtime::getRuntime();
168 _Jv_Utf8Const *name_u = NULL;
170 // Compare against `3' because that is the length of "lib".
171 while (! klass && so_base_name && so_base_name->length() > 3)
173 if (lib_control == LIB_CACHE)
175 // If we've already tried this name, we're done.
176 if (tried_libraries->contains(so_base_name))
177 break;
178 tried_libraries->add(so_base_name);
181 jboolean loaded = rt->loadLibraryInternal (so_base_name);
183 jint nd = so_base_name->lastIndexOf ('-');
184 if (nd == -1)
185 so_base_name = NULL;
186 else
187 so_base_name = so_base_name->substring (0, nd);
189 if (loaded)
191 if (name_u == NULL)
192 name_u = _Jv_makeUtf8Const (name);
193 klass = _Jv_FindClassInCache (name_u);
198 if (klass)
199 definePackageForNative(name);
201 return klass;
204 jclass
205 java::lang::VMClassLoader::loadClass(jstring name, jboolean resolve)
207 // We try the boot loader first, so that the endorsed directory
208 // overrides compiled-in classes.
209 jclass klass = NULL;
210 if (bootLoader)
211 klass = bootLoader->bootLoadClass(name);
212 if (! klass)
214 _Jv_Utf8Const *utf = _Jv_makeUtf8Const (name);
215 klass = _Jv_FindClassInCache (utf);
217 if (! klass)
218 klass = nativeFindClass(name);
219 if (klass)
221 // We never want to return a class without its supers linked.
222 // It isn't clear from the spec, but this is what other
223 // implementations do in practice.
224 if (resolve)
225 resolveClass (klass);
226 else
227 _Jv_Linker::wait_for_state (klass, JV_STATE_LOADING);
229 definePackageForNative(name);
232 return klass;