1 /* src/native/vm/VMClassLoader.c - java/lang/VMClassLoader
3 Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
4 R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
5 C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
6 Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
25 Contact: cacao@complang.tuwien.ac.at
27 Authors: Roman Obermaiser
29 Changes: Joseph Wenninger
33 $Id: VMClassLoader.c 4151 2006-01-12 21:13:27Z twisti $
43 #include "mm/memory.h"
44 #include "native/jni.h"
45 #include "native/native.h"
46 #include "native/include/java_lang_Class.h"
47 #include "native/include/java_lang_String.h"
48 #include "native/include/java_lang_ClassLoader.h"
49 #include "native/include/java_security_ProtectionDomain.h"
50 #include "native/include/java_util_Vector.h"
51 #include "toolbox/logging.h"
52 #include "vm/builtin.h"
54 #include "vm/classcache.h"
55 #include "vm/exceptions.h"
56 #include "vm/initialize.h"
57 #include "vm/linker.h"
58 #include "vm/loader.h"
59 #include "vm/options.h"
60 #include "vm/statistics.h"
61 #include "vm/stringlocal.h"
64 #include "vm/jit/asmpart.h"
68 * Class: java/lang/VMClassLoader
70 * Signature: (Ljava/lang/ClassLoader;Ljava/lang/String;[BIILjava/security/ProtectionDomain;)Ljava/lang/Class;
72 JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClassLoader_defineClass(JNIEnv *env, jclass clazz, java_lang_ClassLoader *cl, java_lang_String *name, java_bytearray *data, s4 offset, s4 len, java_security_ProtectionDomain *pd)
79 /* check if data was passed */
82 exceptions_throw_nullpointerexception();
86 /* check the indexes passed */
88 if ((offset < 0) || (len < 0) || ((offset + len) > data->header.size)) {
89 exceptions_throw_arrayindexoutofboundsexception();
94 /* convert '.' to '/' in java string */
96 utfname = javastring_toutf(name, true);
98 /* check if this class has already been defined */
100 c = classcache_lookup_defined_or_initiated((java_objectheader *) cl, utfname);
103 exceptions_new_linkageerror("duplicate class definition: ",c);
111 /* create a new classinfo struct */
113 c = class_create_classinfo(utfname);
115 #if defined(ENABLE_STATISTICS)
122 /* build a classbuffer with the given data */
124 cb = NEW(classbuffer);
127 cb->data = (u1 *) &data->data[offset];
130 /* preset the defining classloader */
132 c->classloader = (java_objectheader *) cl;
134 /* load the class from this buffer */
136 r = load_class_from_classbuffer(cb);
140 FREE(cb, classbuffer);
142 #if defined(ENABLE_STATISTICS)
150 /* If return value is NULL, we had a problem and the class is not */
152 /* now free the allocated memory, otherwise we could run into a DOS */
159 /* set ProtectionDomain */
163 /* Store the newly defined class in the class cache. This call also */
164 /* checks whether a class of the same name has already been defined by */
165 /* the same defining loader, and if so, replaces the newly created class */
166 /* by the one defined earlier. */
167 /* Important: The classinfo given to classcache_store_defined must be */
168 /* fully prepared because another thread may return this */
169 /* pointer after the lookup at to top of this function */
170 /* directly after the class cache lock has been released. */
172 c = classcache_store_defined(c);
174 return (java_lang_Class *) c;
179 * Class: java/lang/VMClassLoader
180 * Method: getPrimitiveClass
181 * Signature: (C)Ljava/lang/Class;
183 JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClassLoader_getPrimitiveClass(JNIEnv *env, jclass clazz, s4 type)
187 /* get primitive class */
191 c = primitivetype_table[PRIMITIVETYPE_INT].class_primitive;
194 c = primitivetype_table[PRIMITIVETYPE_LONG].class_primitive;
197 c = primitivetype_table[PRIMITIVETYPE_FLOAT].class_primitive;
200 c = primitivetype_table[PRIMITIVETYPE_DOUBLE].class_primitive;
203 c = primitivetype_table[PRIMITIVETYPE_BYTE].class_primitive;
206 c = primitivetype_table[PRIMITIVETYPE_CHAR].class_primitive;
209 c = primitivetype_table[PRIMITIVETYPE_SHORT].class_primitive;
212 c = primitivetype_table[PRIMITIVETYPE_BOOLEAN].class_primitive;
215 c = primitivetype_table[PRIMITIVETYPE_VOID].class_primitive;
218 *exceptionptr = new_exception(string_java_lang_ClassNotFoundException);
222 return (java_lang_Class *) c;
227 * Class: java/lang/VMClassLoader
228 * Method: resolveClass
229 * Signature: (Ljava/lang/Class;)V
231 JNIEXPORT void JNICALL Java_java_lang_VMClassLoader_resolveClass(JNIEnv *env, jclass clazz, java_lang_Class *c)
235 ci = (classinfo *) c;
238 exceptions_throw_nullpointerexception();
244 if (!(ci->state & CLASS_LINKED))
245 (void) link_class(ci);
252 * Class: java/lang/VMClassLoader
254 * Signature: (Ljava/lang/String;Z)Ljava/lang/Class;
256 JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClassLoader_loadClass(JNIEnv *env, jclass clazz, java_lang_String *name, jboolean resolve)
262 exceptions_throw_nullpointerexception();
266 /* create utf string in which '.' is replaced by '/' */
268 u = javastring_toutf(name, true);
272 if (!(c = load_class_bootstrap(u)))
275 /* resolve class -- if requested */
276 /* XXX TWISTI: we do not support REAL (at runtime) lazy linking */
282 return (java_lang_Class *) c;
285 c = (*exceptionptr)->vftbl->class;
287 /* if the exception is a NoClassDefFoundError, we replace it with a
288 ClassNotFoundException, otherwise return the exception */
290 if (c == class_java_lang_NoClassDefFoundError) {
291 /* clear exceptionptr, because builtin_new checks for
292 ExceptionInInitializerError */
293 *exceptionptr = NULL;
296 new_exception_javastring(string_java_lang_ClassNotFoundException, name);
304 * Class: java/lang/VMClassLoader
305 * Method: nativeGetResources
306 * Signature: (Ljava/lang/String;)Ljava/util/Vector;
308 JNIEXPORT java_util_Vector* JNICALL Java_java_lang_VMClassLoader_nativeGetResources(JNIEnv *env, jclass clazz, java_lang_String *name)
312 java_lang_String *path;
313 list_classpath_entry *lce;
323 /* get the resource name as utf string */
325 utfname = javastring_toutf(name, false);
327 namelen = utf_strlen(utfname) + strlen("0");
328 charname = MNEW(char, namelen);
330 utf_sprint(charname, utfname);
332 /* search for `.class', if found remove it */
334 if ((end = strstr(charname, ".class"))) {
336 utfname = utf_new_char(charname);
338 /* little hack, but it should work */
344 o = native_new_and_init(class_java_util_Vector);
349 /* get Vector.add() method */
351 m = class_resolveclassmethod(class_java_util_Vector,
353 utf_new_char("(Ljava/lang/Object;)Z"),
360 for (lce = list_first(list_classpath_entries); lce != NULL;
361 lce = list_next(list_classpath_entries, lce)) {
362 /* clear path pointer */
365 #if defined(ENABLE_ZLIB)
366 if (lce->type == CLASSPATH_ARCHIVE) {
368 if (zip_find(lce, utfname)) {
369 pathlen = strlen("jar:file://") + lce->pathlen + strlen("!/") +
370 namelen + strlen("0");
372 tmppath = MNEW(char, pathlen);
374 sprintf(tmppath, "jar:file://%s!/%s", lce->path, charname);
375 path = javastring_new_char(tmppath),
377 MFREE(tmppath, char, pathlen);
381 #endif /* defined(ENABLE_ZLIB) */
382 pathlen = strlen("file://") + lce->pathlen + namelen + strlen("0");
384 tmppath = MNEW(char, pathlen);
386 sprintf(tmppath, "file://%s%s", lce->path, charname);
388 if (stat(tmppath + strlen("file://") - 1, &buf) == 0)
389 path = javastring_new_char(tmppath),
391 MFREE(tmppath, char, pathlen);
392 #if defined(ENABLE_ZLIB)
396 /* if a resource was found, add it to the vector */
399 ASM_CALLJAVAFUNCTION_INT(ret, m, o, path, NULL, NULL);
406 return (java_util_Vector *) o;
411 * Class: java/lang/VMClassLoader
412 * Method: findLoadedClass
413 * Signature: (Ljava/lang/ClassLoader;Ljava/lang/String;)Ljava/lang/Class;
415 JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClassLoader_findLoadedClass(JNIEnv *env, jclass clazz, java_lang_ClassLoader *cl, java_lang_String *name)
420 /* replace `.' by `/', this is required by the classcache */
422 u = javastring_toutf(name, true);
424 /* lookup for defining classloader */
426 c = classcache_lookup_defined((classloader *) cl, u);
428 /* if not found, lookup for initiating classloader */
431 c = classcache_lookup((classloader *) cl, u);
433 return (java_lang_Class *) c;
438 * These are local overrides for various environment variables in Emacs.
439 * Please do not remove this and leave it at the end of the file, where
440 * Emacs will automagically detect them.
441 * ---------------------------------------------------------------------
444 * indent-tabs-mode: t