Warning fixes.
[cacao.git] / jni.c
diff --git a/jni.c b/jni.c
index b0b167ff2ab0725d7c233afecbb704ed24deb233..7fa8843dfedc1c63aa8ed9ee3eeba0d9f02ead49 100644 (file)
--- a/jni.c
+++ b/jni.c
@@ -1,10 +1,39 @@
-/********************************** 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"
@@ -12,6 +41,8 @@
 #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 **********************************/
 
@@ -88,7 +122,7 @@ void fill_callblock(void *obj,utf *descr,jni_callblock blk[], va_list data, char
     /* 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 != ')' ) {
@@ -131,7 +165,7 @@ void fill_callblock(void *obj,utf *descr,jni_callblock blk[], va_list data, char
                            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 '[' : {
@@ -146,7 +180,7 @@ void fill_callblock(void *obj,utf *descr,jni_callblock blk[], va_list data, char
        
                             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;                      
                         }
        }
@@ -201,7 +235,7 @@ char fill_callblock_objA(void *obj, utf *descr, jni_callblock blk[], java_object
     /* 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 {
@@ -280,7 +314,7 @@ char fill_callblock_objA(void *obj, utf *descr, jni_callblock blk[], java_object
                                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")));
@@ -389,7 +423,7 @@ char fill_callblock_objA(void *obj, utf *descr, jni_callblock blk[], java_object
                                        }                       
                                }
                                blk[cnt].itemtype = TYPE_ADR;
-                               blk[cnt].item= (u8)(u4) (params->data[cnts]);
+                               blk[cnt].item= PTR_TO_ITEM(params->data[cnts]);
                                break;                  
 
                          }
@@ -405,14 +439,14 @@ char fill_callblock_objA(void *obj, utf *descr, jni_callblock blk[], java_object
                                        }
                                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;
                        }
                }
@@ -466,36 +500,41 @@ jobject callObjectMethod (jobject obj, jmethodID methodID, va_list args)
          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;
 }
@@ -528,20 +567,20 @@ jint callIntegerMethod(jobject obj, jmethodID methodID, char retType, va_list ar
         
        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;
        }
@@ -578,37 +617,42 @@ jlong callLongMethod(jobject obj, jmethodID methodID, va_list args)
         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;
@@ -616,9 +660,9 @@ jlong callLongMethod(jobject obj, jmethodID methodID, va_list args)
 
 
 /*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;
 
@@ -630,19 +674,24 @@ jdouble callFloatMethod (jobject obj, jmethodID methodID, va_list args,char retT
         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;
@@ -855,8 +904,6 @@ jobject PopLocalFrame(JNIEnv* env, jobject result)
     
 jobject NewGlobalRef(JNIEnv* env, jobject lobj)
 {
-       heap_addreference((void**) &lobj);
-
        return lobj;
 }
 
@@ -944,7 +991,7 @@ jobject NewObject (JNIEnv* env, jclass clazz, jmethodID methodID, ...)
                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;
 }
@@ -3237,13 +3284,13 @@ jobject *jni_method_invokeNativeHelper(JNIEnv *env,struct methodinfo *methodID,j
 
        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);
@@ -3253,7 +3300,7 @@ jobject *jni_method_invokeNativeHelper(JNIEnv *env,struct methodinfo *methodID,j
                                        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);
@@ -3263,7 +3310,7 @@ jobject *jni_method_invokeNativeHelper(JNIEnv *env,struct methodinfo *methodID,j
                                        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);
@@ -3273,7 +3320,7 @@ jobject *jni_method_invokeNativeHelper(JNIEnv *env,struct methodinfo *methodID,j
                                        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);
@@ -3283,7 +3330,7 @@ jobject *jni_method_invokeNativeHelper(JNIEnv *env,struct methodinfo *methodID,j
                                        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);
@@ -3293,7 +3340,7 @@ jobject *jni_method_invokeNativeHelper(JNIEnv *env,struct methodinfo *methodID,j
                                        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);
@@ -3303,7 +3350,7 @@ jobject *jni_method_invokeNativeHelper(JNIEnv *env,struct methodinfo *methodID,j
                                        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);
@@ -3313,7 +3360,7 @@ jobject *jni_method_invokeNativeHelper(JNIEnv *env,struct methodinfo *methodID,j
                                        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);
@@ -3331,8 +3378,15 @@ jobject *jni_method_invokeNativeHelper(JNIEnv *env,struct methodinfo *methodID,j
        }
        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;  
 
 }