* Merged with default branch at rev 16f3633aaa5a.
[cacao.git] / src / native / vm / java_lang_ClassLoader.c
index ba8ce0e25a0ef920b217faf0dcd03ea4cbaf8bf0..5eaed828ca99a386a0c5e6547d8d2283c8a67524 100644 (file)
@@ -22,8 +22,6 @@
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   $Id: java_lang_VMClass.c 6131 2006-12-06 22:15:57Z twisti $
-
 */
 
 
 
 #include "vm/global.h"                          /* required by native headers */
 
+#include "native/jni.h"
+#include "native/llni.h"
+
+/* keep this order of the native includes */
+
 #include "native/include/java_lang_Object.h"
 
 #if defined(ENABLE_JAVASE)
-# include "native/include/java_lang_String.h"/* required by java_lang_Class.h */
+# include "native/include/java_lang_String.h"            /* required by j.l.C */
+
+# if defined(WITH_CLASSPATH_SUN)
+#  include "native/include/java_nio_ByteBuffer.h"       /* required by j.l.CL */
+# endif
+
+# include "native/include/java_lang_ClassLoader.h"       /* required by j.l.C */
 # include "native/include/java_lang_Class.h"
-# include "native/include/java_lang_ClassLoader.h"
 # include "native/include/java_security_ProtectionDomain.h"
 #endif
 
 #include "vm/exceptions.h"
+#include "vm/stringlocal.h"
 
 #include "vmcore/class.h"
 #include "vmcore/classcache.h"
 #include "vmcore/options.h"
 
+#if defined(ENABLE_STATISTICS)
+# include "vmcore/statistics.h"
+#endif
+
 
 /*
  * Class:     java/lang/ClassLoader
  * Method:    defineClass
  * Signature: (Ljava/lang/ClassLoader;Ljava/lang/String;[BIILjava/security/ProtectionDomain;)Ljava/lang/Class;
  */
-java_lang_Class *_Jv_java_lang_ClassLoader_defineClass(java_lang_ClassLoader *cl, java_lang_String *name, java_bytearray *data, s4 offset, s4 len, java_security_ProtectionDomain *pd)
+java_lang_Class *_Jv_java_lang_ClassLoader_defineClass(java_lang_ClassLoader *cl, java_lang_String *name, java_handle_bytearray_t *data, s4 offset, s4 len, java_security_ProtectionDomain *pd)
 {
-       java_objectheader *loader;
-       utf               *utfname;
-       classinfo         *c;
-       classinfo         *r;
-       classbuffer       *cb;
-       java_lang_Class   *co;
+       utf             *utfname;
+       classinfo       *c;
+       classloader     *loader;
+       java_lang_Class *o;
+
 #if defined(ENABLE_JVMTI)
        jint new_class_data_len = 0;
        unsigned char* new_class_data = NULL;
 #endif
 
-       loader = (java_objectheader *) cl;
-
        /* check if data was passed */
 
        if (data == NULL) {
@@ -83,114 +93,61 @@ java_lang_Class *_Jv_java_lang_ClassLoader_defineClass(java_lang_ClassLoader *cl
 
        /* check the indexes passed */
 
-       if ((offset < 0) || (len < 0) || ((offset + len) > data->header.size)) {
+       if ((offset < 0) || (len < 0) || ((offset + len) > LLNI_array_size(data))) {
                exceptions_throw_arrayindexoutofboundsexception();
                return NULL;
        }
 
-       if (name != NULL) {
-               /* convert '.' to '/' in java string */
+       /* add classloader to classloader hashtable */
 
-               utfname = javastring_toutf(name, true);
-               
-               /* check if this class has already been defined */
+       assert(cl);
+       loader = loader_hashtable_classloader_add((java_handle_t *) cl);
 
-               c = classcache_lookup_defined_or_initiated(loader, utfname);
+       if (name != NULL) {
+               /* convert '.' to '/' in java string */
 
-               if (c != NULL) {
-                       exceptions_throw_linkageerror("duplicate class definition: ", c);
-                       return NULL;
-               }
+               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_objectheader *) pd, 
+                                                               loader, (java_handle_t *) 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
-
-       /* build a classbuffer with the given data */
+       /* define the class */
 
-       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;
-       }
-#endif
-       cb->pos   = cb->data;
-
-       /* preset the defining classloader */
-
-       c->classloader = loader;
-
-       /* load the class from this buffer */
-
-       r = load_class_from_classbuffer(cb);
-
-       /* free memory */
-
-       FREE(cb, classbuffer);
 
-#if defined(ENABLE_STATISTICS)
-       /* measure time */
-
-       if (opt_getloadingtime)
-               loadingtime_stop();
+       if (new_class_data == NULL)
+               c = class_define(utfname, loader, new_class_data_len, new_class_data); 
+       else
 #endif
+               c = class_define(utfname, loader, len, (const uint8_t *) &LLNI_array_direct(data, offset));
 
-       if (r == NULL) {
-               /* 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. */
-
-               class_free(c);
-
+       if (c == NULL)
                return NULL;
-       }
 
-       /* set ProtectionDomain */
-
-       co = (java_lang_Class *) c;
+       /* for convenience */
 
-       co->pd = pd;
+       o = LLNI_classinfo_wrap(c);
 
-       /* 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.      */
+#if defined(WITH_CLASSPATH_GNU)
+       /* set ProtectionDomain */
 
-       c = classcache_store(loader, c, true);
+       LLNI_field_set_ref(o, pd, pd);
+#endif
 
-       return (java_lang_Class *) c;
+       return o;
 }