-/* 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 7723 2007-04-16 18:03:08Z 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/vm/java_lang_ClassLoader.h"
+#include "native/include/java_lang_VMClassLoader.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 *) (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 },
+};
+
+
+/* _Jv_java_lang_VMClassLoader_init ********************************************
+
+ Register native functions.
+
+*******************************************************************************/
+
+void _Jv_java_lang_VMClassLoader_init(void)
+{
+ utf *u;
+
+ u = utf_new_char("java/lang/VMClassLoader");
+
+ native_method_register(u, methods, NATIVE_METHODS_COUNT);
+}
+
/*
* 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)
+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;
- 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);
- return (java_lang_Class *) c;
+ if (c == NULL) {
+ exceptions_throw_classnotfoundexception(utf_null);
+ return NULL;
+ }
+
+ return LLNI_classinfo_wrap(c);
}
{
classinfo *ci;
- ci = (classinfo *) c;
+ ci = LLNI_classinfo_unwrap(c);
if (!ci) {
exceptions_throw_nullpointerexception();
* 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, int32_t resolve)
{
- classinfo *c;
- utf *u;
- java_objectheader *xptr;
+ classinfo *c;
+ utf *u;
if (name == NULL) {
exceptions_throw_nullpointerexception();
/* 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();
-
- 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 NULL;
+ return LLNI_classinfo_wrap(c);
}
*/
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;
* 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)
{
- return _Jv_jvm->Java_java_lang_VMClassLoader_defaultAssertionStatus;
+#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)
+{
+ 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;
+
+ /* 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 */
if (c == NULL)
c = classcache_lookup(cl, u);
- return (java_lang_Class *) c;
+ return LLNI_classinfo_wrap(c);
}