Merged revisions 8299-8320 via svnmerge from
[cacao.git] / src / native / vm / gnu / java_lang_VMClassLoader.c
index 282414ac3d56498bfadcef54bf9c6fd645c2e5ea..1ef3d9a0df219f96f7078b86433a25fe6492e05e 100644 (file)
@@ -1,6 +1,6 @@
-/* src/native/vm/VMClassLoader.c - java/lang/VMClassLoader
+/* src/native/vm/gnu/VMClassLoader.c
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Roman Obermaiser
-
-   Changes: Joseph Wenninger
-            Christian Thalinger
-            Edwin Steiner
-
-   $Id: java_lang_VMClassLoader.c 6213 2006-12-18 17:36:06Z twisti $
+   $Id: java_lang_VMClassLoader.c 8321 2007-08-16 11:37:25Z michi $
 
 */
 
 
 #include "config.h"
 
+#include <assert.h>
 #include <sys/stat.h>
 
 #include "vm/types.h"
 
 #include "mm/memory.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_security_ProtectionDomain.h"  /* required by... */
 #include "native/include/java_lang_ClassLoader.h"
-#include "native/include/java_security_ProtectionDomain.h"
 #include "native/include/java_util_Vector.h"
+
+#include "native/include/java_lang_VMClassLoader.h"
+
+#include "native/vm/java_lang_ClassLoader.h"
+
 #include "toolbox/logging.h"
+
 #include "vm/builtin.h"
-#include "vm/class.h"
-#include "vm/classcache.h"
 #include "vm/exceptions.h"
 #include "vm/initialize.h"
-#include "vm/linker.h"
-#include "vm/loader.h"
-#include "vm/options.h"
-#include "vm/statistics.h"
+#include "vm/primitive.h"
 #include "vm/stringlocal.h"
-#include "vm/suck.h"
 #include "vm/vm.h"
-#include "vm/zip.h"
-#include "vm/jit/asmpart.h"
-
-#if defined(ENABLE_JVMTI)
-#include "native/jvmti/cacaodbg.h"
-#endif
-
-
-/*
- * Class:     java/lang/VMClassLoader
- * 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)
-{
-       classinfo   *c;
-       classinfo   *r;
-       classbuffer *cb;
-       utf         *utfname;
-#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) > data->header.size)) {
-               exceptions_throw_arrayindexoutofboundsexception();
-               return NULL;
-       }
-
-       if (name) {
-               /* convert '.' to '/' in java string */
-
-               utfname = javastring_toutf(name, true);
-               
-               /* check if this class has already been defined */
-
-               c = classcache_lookup_defined_or_initiated((java_objectheader *) cl, utfname);
-               if (c) {
-                       *exceptionptr =
-                               exceptions_new_linkageerror("duplicate class definition: ",c);
-                       return NULL;
-               }
-       } 
-       else {
-               utfname = NULL;
-       }
-
-
-#if defined(ENABLE_JVMTI)
-       /* fire Class File Load Hook JVMTI event */
-       if (jvmti) jvmti_ClassFileLoadHook(utfname, len, (unsigned char*)data->data, 
-                                                       (java_objectheader *)cl, (java_objectheader *)pd, 
-                                                       &new_class_data_len, &new_class_data);
-#endif
-
-
-       /* create a new classinfo struct */
 
-       c = class_create_classinfo(utfname);
-
-#if defined(ENABLE_STATISTICS)
-       /* measure time */
-
-       if (opt_getloadingtime)
-               loadingtime_start();
-#endif
+#include "vm/jit/asmpart.h"
 
-       /* build a classbuffer with the given data */
+#include "vmcore/class.h"
+#include "vmcore/classcache.h"
+#include "vmcore/linker.h"
+#include "vmcore/loader.h"
+#include "vmcore/options.h"
+#include "vmcore/statistics.h"
+#include "vmcore/suck.h"
+#include "vmcore/zip.h"
 
-       cb = NEW(classbuffer);
-       cb->class = c;
-#if defined(ENABLE_JVMTI)
-       /* check if the JVMTI wants to modify the class */
-       if (new_class_data == NULL) {
-#endif
-       cb->size  = len;
-       cb->data  = (u1 *) &data->data[offset];
 #if defined(ENABLE_JVMTI)
-       } else {
-               cb->size  = new_class_data_len;
-               cb->data  = (u1 *) new_class_data;
-       }
+#include "native/jvmti/cacaodbg.h"
 #endif
-       cb->pos   = cb->data;
-
-       /* preset the defining classloader */
-
-       c->classloader = (java_objectheader *) cl;
-
-       /* load the class from this buffer */
 
-       r = load_class_from_classbuffer(cb);
 
-       /* free memory */
+/* native methods implemented by this file ************************************/
 
-       FREE(cb, classbuffer);
+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        },
+};
 
-#if defined(ENABLE_STATISTICS)
-       /* measure time */
 
-       if (opt_getloadingtime)
-               loadingtime_stop();
-#endif
-
-       if (!r) {
-               /* If return value is NULL, we had a problem and the class is not   */
-               /* loaded. */
-               /* now free the allocated memory, otherwise we could run into a DOS */
+/* _Jv_java_lang_VMClassLoader_init ********************************************
 
-               class_free(c);
+   Register native functions.
 
-               return NULL;
-       }
+*******************************************************************************/
 
-       /* set ProtectionDomain */
+void _Jv_java_lang_VMClassLoader_init(void)
+{
+       utf *u;
 
-       c->object.pd = pd;
+       u = utf_new_char("java/lang/VMClassLoader");
 
-       /* Store the newly defined class in the class cache. This call also       */
-       /* checks whether a class of the same name has already been defined by    */
-       /* the same defining loader, and if so, replaces the newly created class  */
-       /* by the one defined earlier.                                            */
-       /* Important: The classinfo given to classcache_store must be             */
-       /*            fully prepared because another thread may return this       */
-       /*            pointer after the lookup at to top of this function         */
-       /*            directly after the class cache lock has been released.      */
+       native_method_register(u, methods, NATIVE_METHODS_COUNT);
+}
 
-       c = classcache_store((java_objectheader *)cl,c,true);
 
-       return (java_lang_Class *) c;
+/*
+ * Class:     java/lang/VMClassLoader
+ * 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_handle_bytearray_t *data, s4 offset, s4 len, java_security_ProtectionDomain *pd)
+{
+       return _Jv_java_lang_ClassLoader_defineClass(cl, name, data, offset, len, pd);
 }
 
 
@@ -213,39 +122,11 @@ JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClassLoader_getPrimitiveClas
 {
        classinfo *c;
 
-       /* get primitive class */
-
-       switch (type) {
-       case 'I':
-               c = primitivetype_table[PRIMITIVETYPE_INT].class_primitive;
-               break;
-       case 'J':
-               c = primitivetype_table[PRIMITIVETYPE_LONG].class_primitive;
-               break;
-       case 'F':
-               c = primitivetype_table[PRIMITIVETYPE_FLOAT].class_primitive;
-               break;
-       case 'D':
-               c = primitivetype_table[PRIMITIVETYPE_DOUBLE].class_primitive;
-               break;
-       case 'B':
-               c = primitivetype_table[PRIMITIVETYPE_BYTE].class_primitive;
-               break;
-       case 'C':
-               c = primitivetype_table[PRIMITIVETYPE_CHAR].class_primitive;
-               break;
-       case 'S':
-               c = primitivetype_table[PRIMITIVETYPE_SHORT].class_primitive;
-               break;
-       case 'Z':
-               c = primitivetype_table[PRIMITIVETYPE_BOOLEAN].class_primitive;
-               break;
-       case 'V':
-               c = primitivetype_table[PRIMITIVETYPE_VOID].class_primitive;
-               break;
-       default:
-               *exceptionptr = new_exception(string_java_lang_ClassNotFoundException);
-               c = NULL;
+       c = primitive_class_get_by_char(type);
+
+       if (c == NULL) {
+               exceptions_throw_classnotfoundexception(utf_null);
+               return NULL;
        }
 
        return (java_lang_Class *) c;
@@ -282,10 +163,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, jboolean resolve)
+JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClassLoader_loadClass(JNIEnv *env, jclass clazz, java_lang_String *name, s4 resolve)
 {
        classinfo *c;
-       utf *u;
+       utf       *u;
 
        if (name == NULL) {
                exceptions_throw_nullpointerexception();
@@ -294,37 +175,22 @@ JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClassLoader_loadClass(JNIEnv
 
        /* create utf string in which '.' is replaced by '/' */
 
-       u = javastring_toutf(name, true);
+       u = javastring_toutf((java_handle_t *) name, true);
 
        /* load class */
 
-       if (!(c = load_class_bootstrap(u)))
-               goto exception;
+       c = load_class_bootstrap(u);
+
+       if (c == NULL)
+               return NULL;
 
        /* resolve class -- if requested */
 
 /*     if (resolve) */
                if (!link_class(c))
-                       goto exception;
+                       return NULL;
 
        return (java_lang_Class *) c;
-
- exception:
-       c = (*exceptionptr)->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 */
-               *exceptionptr = NULL;
-
-               *exceptionptr =
-                       new_exception_javastring(string_java_lang_ClassNotFoundException, name);
-       }
-
-       return NULL;
 }
 
 
@@ -335,9 +201,9 @@ 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)
 {
-       jobject               o;         /* vector being created     */
+       java_handle_t        *o;         /* vector being created     */
        methodinfo           *m;         /* "add" method of vector   */
-       java_lang_String     *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              */
@@ -352,16 +218,17 @@ JNIEXPORT java_util_Vector* JNICALL Java_java_lang_VMClassLoader_nativeGetResour
 
        /* get the resource name as utf string */
 
-       utfname = javastring_toutf(name, false);
-       if (!utfname)
+       utfname = javastring_toutf((java_handle_t *) name, false);
+
+       if (utfname == NULL)
                return NULL;
 
        /* copy it to a char buffer */
 
-       namelen = utf_bytes(utfname);
+       namelen   = utf_bytes(utfname);
        searchlen = namelen;
-       bufsize = namelen + strlen("0");
-       buffer = MNEW(char, bufsize);
+       bufsize   = namelen + strlen("0");
+       buffer    = MNEW(char, bufsize);
 
        utf_copy(buffer, utfname);
        namestart = buffer;
@@ -392,7 +259,7 @@ JNIEXPORT java_util_Vector* JNICALL Java_java_lang_VMClassLoader_nativeGetResour
 
        o = native_new_and_init(class_java_util_Vector);
 
-       if (!o)
+       if (o == NULL)
                goto return_NULL;
 
        /* get Vector.add() method */
@@ -403,7 +270,7 @@ JNIEXPORT java_util_Vector* JNICALL Java_java_lang_VMClassLoader_nativeGetResour
                                                                 NULL,
                                                                 true);
 
-       if (!m)
+       if (m == NULL)
                goto return_NULL;
 
        /* iterate over all classpath entries */
@@ -449,10 +316,10 @@ JNIEXPORT java_util_Vector* JNICALL Java_java_lang_VMClassLoader_nativeGetResour
 
                /* if a resource was found, add it to the vector */
 
-               if (path) {
+               if (path != NULL) {
                        ret = vm_call_method_int(m, o, path);
 
-                       if (*exceptionptr)
+                       if (exceptions_get_exception() != NULL)
                                goto return_NULL;
 
                        if (ret == 0) 
@@ -487,23 +354,26 @@ JNIEXPORT s4 JNICALL Java_java_lang_VMClassLoader_defaultAssertionStatus(JNIEnv
  * Method:    findLoadedClass
  * Signature: (Ljava/lang/ClassLoader;Ljava/lang/String;)Ljava/lang/Class;
  */
-JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClassLoader_findLoadedClass(JNIEnv *env, jclass clazz, java_lang_ClassLoader *cl, java_lang_String *name)
+JNIEXPORT java_lang_Class* JNICALL Java_java_lang_VMClassLoader_findLoadedClass(JNIEnv *env, jclass clazz, java_lang_ClassLoader *loader, java_lang_String *name)
 {
-       classinfo *c;
-       utf       *u;
+       classloader *cl;
+       classinfo   *c;
+       utf         *u;
+
+       cl = loader_hashtable_classloader_add((java_objectheader *) loader);
 
        /* replace `.' by `/', this is required by the classcache */
 
-       u = javastring_toutf(name, true);
+       u = javastring_toutf((java_handle_t *) name, true);
 
        /* lookup for defining classloader */
 
-       c = classcache_lookup_defined((classloader *) cl, u);
+       c = classcache_lookup_defined(cl, u);
 
        /* if not found, lookup for initiating classloader */
 
        if (c == NULL)
-               c = classcache_lookup((classloader *) cl, u);
+               c = classcache_lookup(cl, u);
 
        return (java_lang_Class *) c;
 }