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