-/********************************** 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 791 2003-12-16 18:49:19Z edwin $
+
+*/
+
+
+#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;
+#define PTR_TO_ITEM(ptr) ((u8)(size_t)(ptr))
+
+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 **********************************/
/* determine number of parameters */
if (obj) {
blk[0].itemtype=TYPE_ADR;
- blk[0].item=(u8)(u4)obj;
+ blk[0].item=PTR_TO_ITEM(obj);
cnt=1;
} else cnt=0;
while ( **utf_ptr != ')' ) {
while (utf_nextu2(utf_ptr)!=';')
blk[cnt].itemtype=TYPE_ADR;
- blk[cnt].item=(u8)(u4)va_arg(data,void*);
+ blk[cnt].item=PTR_TO_ITEM(va_arg(data,void*));
break;
}
case '[' : {
ch=utf_nextu2(utf_ptr);
blk[cnt].itemtype=TYPE_ADR;
- blk[cnt].item=(u8)(u4)va_arg(data,void*);
+ blk[cnt].item=PTR_TO_ITEM(va_arg(data,void*));
break;
}
}
/* determine number of parameters */
if (obj) {
blk[0].itemtype = TYPE_ADR;
- blk[0].item = (u8)(u4)obj;
+ blk[0].item = PTR_TO_ITEM(obj);
cnt=1;
} else {
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")));
}
}
blk[cnt].itemtype = TYPE_ADR;
- blk[cnt].item= (u8)(u4) (params->data[cnts]);
+ blk[cnt].item= PTR_TO_ITEM(params->data[cnts]);
break;
}
}
end=(*utf_ptr)-1;
ch = utf_nextu2(utf_ptr);
- if (!builtin_arrayinstanceof(params->data[cnts],class_from_descriptor(start,end,0,CLASSLOAD_LOAD))) {
+ if (!builtin_arrayinstanceof(params->data[cnts],class_from_descriptor(start,end,0,CLASSLOAD_LOAD)->vftbl)) {
exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
return 0;
}
blk[cnt].itemtype = TYPE_ADR;
- blk[cnt].item = (u8)(u4) (params->data[cnts]);
+ blk[cnt].item = PTR_TO_ITEM(params->data[cnts]);
break;
}
}
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;
jobject NewGlobalRef(JNIEnv* env, jobject lobj)
{
- heap_addreference((void**) &lobj);
-
return lobj;
}
args[i]=va_arg(vaargs,void*);
}
va_end(vaargs);
- exceptionptr=asm_calljavamethod(methodID,o,args[0],args[1],args[2]);
+ asm_calljavafunction(methodID,o,args[0],args[1],args[2]);
return o;
}
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;
intVal=(s4)asm_calljavafunction2(methodID,
argcount+1,(argcount+1)*sizeof(jni_callblock),blk);
- retVal=builtin_new(loader_load(utf_new_char("java/lang/Integer")));
+ retVal=builtin_new(loader_load_sysclass(NULL,utf_new_char("java/lang/Integer")));
CallVoidMethod(env,retVal,
class_resolvemethod(retVal->vftbl->class,
utf_new_char("<init>"),utf_new_char("(I)V")),intVal);
s4 intVal;
intVal=(s4)asm_calljavafunction2(methodID,
argcount+1,(argcount+1)*sizeof(jni_callblock),blk);
- retVal=builtin_new(loader_load(utf_new_char("java/lang/Byte")));
+ retVal=builtin_new(loader_load_sysclass(NULL,utf_new_char("java/lang/Byte")));
CallVoidMethod(env,retVal,
class_resolvemethod(retVal->vftbl->class,
utf_new_char("<init>"),utf_new_char("(B)V")),intVal);
s4 intVal;
intVal=(s4)asm_calljavafunction2(methodID,
argcount+1,(argcount+1)*sizeof(jni_callblock),blk);
- retVal=builtin_new(loader_load(utf_new_char("java/lang/Character")));
+ retVal=builtin_new(loader_load_sysclass(NULL,utf_new_char("java/lang/Character")));
CallVoidMethod(env,retVal,
class_resolvemethod(retVal->vftbl->class,
utf_new_char("<init>"),utf_new_char("(C)V")),intVal);
s4 intVal;
intVal=(s4)asm_calljavafunction2(methodID,
argcount+1,(argcount+1)*sizeof(jni_callblock),blk);
- retVal=builtin_new(loader_load(utf_new_char("java/lang/Short")));
+ retVal=builtin_new(loader_load_sysclass(NULL,utf_new_char("java/lang/Short")));
CallVoidMethod(env,retVal,
class_resolvemethod(retVal->vftbl->class,
utf_new_char("<init>"),utf_new_char("(S)V")),intVal);
s4 intVal;
intVal=(s4)asm_calljavafunction2(methodID,
argcount+1,(argcount+1)*sizeof(jni_callblock),blk);
- retVal=builtin_new(loader_load(utf_new_char("java/lang/Boolean")));
+ retVal=builtin_new(loader_load_sysclass(NULL,utf_new_char("java/lang/Boolean")));
CallVoidMethod(env,retVal,
class_resolvemethod(retVal->vftbl->class,
utf_new_char("<init>"),utf_new_char("(Z)V")),intVal);
jlong intVal;
intVal=asm_calljavafunction2long(methodID,
argcount+1,(argcount+1)*sizeof(jni_callblock),blk);
- retVal=builtin_new(loader_load(utf_new_char("java/lang/Long")));
+ retVal=builtin_new(loader_load_sysclass(NULL,utf_new_char("java/lang/Long")));
CallVoidMethod(env,retVal,
class_resolvemethod(retVal->vftbl->class,
utf_new_char("<init>"),utf_new_char("(J)V")),intVal);
jdouble floatVal;
floatVal=asm_calljavafunction2double(methodID,
argcount+1,(argcount+1)*sizeof(jni_callblock),blk);
- retVal=builtin_new(loader_load(utf_new_char("java/lang/Float")));
+ retVal=builtin_new(loader_load_sysclass(NULL,utf_new_char("java/lang/Float")));
CallVoidMethod(env,retVal,
class_resolvemethod(retVal->vftbl->class,
utf_new_char("<init>"),utf_new_char("(F)V")),floatVal);
jdouble floatVal;
floatVal=asm_calljavafunction2double(methodID,
argcount+1,(argcount+1)*sizeof(jni_callblock),blk);
- retVal=builtin_new(loader_load(utf_new_char("java/lang/Double")));
+ retVal=builtin_new(loader_load_sysclass(NULL,utf_new_char("java/lang/Double")));
CallVoidMethod(env,retVal,
class_resolvemethod(retVal->vftbl->class,
utf_new_char("<init>"),utf_new_char("(D)V")),floatVal);
}
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_sysclass(NULL,utf_new_char("java/lang/reflect/InvocationTargetException"));
+ java_objectheader* ivte=builtin_new(ivtec);
+ asm_calljavafunction(class_resolvemethod(ivtec,utf_new_char("<init>"),utf_new_char("(Ljava/lang/Throwable;)V")),
+ ivte,exceptionToWrap,0,0);
+ if (exceptionptr!=NULL) panic("jni.c: error while creating InvocationTargetException wrapper");
+ exceptionptr=ivte;
+ }
return retVal;
}