- support external classpath
[cacao.git] / src / native / vm / VMClassLoader.c
1 /* native/vm/VMClassLoader.c - java/lang/VMClassLoader
2
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
7
8    This file is part of CACAO.
9
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.
14
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.
19
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
23    02111-1307, USA.
24
25    Contact: cacao@complang.tuwien.ac.at
26
27    Authors: Roman Obermaiser
28
29    Changes: Joseph Wenninger
30             Christian Thalinger
31
32    $Id: VMClassLoader.c 1919 2005-02-10 10:08:53Z twisti $
33
34 */
35
36
37 #include "mm/memory.h"
38 #include "native/jni.h"
39 #include "native/native.h"
40 #include "native/include/java_lang_Class.h"
41 #include "native/include/java_lang_String.h"
42 #include "native/include/java_lang_ClassLoader.h"
43 #include "toolbox/logging.h"
44 #include "vm/exceptions.h"
45 #include "vm/builtin.h"
46 #include "vm/loader.h"
47 #include "vm/stringlocal.h"
48 #include "vm/tables.h"
49
50
51 /*
52  * Class:     java/lang/VMClassLoader
53  * Method:    defineClass
54  * Signature: (Ljava/lang/String;[BII)Ljava/lang/Class;
55  */
56 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)
57 {
58         classinfo *c;
59         char *tmp;
60
61         if (off < 0 || len < 0 || off + len > buf->header.size) {
62                 *exceptionptr =
63                         new_exception(string_java_lang_IndexOutOfBoundsException);
64                 return NULL;
65         }
66
67         /* convert class name to char string */
68
69         tmp = javastring_tochar((java_objectheader *) name);
70
71         /* call JNI-function to load the class */
72         c = (*env)->DefineClass(env,
73                                                         tmp,
74                                                         (jobject) this,
75                                                         (const jbyte *) &buf->data[off],
76                                                         len);
77
78         /* release memory allocated by javastring_tochar */
79
80         MFREE(tmp, char, strlen(tmp));
81
82         /* exception? return! */
83         if (!c)
84                 return NULL;
85
86         use_class_as_object(c);
87
88         return (java_lang_Class *) c;
89 }
90
91
92 /*
93  * Class:     java/lang/VMClassLoader
94  * Method:    getPrimitiveClass
95  * Signature: (Ljava/lang/String;)Ljava/lang/Class;
96  */
97 JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClassLoader_getPrimitiveClass(JNIEnv *env, jclass clazz, java_lang_String *name)
98 {
99         classinfo *c;
100         utf *u = javastring_toutf(name, false);
101
102         /* illegal primitive classname specified */
103         if (!u) {
104                 *exceptionptr = new_exception(string_java_lang_ClassNotFoundException);
105                 return NULL;
106         }
107
108         /* get primitive class */
109         c = class_new(u);
110
111         if (!class_load(c) || !class_init(c))
112                 return NULL;
113
114         use_class_as_object(c);
115
116         return (java_lang_Class *) c;
117 }
118
119
120 /*
121  * Class:     java/lang/VMClassLoader
122  * Method:    resolveClass
123  * Signature: (Ljava/lang/Class;)V
124  */
125 JNIEXPORT void JNICALL Java_java_lang_VMClassLoader_resolveClass(JNIEnv *env, jclass clazz, java_lang_Class *c)
126 {
127         classinfo *ci;
128
129         ci = (classinfo *) c;
130
131         if (!ci) {
132                 *exceptionptr = new_exception(string_java_lang_NullPointerException);
133                 return;
134         }
135
136         /* link the class */
137         if (!ci->linked)
138                 class_link(ci);
139
140         return;
141 }
142
143
144 /*
145  * Class:     java/lang/VMClassLoader
146  * Method:    loadClass
147  * Signature: (Ljava/lang/String;Z)Ljava/lang/Class;
148  */
149 JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClassLoader_loadClass(JNIEnv *env, jclass clazz, java_lang_String *name, jboolean resolve)
150 {
151         classinfo *c;
152         utf *u;
153
154         if (!name) {
155                 *exceptionptr = new_exception(string_java_lang_NullPointerException);
156                 return NULL;
157         }
158
159         /* create utf string in which '.' is replaced by '/' */
160         u = javastring_toutf(name, true);
161
162         /* create class */
163         c = class_new(u);
164
165         /* load class */
166         if (!class_load(c)) {
167                 classinfo *xclass;
168
169                 xclass = (*exceptionptr)->vftbl->class;
170
171                 /* if the exception is a NoClassDefFoundError, we replace it with a
172                    ClassNotFoundException, otherwise return the exception */
173
174                 if (xclass == class_get(utf_new_char(string_java_lang_NoClassDefFoundError))) {
175                         /* clear exceptionptr, because builtin_new checks for 
176                            ExceptionInInitializerError */
177                         *exceptionptr = NULL;
178
179                         *exceptionptr =
180                                 new_exception_javastring(string_java_lang_ClassNotFoundException, name);
181                 }
182
183                 return NULL;
184         }
185
186         /* resolve class -- if requested */
187         /* XXX TWISTI: we do not support REAL (at runtime) lazy linking */
188 /*      if (resolve) */
189                 if (!class_link(c))
190                         return NULL;
191
192         use_class_as_object(c);
193
194         return (java_lang_Class *) c;
195 }
196
197
198 /*
199  * These are local overrides for various environment variables in Emacs.
200  * Please do not remove this and leave it at the end of the file, where
201  * Emacs will automagically detect them.
202  * ---------------------------------------------------------------------
203  * Local variables:
204  * mode: c
205  * indent-tabs-mode: t
206  * c-basic-offset: 4
207  * tab-width: 4
208  * End:
209  */