-/* 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 8343 2007-08-17 21:39:32Z 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/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 "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 },
};
* 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)
+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);
+
+ /* set ProtectionDomain */
+
+ LLNI_field_set_ref(o, pd, pd);
+
+ return o;
}
* 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;
* 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;
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" */
* 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)
+{
+ 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)
{
- 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_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;
}
*/
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;
- cl = loader_hashtable_classloader_find((java_handle_t *) loader);
+ /* XXX is it correct to add the classloader to the hashtable here? */
- if (cl == NULL)
- vm_abort("unable to find classloader");
+ cl = loader_hashtable_classloader_add((java_handle_t *) loader);
/* replace `.' by `/', this is required by the classcache */