Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser,
M. Probst, S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck,
- P. Tomsich, J. Wenninger
+ P. Tomsich, J. Wenninger, M. Platter
This file is part of CACAO.
Authors: ?
- Changes: Joseph Wenninger
+ Changes: Joseph Wenninger, Martin Platter
- $Id: jni.c 1005 2004-03-30 23:01:45Z twisti $
+ $Id: jni.c 1384 2004-08-02 11:41:26Z motse $
*/
#include <string.h>
+#include "exceptions.h"
+#include "main.h"
#include "jni.h"
#include "global.h"
#include "loader.h"
#include "tables.h"
#include "native.h"
#include "builtin.h"
+#include "options.h"
+#include "statistics.h"
#include "threads/thread.h"
-#include "toolbox/loging.h"
+#include "toolbox/logging.h"
#include "toolbox/memory.h"
#include "nat/java_lang_Byte.h"
#include "nat/java_lang_Character.h"
jmethodID get_nonvirtual(jclass clazz,jmethodID methodID) {
if (clazz==methodID->class) return methodID;
+/*class_resolvemethod -> classfindmethod? (JOWENN)*/
return class_resolvemethod (clazz, methodID->name, methodID->descriptor);
}
}
if (argcount > 3) {
- *exceptionptr = native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
+ *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
log_text("Too many arguments. CallObjectMethod does not support that");
return 0;
}
if (argcount > 3) {
- *exceptionptr = native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
+ *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
log_text("Too many arguments. CallIntegerMethod does not support that");
return 0;
}
jni_callblock *blk;
jlong ret;
- /*
+/*
log_text("JNI-Call: CallObjectMethodV");
utf_display(methodID->name);
utf_display(methodID->descriptor);
printf("\nParmaeter count: %d\n",argcount);
utf_display(obj->vftbl->class->name);
printf("\n");
- */
+*/
if (methodID == 0) {
*exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
return 0;
if (argcount > 3) {
- *exceptionptr = native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
+ *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
log_text("Too many arguments. CallObjectMethod does not support that");
return 0;
}
blk = MNEW(jni_callblock, 4 /*argcount+2*/);
- fill_callblock(obj, methodID->descriptor, blk, args, 'L');
+ fill_callblock(obj, methodID->descriptor, blk, args, 'J');
/* printf("parameter: obj: %p",blk[0].item); */
ret = asm_calljavafunction2long(methodID,
*/
if (argcount > 3) {
- *exceptionptr = native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
+ *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
log_text("Too many arguments. CallObjectMethod does not support that");
return 0;
}
return JNI_VERSION;
}
+
/****************** loads a class from a buffer of raw class data *****************/
jclass DefineClass(JNIEnv* env, const char *name, jobject loader, const jbyte *buf, jsize len)
{
- jclass clazz;
+ jclass clazz;
+ classbuffer *cb;
+ s8 starttime;
+ s8 stoptime;
+
+#if defined(USE_THREADS)
+#if defined(NATIVE_THREADS)
+ compiler_lock();
+ tables_lock();
+#else
+ intsDisable();
+#endif
+#endif
+
+ /* measure time */
+ if (getloadingtime)
+ starttime = getcputime();
+
+ clazz = class_new(utf_new_char((char *) name));
- /* change suck-mode, so subsequent class_load will read from memory-buffer */
- classload_buffer( (u1*) buf,len);
+ /* build a classbuffer with the given data */
+ cb = NEW(classbuffer);
+ cb->class = clazz;
+ cb->size = len;
+ cb->data = (u1 *) buf;
+ cb->pos = cb->data - 1;
- clazz = loader_load(utf_new_char ((char *) name));
+ class_load_intern(cb);
+
+ /* free memory */
+ FREE(cb, classbuffer);
+
+ /* measure time */
+ if (getloadingtime) {
+ stoptime = getcputime();
+ loadingtime += (stoptime - starttime);
+ }
+
+#if defined(USE_THREADS)
+#if defined(NATIVE_THREADS)
+ tables_unlock();
+ compiler_unlock();
+#else
+ intsRestore();
+#endif
+#endif
+
+ if (*exceptionptr)
+ return NULL;
+
+ /* XXX link the class here? */
+ class_link(clazz);
+
+ if (*exceptionptr)
+ return NULL;
+
+ if (clazz)
+ clazz->classloader = loader;
- /* restore old suck-mode */
- classload_buffer(NULL,0);
- if (clazz) clazz->classloader=loader;
return clazz;
}
{
classinfo *c;
-/* if (strcmp(name,"[B")==0) {
- c = loader_load(utf_new_char("The_Array_Class"));
- }
- else*/
- c = loader_load(utf_new_char_classname((char *) name));
+ c = class_new(utf_new_char_classname((char *) name));
+
+ class_load(c);
+
+ if (*exceptionptr)
+ return NULL;
+
+ class_link(c);
- if (!c)
- *exceptionptr = new_exception(string_java_lang_ClassFormatError);
+ if (*exceptionptr)
+ return NULL;
return c;
}
/* log_text("JNI-Call: NewObject"); */
- if (argcount>3) {
- *exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
+ if (argcount > 3) {
+ *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
log_text("Too many arguments. NewObject does not support that");
return 0;
}
utf_new_char ((char*) sig)
);
- if (!m) *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
-
+ if (!m) *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
+ else if (m->flags & ACC_STATIC) {
+ m=0;
+ *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
+ }
return m;
}
jlong CallLongMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
{
- log_text("JNI-Call: CallLongMethod");
+ jlong ret;
+ va_list vaargs;
+
+ va_start(vaargs,methodID);
+ ret = callLongMethod(obj,get_virtual(obj, methodID),vaargs);
+ va_end(vaargs);
- return 0;
+ return ret;
}
jlong CallLongMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
{
- log_text("JNI-Call: CallLongMethodV");
-
- return 0;
+ return callLongMethod(obj,get_virtual(obj, methodID),args);
}
utf_new_char((char *) sig));
if (!m) *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
+ else if (!(m->flags & ACC_STATIC)) {
+ m=0;
+ *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
+ }
return m;
}
jobject CallStaticObjectMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
{
- log_text("JNI-Call: CallStaticObjectMethod");
+ jobject ret;
+ va_list vaargs;
- return NULL;
+ /* log_text("JNI-Call: CallStaticObjectMethod");*/
+
+ va_start(vaargs, methodID);
+ ret = callObjectMethod(0, methodID, vaargs);
+ va_end(vaargs);
+
+ return ret;
}
jobject CallStaticObjectMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
{
- log_text("JNI-Call: CallStaticObjectMethodV");
-
- return NULL;
+ /* log_text("JNI-Call: CallStaticObjectMethodV"); */
+
+ return callObjectMethod(0,methodID,args);
}
jboolean ret;
va_list vaargs;
- /* log_text("JNI-Call: CallStaticBooleanMethod");*/
-
va_start(vaargs, methodID);
ret = (jboolean) callIntegerMethod(0, methodID, 'Z', vaargs);
va_end(vaargs);
j = builtin_anewarray(len, clazz);
- if (!j)
- *exceptionptr = new_exception(string_java_lang_OutOfMemoryError);
-
return j;
}
j = builtin_newarray_boolean(len);
- if (!j)
- *exceptionptr = new_exception(string_java_lang_OutOfMemoryError);
-
return j;
}
j = builtin_newarray_byte(len);
- if (!j)
- *exceptionptr = new_exception(string_java_lang_OutOfMemoryError);
-
return j;
}
j = builtin_newarray_char(len);
- if (!j)
- *exceptionptr = new_exception(string_java_lang_OutOfMemoryError);
-
return j;
}
j = builtin_newarray_short(len);
- if (!j)
- *exceptionptr = new_exception(string_java_lang_OutOfMemoryError);
-
return j;
}
j = builtin_newarray_int(len);
- if (!j)
- *exceptionptr = new_exception(string_java_lang_OutOfMemoryError);
-
return j;
}
j = builtin_newarray_long(len);
- if (!j)
- *exceptionptr = new_exception(string_java_lang_OutOfMemoryError);
-
return j;
}
j = builtin_newarray_float(len);
- if (!j)
- *exceptionptr = new_exception(string_java_lang_OutOfMemoryError);
-
return j;
}
j = builtin_newarray_double(len);
- if (!j)
- *exceptionptr = new_exception(string_java_lang_OutOfMemoryError);
-
return j;
}
argcount = get_parametercount(methodID);
if (obj && (!builtin_instanceof((java_objectheader *) obj, methodID->class))) {
- (*env)->ThrowNew(env, loader_load(utf_new_char("java/lang/IllegalArgumentException")),
- "Object parameter of wrong type in Java_java_lang_reflect_Method_invokeNative");
+ *exceptionptr = new_exception_message(string_java_lang_IllegalArgumentException,
+ "Object parameter of wrong type in Java_java_lang_reflect_Method_invokeNative");
return 0;
}
if (argcount > 3) {
- *exceptionptr = native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
+ *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
log_text("Too many arguments. invokeNativeHelper does not support that");
return 0;
}
if (((!params) && (argcount != 0)) || (params && (params->header.size != argcount))) {
- *exceptionptr = native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
+ *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
return 0;
}
if (!(methodID->flags & ACC_STATIC) && (!obj)) {
- (*env)->ThrowNew(env, loader_load(utf_new_char("java/lang/NullPointerException")),
- "Static mismatch in Java_java_lang_reflect_Method_invokeNative");
+ *exceptionptr = new_exception_message(string_java_lang_NullPointerException,
+ "Static mismatch in Java_java_lang_reflect_Method_invokeNative");
return 0;
}
argcount + 1,
(argcount + 1) * sizeof(jni_callblock),
blk);
- retVal = builtin_new(loader_load_sysclass(NULL,
- utf_new_char("java/lang/Integer")));
+ retVal = builtin_new(class_new(utf_new_char("java/lang/Integer")));
CallVoidMethod(env,
retVal,
class_resolvemethod(retVal->vftbl->class,
argcount + 1,
(argcount + 1) * sizeof(jni_callblock),
blk);
- retVal = builtin_new(loader_load_sysclass(NULL,
- utf_new_char("java/lang/Byte")));
+ retVal = builtin_new(class_new(utf_new_char("java/lang/Byte")));
CallVoidMethod(env,
retVal,
class_resolvemethod(retVal->vftbl->class,
argcount + 1,
(argcount + 1) * sizeof(jni_callblock),
blk);
- retVal = builtin_new(loader_load_sysclass(NULL,
- utf_new_char("java/lang/Character")));
+ retVal = builtin_new(class_new(utf_new_char("java/lang/Character")));
CallVoidMethod(env,
retVal,
class_resolvemethod(retVal->vftbl->class,
argcount + 1,
(argcount + 1) * sizeof(jni_callblock),
blk);
- retVal = builtin_new(loader_load_sysclass(NULL,
- utf_new_char("java/lang/Short")));
+ retVal = builtin_new(class_new(utf_new_char("java/lang/Short")));
CallVoidMethod(env,
retVal,
class_resolvemethod(retVal->vftbl->class,
argcount + 1,
(argcount + 1) * sizeof(jni_callblock),
blk);
- retVal = builtin_new(loader_load_sysclass(NULL,
- utf_new_char("java/lang/Boolean")));
+ retVal = builtin_new(class_new(utf_new_char("java/lang/Boolean")));
CallVoidMethod(env,
retVal,
class_resolvemethod(retVal->vftbl->class,
argcount + 1,
(argcount + 1) * sizeof(jni_callblock),
blk);
- retVal = builtin_new(loader_load_sysclass(NULL,
- utf_new_char("java/lang/Long")));
+ retVal = builtin_new(class_new(utf_new_char("java/lang/Long")));
CallVoidMethod(env,
retVal,
class_resolvemethod(retVal->vftbl->class,
argcount + 1,
(argcount + 1) * sizeof(jni_callblock),
blk);
- retVal = builtin_new(loader_load_sysclass(NULL,
- utf_new_char("java/lang/Float")));
+ retVal = builtin_new(class_new(utf_new_char("java/lang/Float")));
CallVoidMethod(env,
retVal,
class_resolvemethod(retVal->vftbl->class,
argcount + 1,
(argcount + 1) * sizeof(jni_callblock),
blk);
- retVal = builtin_new(loader_load_sysclass(NULL,
- utf_new_char("java/lang/Double")));
+ retVal = builtin_new(class_new(utf_new_char("java/lang/Double")));
CallVoidMethod(env,
retVal,
class_resolvemethod(retVal->vftbl->class,
MFREE(blk, jni_callblock, 4 /*argcount+2*/);
if (*exceptionptr) {
- java_objectheader *exceptionToWrap=*exceptionptr;
+ java_objectheader *exceptionToWrap = *exceptionptr;
classinfo *ivtec;
java_objectheader *ivte;
- *exceptionptr=0;
- ivtec = loader_load_sysclass(NULL,
- utf_new_char("java/lang/reflect/InvocationTargetException"));
+ *exceptionptr = NULL;
+ ivtec = class_new(utf_new_char("java/lang/reflect/InvocationTargetException"));
ivte = builtin_new(ivtec);
asm_calljavafunction(class_resolvemethod(ivtec,
utf_new_char("<init>"),