-/********************************** jni.c *****************************************
+/* jni.c - implementation of the Java Native Interface functions
- implementation of the Java Native Interface functions
- which are used in the JNI function table
+ 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
-***********************************************************************************/
+ This file is part of CACAO.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA.
+
+ Contact: cacao@complang.tuwien.ac.at
+
+ Authors: ?
+
+ Changes: Joseph Wenninger
+
+ $Id: jni.c 718 2003-12-08 13:03:43Z jowenn $
+
+*/
+
+#include <string.h>
#include "jni.h"
#include "global.h"
#include "loader.h"
#include "native.h"
#include "builtin.h"
#include "threads/thread.h"
+#include "toolbox/loging.h"
+#include "toolbox/memory.h"
#include "nat/java_lang_Byte.h"
#include "nat/java_lang_Character.h"
#include "nat/java_lang_Short.h"
#define JNI_VERSION 0x00010002
-static utf* utf_char=0;
-static utf* utf_bool=0;
-static utf* utf_byte=0;
-static utf* utf_short=0;
-static utf* utf_int=0;
-static utf* utf_long=0;
-static utf* utf_float=0;
-static utf* utf_double=0;
+static utf* utf_char = 0;
+static utf* utf_bool = 0;
+static utf* utf_byte =0;
+static utf* utf_short = 0;
+static utf* utf_int = 0;
+static utf* utf_long = 0;
+static utf* utf_float = 0;
+static utf* utf_double = 0;
+
/********************* accessing instance-fields **********************************/
switch (utf_nextu2(utf_ptr)) {
case 'B':
param=params->data[cnts];
+ if (param==0) {
+ exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
+ return 0;
+ }
if (param->vftbl->class->name==utf_byte) {
blk[cnt].itemtype=TYPE_INT;
blk[cnt].item = (u8) ((struct java_lang_Byte * )param)->value;
break;
case 'C':
param=params->data[cnts];
+ if (param==0) {
+ exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
+ return 0;
+ }
if (param->vftbl->class->name==utf_char) {
blk[cnt].itemtype=TYPE_INT;
blk[cnt].item = (u8) ((struct java_lang_Character * )param)->value;
case 'S':
param=params->data[cnts];
+ if (param==0) {
+ exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
+ return 0;
+ }
if (param->vftbl->class->name==utf_short) {
blk[cnt].itemtype=TYPE_INT;
blk[cnt].item = (u8) ((struct java_lang_Short* )param)->value;
case 'Z':
param=params->data[cnts];
+ if (param==0) {
+ exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
+ return 0;
+ }
if (param->vftbl->class->name==utf_bool) {
blk[cnt].itemtype=TYPE_INT;
blk[cnt].item = (u8) ((struct java_lang_Boolean * )param)->value;
break;
case 'I':
- log_text("fill_callblock_objA: param 'I'");
+ /*log_text("fill_callblock_objA: param 'I'");*/
param=params->data[cnts];
+ if (param==0) {
+ exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
+ return 0;
+ }
if (param->vftbl->class->name==utf_int) {
blk[cnt].itemtype=TYPE_INT;
blk[cnt].item = (u8) ((struct java_lang_Integer * )param)->value;
break;
case 'J':
param=params->data[cnts];
+ if (param==0) {
+ exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
+ return 0;
+ }
if (param->vftbl->class->name==utf_long) {
blk[cnt].itemtype=TYPE_LNG;
blk[cnt].item = (u8) ((struct java_lang_Long * )param)->value;
case 'F' :
param=params->data[cnts];
+ if (param==0) {
+ exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
+ return 0;
+ }
+
if (param->vftbl->class->name==utf_float) {
blk[cnt].itemtype=TYPE_FLT;
*((jfloat*)(&blk[cnt].item))=(jfloat) ((struct java_lang_Float*)param)->value;
break;
case 'D' :
param=params->data[cnts];
+ if (param==0) {
+ exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
+ return 0;
+ }
+
if (param->vftbl->class->name==utf_double) {
blk[cnt].itemtype=TYPE_DBL;
*((jdouble*)(&blk[cnt].item))=(jdouble) ((struct java_lang_Float*)param)->value;
printf("\n");
*/
- if (methodID==0) {
+ if (methodID == 0) {
exceptionptr = native_new_and_init(class_java_lang_NoSuchMethodError);
return 0;
}
- argcount=get_parametercount(methodID);
- if (!( ((methodID->flags & ACC_STATIC) && (obj==0)) ||
- ((!(methodID->flags & ACC_STATIC)) && (obj!=0)) )) {
+ argcount = get_parametercount(methodID);
+
+ if (!( ((methodID->flags & ACC_STATIC) && (obj == 0)) ||
+ ((!(methodID->flags & ACC_STATIC)) && (obj != 0)) )) {
exceptionptr = native_new_and_init(class_java_lang_NoSuchMethodError);
return 0;
}
- if (obj && (! builtin_instanceof(obj,methodID->class))) {
+ if (obj && !builtin_instanceof(obj, methodID->class)) {
exceptionptr = native_new_and_init(class_java_lang_NoSuchMethodError);
return 0;
}
- if (argcount>3) {
- exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
+ if (argcount > 3) {
+ exceptionptr = native_new_and_init(loader_load(utf_new_char("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,'O');
+ fill_callblock(obj, methodID->descriptor, blk, args, 'O');
/* printf("parameter: obj: %p",blk[0].item); */
- ret=asm_calljavafunction2(methodID,argcount+1,(argcount+1)*sizeof(jni_callblock),blk);
- MFREE(blk,jni_callblock,argcount+1);
+ ret = asm_calljavafunction2(methodID,
+ argcount + 1,
+ (argcount + 1) * sizeof(jni_callblock),
+ blk);
+
+ MFREE(blk, jni_callblock, argcount + 1);
/* printf("(CallObjectMethodV)-->%p\n",ret); */
return ret;
}
argcount = get_parametercount(methodID);
- if (!( ((methodID->flags & ACC_STATIC) && (obj==0)) ||
- ((!(methodID->flags & ACC_STATIC)) && (obj!=0)) )) {
+ if (!( ((methodID->flags & ACC_STATIC) && (obj == 0)) ||
+ ((!(methodID->flags & ACC_STATIC)) && (obj != 0)) )) {
exceptionptr = native_new_and_init(class_java_lang_NoSuchMethodError);
return 0;
}
- if (obj && (! builtin_instanceof(obj,methodID->class))) {
+ if (obj && !builtin_instanceof(obj, methodID->class)) {
exceptionptr = native_new_and_init(class_java_lang_NoSuchMethodError);
return 0;
}
- if (argcount>3) {
- exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
+ if (argcount > 3) {
+ exceptionptr = native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
log_text("Too many arguments. CallObjectMethod does not support that");
return 0;
}
utf_display(obj->vftbl->class->name);
printf("\n");
*/
- if (methodID==0) {
+ if (methodID == 0) {
exceptionptr = native_new_and_init(class_java_lang_NoSuchMethodError);
return 0;
}
- argcount=get_parametercount(methodID);
- if (!( ((methodID->flags & ACC_STATIC) && (obj==0)) ||
+ argcount = get_parametercount(methodID);
+
+ if (!( ((methodID->flags & ACC_STATIC) && (obj == 0)) ||
((!(methodID->flags & ACC_STATIC)) && (obj!=0)) )) {
exceptionptr = native_new_and_init(class_java_lang_NoSuchMethodError);
return 0;
}
- if (obj && (! builtin_instanceof(obj,methodID->class))) {
+ if (obj && !builtin_instanceof(obj,methodID->class)) {
exceptionptr = native_new_and_init(class_java_lang_NoSuchMethodError);
return 0;
}
- if (argcount>3) {
- exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
+ if (argcount > 3) {
+ exceptionptr = native_new_and_init(loader_load(utf_new_char("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, 'L');
/* printf("parameter: obj: %p",blk[0].item); */
- ret=asm_calljavafunction2long(methodID,argcount+1,(argcount+1)*sizeof(jni_callblock),blk);
- MFREE(blk,jni_callblock,argcount+1);
+ ret = asm_calljavafunction2long(methodID,
+ argcount + 1,
+ (argcount + 1) * sizeof(jni_callblock),
+ blk);
+
+ MFREE(blk, jni_callblock, argcount + 1);
/* printf("(CallObjectMethodV)-->%p\n",ret); */
return ret;
/*core function for float class methods (float,double)*/
-jdouble callFloatMethod (jobject obj, jmethodID methodID, va_list args,char retType)
+jdouble callFloatMethod(jobject obj, jmethodID methodID, va_list args,char retType)
{
- int argcount=get_parametercount(methodID);
+ int argcount = get_parametercount(methodID);
jni_callblock *blk;
jdouble ret;
utf_display(obj->vftbl->class->name);
printf("\n");
*/
- if (argcount>3) {
- exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
+
+ if (argcount > 3) {
+ exceptionptr = native_new_and_init(loader_load(utf_new_char("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,retType);
+ fill_callblock(obj, methodID->descriptor, blk, args, retType);
/* printf("parameter: obj: %p",blk[0].item); */
- ret=asm_calljavafunction2double(methodID,argcount+1,(argcount+1)*sizeof(jni_callblock),blk);
- MFREE(blk,jni_callblock,argcount+1);
+ ret = asm_calljavafunction2double(methodID,
+ argcount + 1,
+ (argcount + 1) * sizeof(jni_callblock),
+ blk);
+
+ MFREE(blk, jni_callblock, argcount + 1);
/* printf("(CallObjectMethodV)-->%p\n",ret); */
return ret;
jclass GetObjectClass(JNIEnv* env, jobject obj)
{
classinfo *c = obj->vftbl->class;
+/* log_text("GetObjectClass");
+ utf_display(obj->vftbl->class->name);*/
use_class_as_object(c);
+ /*printf("\nPointer: %p\n",c);*/
return c;
}
jobjectArray NewObjectArray (JNIEnv *env, jsize len, jclass clazz, jobject init)
{
+ java_objectarray *j;
if (len<0) {
exceptionptr=proto_java_lang_NegativeArraySizeException;
return NULL;
}
- java_objectarray *j = builtin_anewarray (len, clazz);
+ j = builtin_anewarray (len, clazz);
if (!j) exceptionptr = proto_java_lang_OutOfMemoryError;
return j;
}
jbooleanArray NewBooleanArray (JNIEnv *env, jsize len)
{
+ java_booleanarray *j;
if (len<0) {
exceptionptr=proto_java_lang_NegativeArraySizeException;
return NULL;
}
- java_booleanarray *j = builtin_newarray_boolean(len);
+ j = builtin_newarray_boolean(len);
if (!j) exceptionptr = proto_java_lang_OutOfMemoryError;
return j;
}
jbyteArray NewByteArray (JNIEnv *env, jsize len)
{
+ java_bytearray *j;
if (len<0) {
exceptionptr=proto_java_lang_NegativeArraySizeException;
return NULL;
}
- java_bytearray *j = builtin_newarray_byte(len);
+ j = builtin_newarray_byte(len);
if (!j) exceptionptr = proto_java_lang_OutOfMemoryError;
return j;
}
jcharArray NewCharArray (JNIEnv *env, jsize len)
{
+ java_chararray *j;
if (len<0) {
exceptionptr=proto_java_lang_NegativeArraySizeException;
return NULL;
}
- java_chararray *j = builtin_newarray_char(len);
+ j = builtin_newarray_char(len);
if (!j) exceptionptr = proto_java_lang_OutOfMemoryError;
return j;
}
jshortArray NewShortArray (JNIEnv *env, jsize len)
{
+ java_shortarray *j;
if (len<0) {
exceptionptr=proto_java_lang_NegativeArraySizeException;
return NULL;
}
- java_shortarray *j = builtin_newarray_short(len);
+ j = builtin_newarray_short(len);
if (!j) exceptionptr = proto_java_lang_OutOfMemoryError;
return j;
}
jintArray NewIntArray (JNIEnv *env, jsize len)
{
+ java_intarray *j;
if (len<0) {
exceptionptr=proto_java_lang_NegativeArraySizeException;
return NULL;
}
- java_intarray *j = builtin_newarray_int(len);
+ j = builtin_newarray_int(len);
if (!j) exceptionptr = proto_java_lang_OutOfMemoryError;
return j;
}
jlongArray NewLongArray (JNIEnv *env, jsize len)
{
+ java_longarray *j;
if (len<0) {
exceptionptr=proto_java_lang_NegativeArraySizeException;
return NULL;
}
- java_longarray *j = builtin_newarray_long(len);
+ j = builtin_newarray_long(len);
if (!j) exceptionptr = proto_java_lang_OutOfMemoryError;
return j;
}
jfloatArray NewFloatArray (JNIEnv *env, jsize len)
{
+ java_floatarray *j;
if (len<0) {
exceptionptr=proto_java_lang_NegativeArraySizeException;
return NULL;
}
- java_floatarray *j = builtin_newarray_float(len);
+ j = builtin_newarray_float(len);
if (!j) exceptionptr = proto_java_lang_OutOfMemoryError;
return j;
}
jdoubleArray NewDoubleArray (JNIEnv *env, jsize len)
{
+ java_doublearray *j;
if (len<0) {
exceptionptr=proto_java_lang_NegativeArraySizeException;
return NULL;
}
- java_doublearray *j = builtin_newarray_double(len);
+ j = builtin_newarray_double(len);
if (!j) exceptionptr = proto_java_lang_OutOfMemoryError;
return j;
}
}
argcount=get_parametercount(methodID);
- if (obj && (! builtin_instanceof((java_objectheader*)obj,methodID->class))) {
- exceptionptr = native_new_and_init(class_java_lang_NoSuchMethodError);
- return 0;
- }
+ 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");
+ return 0;
+ }
+
+
if (argcount>3) {
exceptionptr=native_new_and_init(loader_load(utf_new_char("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");
+ return 0;
+ }
+
+ if ((methodID->flags & ACC_STATIC) && (obj)) obj=0;
+
blk = MNEW(jni_callblock, 4 /*argcount+2*/);
retT=fill_callblock_objA(obj,methodID->descriptor,blk,params);
switch (retT) {
case 'V': (void)asm_calljavafunction2(methodID,argcount+1,(argcount+1)*sizeof(jni_callblock),blk);
- retVal=native_new_and_init(loader_load(utf_new_char("java/lang/Void")));
+ retVal=NULL; /*native_new_and_init(loader_load(utf_new_char("java/lang/Void")));*/
break;
case 'I': {
s4 intVal;
}
MFREE(blk, jni_callblock, 4 /*argcount+2*/);
- if (exceptionptr)
- exceptionptr=native_new_and_init(loader_load("java/lang/reflect/InvocationTargetException"));
+ if (exceptionptr) {
+ java_objectheader *exceptionToWrap=exceptionptr;
+ classinfo *ivtec=loader_load(utf_new_char("java/lang/reflect/InvocationTargetException"));
+ java_objectheader* ivte=builtin_new(ivtec);
+ if (asm_calljavamethod(class_resolvemethod(ivtec,utf_new_char("<init>"),utf_new_char("(Ljava/lang/Throwable;)V")),
+ ivte,exceptionToWrap,0,0)!=NULL) panic("jni.c: error while creating InvocationTargetException wrapper");
+ exceptionptr=ivte;
+ }
return retVal;
}