Clean merge -> gc7-branch
[cacao.git] / src / native / vm / gnu / java_lang_VMClassLoader.c
index f30764e02089e916cc72b065ef8a718d60755f9f..7df215ca4a8ddbf57f5e43fc34fa53647a1f300d 100644 (file)
@@ -1,9 +1,7 @@
-/* src/native/vm/gnu/VMClassLoader.c
+/* src/native/vm/gnu/java_lang_VMClassLoader.c
 
-   Copyright (C) 1996-2005, 2006, 2007 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
+   Copyright (C) 1996-2005, 2006, 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   $Id: java_lang_VMClassLoader.c 7918 2007-05-20 20:42:18Z michi $
-
 */
 
 
 #include "config.h"
 
 #include <assert.h>
+#include <stdint.h>
 #include <sys/stat.h>
 
-#include "vm/types.h"
-
 #include "mm/memory.h"
 
 #include "native/jni.h"
+#include "native/llni.h"
 #include "native/native.h"
 #include "native/include/java_lang_Class.h"
 #include "native/include/java_lang_String.h"
 #include "native/include/java_security_ProtectionDomain.h"  /* required by... */
 #include "native/include/java_lang_ClassLoader.h"
 #include "native/include/java_util_Vector.h"
+#include "native/include/java_util_HashMap.h"
+#include "native/include/java_util_Map.h"
+#include "native/include/java_lang_Boolean.h"
 
 #include "native/include/java_lang_VMClassLoader.h"
 
-#include "native/vm/java_lang_ClassLoader.h"
-
 #include "toolbox/logging.h"
+#include "toolbox/list.h"
+
+#if defined(ENABLE_ASSERTION)
+#include "vm/assertion.h"
+#endif
 
 #include "vm/builtin.h"
 #include "vm/exceptions.h"
 #include "vm/initialize.h"
+#include "vm/primitive.h"
 #include "vm/stringlocal.h"
 #include "vm/vm.h"
 
 #include "native/jvmti/cacaodbg.h"
 #endif
 
-
 /* native methods implemented by this file ************************************/
 
 static JNINativeMethod methods[] = {
-       { "defineClass",            "(Ljava/lang/ClassLoader;Ljava/lang/String;[BIILjava/security/ProtectionDomain;)Ljava/lang/Class;", (void *) (ptrint) &Java_java_lang_VMClassLoader_defineClass            },
-       { "getPrimitiveClass",      "(C)Ljava/lang/Class;",                                                                             (void *) (ptrint) &Java_java_lang_VMClassLoader_getPrimitiveClass      },
-       { "resolveClass",           "(Ljava/lang/Class;)V",                                                                             (void *) (ptrint) &Java_java_lang_VMClassLoader_resolveClass           },
-       { "loadClass",              "(Ljava/lang/String;Z)Ljava/lang/Class;",                                                           (void *) (ptrint) &Java_java_lang_VMClassLoader_loadClass              },
-       { "nativeGetResources",     "(Ljava/lang/String;)Ljava/util/Vector;",                                                           (void *) (ptrint) &Java_java_lang_VMClassLoader_nativeGetResources     },
-       { "defaultAssertionStatus", "()Z",                                                                                              (void *) (ptrint) &Java_java_lang_VMClassLoader_defaultAssertionStatus },
-       { "findLoadedClass",        "(Ljava/lang/ClassLoader;Ljava/lang/String;)Ljava/lang/Class;",                                     (void *) (ptrint) &Java_java_lang_VMClassLoader_findLoadedClass        },
+       { "defineClass",                "(Ljava/lang/ClassLoader;Ljava/lang/String;[BIILjava/security/ProtectionDomain;)Ljava/lang/Class;", (void *) (uintptr_t) &Java_java_lang_VMClassLoader_defineClass                },
+       { "getPrimitiveClass",          "(C)Ljava/lang/Class;",                                                                             (void *) (uintptr_t) &Java_java_lang_VMClassLoader_getPrimitiveClass          },
+       { "resolveClass",               "(Ljava/lang/Class;)V",                                                                             (void *) (uintptr_t) &Java_java_lang_VMClassLoader_resolveClass               },
+       { "loadClass",                  "(Ljava/lang/String;Z)Ljava/lang/Class;",                                                           (void *) (uintptr_t) &Java_java_lang_VMClassLoader_loadClass                  },
+       { "nativeGetResources",         "(Ljava/lang/String;)Ljava/util/Vector;",                                                           (void *) (uintptr_t) &Java_java_lang_VMClassLoader_nativeGetResources         },
+       { "defaultAssertionStatus",     "()Z",                                                                                              (void *) (uintptr_t) &Java_java_lang_VMClassLoader_defaultAssertionStatus     },
+       { "defaultUserAssertionStatus", "()Z",                                                                                              (void *) (uintptr_t) &Java_java_lang_VMClassLoader_defaultUserAssertionStatus },
+       { "packageAssertionStatus0",    "(Ljava/lang/Boolean;Ljava/lang/Boolean;)Ljava/util/Map;",                                          (void *) (uintptr_t) &Java_java_lang_VMClassLoader_packageAssertionStatus0    },
+       { "classAssertionStatus0",      "(Ljava/lang/Boolean;Ljava/lang/Boolean;)Ljava/util/Map;",                                          (void *) (uintptr_t) &Java_java_lang_VMClassLoader_classAssertionStatus0      },
+       { "findLoadedClass",            "(Ljava/lang/ClassLoader;Ljava/lang/String;)Ljava/lang/Class;",                                     (void *) (uintptr_t) &Java_java_lang_VMClassLoader_findLoadedClass            },
 };
 
 
@@ -106,9 +111,81 @@ void _Jv_java_lang_VMClassLoader_init(void)
  * Method:    defineClass
  * Signature: (Ljava/lang/ClassLoader;Ljava/lang/String;[BIILjava/security/ProtectionDomain;)Ljava/lang/Class;
  */
-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)
+JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClassLoader_defineClass(JNIEnv *env, jclass clazz, java_lang_ClassLoader *cl, java_lang_String *name, java_handle_bytearray_t *data, int32_t offset, int32_t len, java_security_ProtectionDomain *pd)
 {
-       return _Jv_java_lang_ClassLoader_defineClass(cl, name, data, offset, len, pd);
+       utf             *utfname;
+       classinfo       *c;
+       classloader_t   *loader;
+       java_lang_Class *o;
+
+#if defined(ENABLE_JVMTI)
+       jint new_class_data_len = 0;
+       unsigned char* new_class_data = NULL;
+#endif
+
+       /* check if data was passed */
+
+       if (data == NULL) {
+               exceptions_throw_nullpointerexception();
+               return NULL;
+       }
+
+       /* check the indexes passed */
+
+       if ((offset < 0) || (len < 0) || ((offset + len) > LLNI_array_size(data))) {
+               exceptions_throw_arrayindexoutofboundsexception();
+               return NULL;
+       }
+
+       /* add classloader to classloader hashtable */
+
+       loader = loader_hashtable_classloader_add((java_handle_t *) cl);
+
+       if (name != NULL) {
+               /* convert '.' to '/' in java string */
+
+               utfname = javastring_toutf((java_handle_t *) name, true);
+       } 
+       else {
+               utfname = NULL;
+       }
+
+#if defined(ENABLE_JVMTI)
+       /* XXX again this will not work because of the indirection cell for classloaders */
+       assert(0);
+       /* fire Class File Load Hook JVMTI event */
+
+       if (jvmti)
+               jvmti_ClassFileLoadHook(utfname, len, (unsigned char *) data->data, 
+                                                               loader, (java_handle_t *) pd, 
+                                                               &new_class_data_len, &new_class_data);
+#endif
+
+       /* define the class */
+
+#if defined(ENABLE_JVMTI)
+       /* check if the JVMTI wants to modify the class */
+
+       if (new_class_data == NULL)
+               c = class_define(utfname, loader, new_class_data_len, new_class_data, pd); 
+       else
+#endif
+               c = class_define(utfname, loader, len, (uint8_t *) &LLNI_array_direct(data, offset), (java_handle_t *) pd);
+
+       if (c == NULL)
+               return NULL;
+
+       /* for convenience */
+
+       o = LLNI_classinfo_wrap(c);
+
+#if defined(WITH_CLASSPATH_GNU)
+       /* set ProtectionDomain */
+
+       LLNI_field_set_ref(o, pd, pd);
+#endif
+
+       return o;
 }
 
 
@@ -117,49 +194,18 @@ JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClassLoader_defineClass(JNIE
  * Method:    getPrimitiveClass
  * Signature: (C)Ljava/lang/Class;
  */
-JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClassLoader_getPrimitiveClass(JNIEnv *env, jclass clazz, s4 type)
+JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClassLoader_getPrimitiveClass(JNIEnv *env, jclass clazz, int32_t type)
 {
        classinfo *c;
-       s4         index;
-
-       /* get primitive class */
-
-       switch (type) {
-       case 'I':
-               index = PRIMITIVETYPE_INT;
-               break;
-       case 'J':
-               index = PRIMITIVETYPE_LONG;
-               break;
-       case 'F':
-               index = PRIMITIVETYPE_FLOAT;
-               break;
-       case 'D':
-               index = PRIMITIVETYPE_DOUBLE;
-               break;
-       case 'B':
-               index = PRIMITIVETYPE_BYTE;
-               break;
-       case 'C':
-               index = PRIMITIVETYPE_CHAR;
-               break;
-       case 'S':
-               index = PRIMITIVETYPE_SHORT;
-               break;
-       case 'Z':
-               index = PRIMITIVETYPE_BOOLEAN;
-               break;
-       case 'V':
-               index = PRIMITIVETYPE_VOID;
-               break;
-       default:
-               exceptions_throw_noclassdeffounderror(utf_null);
-               c = NULL;
-       }
 
-       c = primitivetype_table[index].class_primitive;
+       c = primitive_class_get_by_char(type);
+
+       if (c == NULL) {
+               exceptions_throw_classnotfoundexception(utf_null);
+               return NULL;
+       }
 
-       return (java_lang_Class *) c;
+       return LLNI_classinfo_wrap(c);
 }
 
 
@@ -172,7 +218,7 @@ JNIEXPORT void JNICALL Java_java_lang_VMClassLoader_resolveClass(JNIEnv *env, jc
 {
        classinfo *ci;
 
-       ci = (classinfo *) c;
+       ci = LLNI_classinfo_unwrap(c);
 
        if (!ci) {
                exceptions_throw_nullpointerexception();
@@ -193,11 +239,10 @@ JNIEXPORT void JNICALL Java_java_lang_VMClassLoader_resolveClass(JNIEnv *env, jc
  * 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, s4 resolve)
+JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClassLoader_loadClass(JNIEnv *env, jclass clazz, java_lang_String *name, int32_t resolve)
 {
-       classinfo         *c;
-       utf               *u;
-       java_objectheader *xptr;
+       classinfo *c;
+       utf       *u;
 
        if (name == NULL) {
                exceptions_throw_nullpointerexception();
@@ -206,40 +251,22 @@ JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClassLoader_loadClass(JNIEnv
 
        /* create utf string in which '.' is replaced by '/' */
 
-       u = javastring_toutf((java_objectheader *) name, true);
+       u = javastring_toutf((java_handle_t *) name, true);
 
        /* load class */
 
        c = load_class_bootstrap(u);
 
        if (c == NULL)
-               goto exception;
+               return NULL;
 
        /* resolve class -- if requested */
 
 /*     if (resolve) */
                if (!link_class(c))
-                       goto exception;
-
-       return (java_lang_Class *) c;
-
- exception:
-       xptr = exceptions_get_exception();
+                       return NULL;
 
-       c = xptr->vftbl->class;
-       
-       /* if the exception is a NoClassDefFoundError, we replace it with a
-          ClassNotFoundException, otherwise return the exception */
-
-       if (c == class_java_lang_NoClassDefFoundError) {
-               /* clear exceptionptr, because builtin_new checks for 
-                  ExceptionInInitializerError */
-               exceptions_clear_exception();
-
-               exceptions_throw_classnotfoundexception(u);
-       }
-
-       return NULL;
+       return LLNI_classinfo_wrap(c);
 }
 
 
@@ -250,24 +277,24 @@ JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClassLoader_loadClass(JNIEnv
  */
 JNIEXPORT java_util_Vector* JNICALL Java_java_lang_VMClassLoader_nativeGetResources(JNIEnv *env, jclass clazz, java_lang_String *name)
 {
-       java_objectheader    *o;         /* vector being created     */
+       java_handle_t        *o;         /* vector being created     */
        methodinfo           *m;         /* "add" method of vector   */
-       java_objectheader    *path;      /* path to be added         */
+       java_handle_t        *path;      /* path to be added         */
        list_classpath_entry *lce;       /* classpath entry          */
        utf                  *utfname;   /* utf to look for          */
        char                 *buffer;    /* char buffer              */
        char                 *namestart; /* start of name to use     */
        char                 *tmppath;   /* temporary buffer         */
-       s4                    namelen;   /* length of name to use    */
-       s4                    searchlen; /* length of name to search */
-       s4                    bufsize;   /* size of buffer allocated */
-       s4                    pathlen;   /* name of path to assemble */
+       int32_t               namelen;   /* length of name to use    */
+       int32_t               searchlen; /* length of name to search */
+       int32_t               bufsize;   /* size of buffer allocated */
+       int32_t               pathlen;   /* name of path to assemble */
        struct stat           buf;       /* buffer for stat          */
        jboolean              ret;       /* return value of "add"    */
 
        /* get the resource name as utf string */
 
-       utfname = javastring_toutf((java_objectheader *) name, false);
+       utfname = javastring_toutf((java_handle_t *) name, false);
 
        if (utfname == NULL)
                return NULL;
@@ -392,9 +419,167 @@ return_NULL:
  * Method:    defaultAssertionStatus
  * Signature: ()Z
  */
-JNIEXPORT s4 JNICALL Java_java_lang_VMClassLoader_defaultAssertionStatus(JNIEnv *env, jclass clazz)
+JNIEXPORT int32_t JNICALL Java_java_lang_VMClassLoader_defaultAssertionStatus(JNIEnv *env, jclass clazz)
+{
+#if defined(ENABLE_ASSERTION)
+       return assertion_system_enabled;
+#else
+       return false;
+#endif
+}
+
+/*
+ * Class:     java/lang/VMClassLoader
+ * Method:    userAssertionStatus
+ * Signature: ()Z
+ */
+JNIEXPORT int32_t JNICALL Java_java_lang_VMClassLoader_defaultUserAssertionStatus(JNIEnv *env, jclass clazz)
+{
+#if defined(ENABLE_ASSERTION)
+       return assertion_user_enabled;
+#else
+       return false;
+#endif
+}
+
+/*
+ * Class:     java/lang/VMClassLoader
+ * Method:    packageAssertionStatus
+ * Signature: ()Ljava_util_Map;
+ */
+JNIEXPORT java_util_Map* JNICALL Java_java_lang_VMClassLoader_packageAssertionStatus0(JNIEnv *env, jclass clazz, java_lang_Boolean *jtrue, java_lang_Boolean *jfalse)
 {
-       return _Jv_jvm->Java_java_lang_VMClassLoader_defaultAssertionStatus;
+       java_handle_t     *hm;
+#if defined(ENABLE_ASSERTION)
+       java_handle_t     *js;
+       methodinfo        *m;
+       assertion_name_t  *item;
+#endif
+
+       /* new HashMap() */
+
+       hm = native_new_and_init(class_java_util_HashMap);
+       if (hm == NULL) {
+               return NULL;
+       }
+
+#if defined(ENABLE_ASSERTION)
+       /* if nothing todo, return now */
+
+       if (assertion_package_count == 0) {
+               return (java_util_Map *) hm;
+       }
+
+       /* get HashMap.put method */
+
+       m = class_resolveclassmethod(class_java_util_HashMap,
+                                 utf_put,
+                                 utf_new_char("(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"),
+                                 NULL,
+                                 true);
+
+       if (m == NULL) {
+               return NULL;
+       }
+
+       item = (assertion_name_t *)list_first(list_assertion_names);
+
+       while (item != NULL) {
+               if (item->package == false) {
+                       item = (assertion_name_t *)list_next(list_assertion_names, item);
+                       continue;
+               }
+               
+               if (strcmp(item->name, "") == 0) {
+                       /* unnamed package wanted */
+                       js = NULL;
+               }
+               else {
+                       js = javastring_new_from_ascii(item->name);
+                       if (js == NULL) {
+                               return NULL;
+                       }
+               }
+
+               if (item->enabled == true) {
+                       vm_call_method(m, hm, js, jtrue);
+               }
+               else {
+                       vm_call_method(m, hm, js, jfalse);
+               }
+
+               item = (assertion_name_t *)list_next(list_assertion_names, item);
+       }
+#endif
+
+       return (java_util_Map *) hm;
+}
+
+/*
+ * Class:     java/lang/VMClassLoader
+ * Method:    classAssertionStatus
+ * Signature: ()Ljava_util_Map;
+ */
+JNIEXPORT java_util_Map* JNICALL Java_java_lang_VMClassLoader_classAssertionStatus0(JNIEnv *env, jclass clazz, java_lang_Boolean *jtrue, java_lang_Boolean *jfalse)
+{
+       java_handle_t     *hm;
+#if defined(ENABLE_ASSERTION)
+       java_handle_t     *js;
+       methodinfo        *m;
+       assertion_name_t  *item;
+#endif
+
+       /* new HashMap() */
+
+       hm = native_new_and_init(class_java_util_HashMap);
+       if (hm == NULL) {
+               return NULL;
+       }
+
+#if defined(ENABLE_ASSERTION)
+       /* if nothing todo, return now */
+
+       if (assertion_class_count == 0) {
+               return (java_util_Map *) hm;
+       }
+
+       /* get HashMap.put method */
+
+       m = class_resolveclassmethod(class_java_util_HashMap,
+                                 utf_put,
+                                 utf_new_char("(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"),
+                                 NULL,
+                                 true);
+
+       if (m == NULL) {
+               return NULL;
+       }
+
+       item = (assertion_name_t *)list_first(list_assertion_names);
+
+       while (item != NULL) {
+               if (item->package == true) {
+                       item = (assertion_name_t *)list_next(list_assertion_names, item);
+                       continue;
+               }
+
+               js = javastring_new_from_ascii(item->name);
+               if (js == NULL) {
+                       return NULL;
+               }
+
+               if (item->enabled == true) {
+                       vm_call_method(m, hm, js, jtrue);
+               }
+               else {
+                       vm_call_method(m, hm, js, jfalse);
+               }
+
+               item = (assertion_name_t *)list_next(list_assertion_names, item);
+       }
+#endif
+
+       return (java_util_Map *) hm;
 }
 
 
@@ -405,15 +590,17 @@ JNIEXPORT s4 JNICALL Java_java_lang_VMClassLoader_defaultAssertionStatus(JNIEnv
  */
 JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClassLoader_findLoadedClass(JNIEnv *env, jclass clazz, java_lang_ClassLoader *loader, java_lang_String *name)
 {
-       classloader *cl;
-       classinfo   *c;
-       utf         *u;
+       classloader_t *cl;
+       classinfo     *c;
+       utf           *u;
+
+       /* XXX is it correct to add the classloader to the hashtable here? */
 
-       cl = (classloader *) loader;
+       cl = loader_hashtable_classloader_add((java_handle_t *) loader);
 
        /* replace `.' by `/', this is required by the classcache */
 
-       u = javastring_toutf((java_objectheader *) name, true);
+       u = javastring_toutf((java_handle_t *) name, true);
 
        /* lookup for defining classloader */
 
@@ -424,7 +611,7 @@ JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClassLoader_findLoadedClass(
        if (c == NULL)
                c = classcache_lookup(cl, u);
 
-       return (java_lang_Class *) c;
+       return LLNI_classinfo_wrap(c);
 }