1 /* 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
32 $Id: VMClassLoader.c 2188 2005-04-02 01:15:33Z edwin $
41 #include "mm/memory.h"
42 #include "native/jni.h"
43 #include "native/native.h"
44 #include "native/include/java_lang_Class.h"
45 #include "native/include/java_lang_String.h"
46 #include "native/include/java_lang_ClassLoader.h"
47 #include "native/include/java_security_ProtectionDomain.h"
48 #include "native/include/java_util_Vector.h"
49 #include "toolbox/logging.h"
51 #include "vm/exceptions.h"
52 #include "vm/builtin.h"
53 #include "vm/loader.h"
54 #include "vm/options.h"
55 #include "vm/statistics.h"
56 #include "vm/stringlocal.h"
57 #include "vm/tables.h"
58 #include "vm/jit/asmpart.h"
62 * Class: java/lang/VMClassLoader
64 * Signature: (Ljava/lang/ClassLoader;Ljava/lang/String;[BIILjava/security/ProtectionDomain;)Ljava/lang/Class;
66 JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClassLoader_defineClass(JNIEnv *env, jclass clazz, java_lang_ClassLoader *this, java_lang_String *name, java_bytearray *buf, s4 off, s4 len, java_security_ProtectionDomain *pd)
72 if ((off < 0) || (len < 0) || ((off + len) > buf->header.size)) {
74 new_exception(string_java_lang_IndexOutOfBoundsException);
79 /* XXX we have to support this case (name is read from classbuffer) */
80 log_text("defineClass(name == NULL,...) is not implemented, yet");
81 *exceptionptr = new_nullpointerexception();
85 /* convert '.' to '/' in java string */
87 c = class_new(javastring_toutf(name, true));
89 #if defined(USE_THREADS)
90 /* enter a monitor on the class */
92 builtin_monitorenter((java_objectheader *) c);
95 #if defined(STATISTICS)
102 /* build a classbuffer with the given data */
104 cb = NEW(classbuffer);
107 cb->data = (u1 *) &buf->data[off];
108 cb->pos = cb->data - 1;
110 /* preset the defining classloader */
112 c->classloader = (java_objectheader *) this;
114 /* load the class from this buffer */
116 r = load_class_from_classbuffer(cb);
120 FREE(cb, classbuffer);
122 #if defined(STATISTICS)
129 #if defined(USE_THREADS)
130 /* leave the monitor */
132 builtin_monitorexit((java_objectheader *) c);
135 /* exception? return! */
138 /* If return value is NULL, we had a problem and the class is not */
143 /* now free the allocated memory, otherwise we could ran into a DOS */
150 /* set ProtectionDomain */
154 use_class_as_object(c);
156 return (java_lang_Class *) c;
161 * Class: java/lang/VMClassLoader
162 * Method: getPrimitiveClass
163 * Signature: (Ljava/lang/String;)Ljava/lang/Class;
165 JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClassLoader_getPrimitiveClass(JNIEnv *env, jclass clazz, java_lang_String *type)
170 u = javastring_toutf(type, false);
172 /* illegal primitive classname specified */
175 *exceptionptr = new_exception(string_java_lang_ClassNotFoundException);
179 /* get primitive class */
183 if (!load_class_bootstrap(c) || !class_init(c))
186 use_class_as_object(c);
188 return (java_lang_Class *) c;
193 * Class: java/lang/VMClassLoader
194 * Method: resolveClass
195 * Signature: (Ljava/lang/Class;)V
197 JNIEXPORT void JNICALL Java_java_lang_VMClassLoader_resolveClass(JNIEnv *env, jclass clazz, java_lang_Class *c)
201 ci = (classinfo *) c;
204 *exceptionptr = new_nullpointerexception();
218 * Class: java/lang/VMClassLoader
220 * Signature: (Ljava/lang/String;Z)Ljava/lang/Class;
222 JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClassLoader_loadClass(JNIEnv *env, jclass clazz, java_lang_String *name, jboolean resolve)
228 *exceptionptr = new_exception(string_java_lang_NullPointerException);
232 /* create utf string in which '.' is replaced by '/' */
234 u = javastring_toutf(name, true);
242 if (!load_class_bootstrap(c))
245 /* resolve class -- if requested */
246 /* XXX TWISTI: we do not support REAL (at runtime) lazy linking */
251 use_class_as_object(c);
254 return (java_lang_Class *) c;
257 c = (*exceptionptr)->vftbl->class;
259 /* if the exception is a NoClassDefFoundError, we replace it with a
260 ClassNotFoundException, otherwise return the exception */
262 if (c == class_java_lang_NoClassDefFoundError) {
263 /* clear exceptionptr, because builtin_new checks for
264 ExceptionInInitializerError */
265 *exceptionptr = NULL;
268 new_exception_javastring(string_java_lang_ClassNotFoundException, name);
276 * Class: java/lang/VMClassLoader
277 * Method: nativeGetResources
278 * Signature: (Ljava/lang/String;)Ljava/util/Vector;
280 JNIEXPORT java_util_Vector* JNICALL Java_java_lang_VMClassLoader_nativeGetResources(JNIEnv *env, jclass clazz, java_lang_String *name)
284 java_lang_String *path;
294 /* get the resource name as utf string */
296 utfname = javastring_toutf(name, false);
298 namelen = utf_strlen(utfname) + strlen("0");
299 charname = MNEW(char, namelen);
301 utf_sprint(charname, utfname);
305 o = native_new_and_init(class_java_util_Vector);
310 /* get v.add() method */
312 m = class_resolveclassmethod(class_java_util_Vector,
314 utf_new_char("(Ljava/lang/Object;)Z"),
321 for (cpi = classpath_entries; cpi != NULL; cpi = cpi->next) {
322 /* clear path pointer */
325 #if defined(USE_ZLIB)
326 if (cpi->type == CLASSPATH_ARCHIVE) {
328 #if defined(USE_THREADS)
329 /* enter a monitor on zip/jar archives */
331 builtin_monitorenter((java_objectheader *) cpi);
334 if (cacao_locate(cpi->uf, utfname) == UNZ_OK) {
335 pathlen = strlen("jar:file://") + cpi->pathlen + strlen("!/") +
336 namelen + strlen("0");
338 tmppath = MNEW(char, pathlen);
340 sprintf(tmppath, "jar:file://%s!/%s", cpi->path, charname);
341 path = javastring_new_char(tmppath),
343 MFREE(tmppath, char, pathlen);
346 #if defined(USE_THREADS)
347 /* leave the monitor */
349 builtin_monitorexit((java_objectheader *) cpi);
353 #endif /* defined(USE_ZLIB) */
354 pathlen = strlen("file://") + cpi->pathlen + namelen + strlen("0");
356 tmppath = MNEW(char, pathlen);
358 sprintf(tmppath, "file://%s%s", cpi->path, charname);
360 if (stat(tmppath + strlen("file://") - 1, &buf) == 0)
361 path = javastring_new_char(tmppath),
363 MFREE(tmppath, char, pathlen);
364 #if defined(USE_ZLIB)
368 /* if a resource was found, add it to the vector */
371 ret = (jboolean) asm_calljavafunction_int(m, o, path, NULL, NULL);
378 return (java_util_Vector *) o;
383 * These are local overrides for various environment variables in Emacs.
384 * Please do not remove this and leave it at the end of the file, where
385 * Emacs will automagically detect them.
386 * ---------------------------------------------------------------------
389 * indent-tabs-mode: t