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) {
/* 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;
}