GNU header update.
[cacao.git] / src / native / vm / VMClassLoader.c
index 23a83c4f91cb6ddf9ff58de141e558f174c1d363..a7086c43ac445e0163251aee8941839724166f67 100644 (file)
@@ -1,9 +1,9 @@
-/* nat/VMClassLoader.c - java/lang/ClassLoader
+/* native/vm/VMClassLoader.c - java/lang/VMClassLoader
 
-   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
-   R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser,
-   M. Probst, S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck,
-   P. Tomsich, J. Wenninger
+   Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
+   R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
+   C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
+   Institut f. Computersprachen - TU Wien
 
    This file is part of CACAO.
 
 
    Changes: Joseph Wenninger
 
-   $Id: VMClassLoader.c 1067 2004-05-18 10:25:51Z stefan $
+   $Id: VMClassLoader.c 1735 2004-12-07 14:33:27Z twisti $
 
 */
 
 
-#include "jni.h"
-#include "loader.h"
-#include "native.h"
-#include "builtin.h"
+#include "native/jni.h"
+#include "native/native.h"
+#include "native/include/java_lang_Class.h"
+#include "native/include/java_lang_String.h"
+#include "native/include/java_lang_ClassLoader.h"
 #include "toolbox/logging.h"
-#include "java_lang_Class.h"
-#include "java_lang_String.h"
-#include "java_lang_ClassLoader.h"
+#include "vm/exceptions.h"
+#include "vm/builtin.h"
+#include "vm/loader.h"
+#include "vm/tables.h"
+
 
 /*
  * Class:     java/lang/ClassLoader
- * Method:    defineClass0
+ * Method:    defineClass
  * Signature: (Ljava/lang/String;[BII)Ljava/lang/Class;
  */
 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)
@@ -53,13 +56,23 @@ JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClassLoader_defineClass(JNIE
 
        log_text("Java_java_lang_VMClassLoader_defineClass called");
 
+       if (off < 0 || len < 0 || off + len > buf->header.size) {
+               *exceptionptr =
+                       new_exception(string_java_lang_IndexOutOfBoundsException);
+               return NULL;
+       }
+
        /* call JNI-function to load the class */
        c = (*env)->DefineClass(env,
-                                                       javastring_tochar((java_objectheader*) name),
+                                                       javastring_tochar((java_objectheader *) name),
                                                        (jobject) this,
-                                                       (const jbyte *) &buf[off],
+                                                       (const jbyte *) &buf->data[off],
                                                        len);
 
+       /* exception? return! */
+       if (!c)
+               return NULL;
+
        use_class_as_object(c);
 
        return (java_lang_Class *) c;
@@ -67,7 +80,7 @@ JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClassLoader_defineClass(JNIE
 
 
 /*
- * Class:     java/lang/Class
+ * Class:     java/lang/ClassLoader
  * Method:    getPrimitiveClass
  * Signature: (Ljava/lang/String;)Ljava/lang/Class;
  */
@@ -76,38 +89,105 @@ JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClassLoader_getPrimitiveClas
        classinfo *c;
        utf *u = javastring_toutf(name, false);
 
-       if (u) {
-               /* get primitive class */
-               c = class_new(u);
-               class_load(c);
-               class_init(c);
-               use_class_as_object(c);
-
-               return (java_lang_Class *) c;
+       /* illegal primitive classname specified */
+       if (!u) {
+               *exceptionptr = new_exception(string_java_lang_ClassNotFoundException);
+               return NULL;
        }
 
-       /* illegal primitive classname specified */
-       *exceptionptr = new_exception(string_java_lang_ClassNotFoundException);
+       /* get primitive class */
+       c = class_new(u);
+
+       if (!class_load(c))
+               return NULL;
+
+       if (!class_init(c))
+               return NULL;
 
-       return NULL;
+       use_class_as_object(c);
+
+       return (java_lang_Class *) c;
 }
 
 
 /*
  * Class:     java/lang/ClassLoader
- * Method:    resolveClass0
+ * Method:    resolveClass
  * Signature: (Ljava/lang/Class;)V
  */
-JNIEXPORT void JNICALL Java_java_lang_VMClassLoader_resolveClass(JNIEnv *env, jclass clazz, java_lang_Class *par1)
+JNIEXPORT void JNICALL Java_java_lang_VMClassLoader_resolveClass(JNIEnv *env, jclass clazz, java_lang_Class *c)
 {
-       /* linked the class */
-       if (!clazz->linked)
-               class_link(clazz);
+       classinfo *ci;
+
+       ci = (classinfo *) c;
+
+       if (!ci) {
+               *exceptionptr = new_exception(string_java_lang_NullPointerException);
+               return;
+       }
+
+       /* link the class */
+       if (!ci->linked)
+               class_link(ci);
 
        return;
 }
 
 
+/*
+ * Class:     java/lang/VMClassLoader
+ * Method:    loadClass
+ * Signature: (Ljava/lang/String;Z)Ljava/lang/Class;
+ */
+JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClassLoader_loadClass(JNIEnv *env, jclass clazz, java_lang_String *name, jboolean resolve)
+{
+       classinfo *c;
+       utf *u;
+
+       if (!name) {
+               *exceptionptr = new_exception(string_java_lang_NullPointerException);
+               return NULL;
+       }
+
+       /* create utf string in which '.' is replaced by '/' */
+       u = javastring_toutf(name, true);
+
+       /* create class */
+       c = class_new(u);
+
+       /* load class */
+       if (!class_load(c)) {
+               classinfo *xclass;
+
+               xclass = (*exceptionptr)->vftbl->class;
+
+               /* if the exception is a NoClassDefFoundError, we replace it with a
+                  ClassNotFoundException, otherwise return the exception */
+
+               if (xclass == class_get(utf_new_char(string_java_lang_NoClassDefFoundError))) {
+                       /* clear exceptionptr, because builtin_new checks for 
+                          ExceptionInInitializerError */
+                       *exceptionptr = NULL;
+
+                       *exceptionptr =
+                               new_exception_javastring(string_java_lang_ClassNotFoundException, name);
+               }
+
+               return NULL;
+       }
+
+       /* resolve class -- if requested */
+       /* XXX TWISTI: we do not support REAL (at runtime) lazy linking */
+/*     if (resolve) */
+               if (!class_link(c))
+                       return NULL;
+
+       use_class_as_object(c);
+
+       return (java_lang_Class *) c;
+}
+
+
 /*
  * These are local overrides for various environment variables in Emacs.
  * Please do not remove this and leave it at the end of the file, where