Fixed --disable-threads compiling issues (missing header includes).
[cacao.git] / src / native / jni.c
index 90b3674a477ea88c3df67c396593c9ef6262db9e..a4b995b80bebeb1a917fdae64d0b3a58a65a4fbc 100644 (file)
@@ -31,7 +31,7 @@
             Martin Platter
             Christian Thalinger
 
-   $Id: jni.c 2146 2005-03-30 16:44:24Z twisti $
+   $Id: jni.c 2194 2005-04-03 16:13:27Z twisti $
 
 */
 
@@ -43,6 +43,7 @@
 #include "mm/memory.h"
 #include "native/jni.h"
 #include "native/native.h"
+#include "native/include/java_lang_Object.h"
 #include "native/include/java_lang_Byte.h"
 #include "native/include/java_lang_Character.h"
 #include "native/include/java_lang_Short.h"
 #include "native/include/java_lang_Double.h"
 #include "native/include/java_lang_Throwable.h"
 
+#include "native/include/java_lang_Class.h" /* for java_lang_VMClass.h */
+#include "native/include/java_lang_VMClass.h"
+#include "native/include/java_lang_VMClassLoader.h"
+
 #if defined(USE_THREADS)
 # if defined(NATIVE_THREADS)
 #  include "threads/native/threads.h"
@@ -72,6 +77,7 @@
 #include "vm/tables.h"
 #include "vm/jit/asmpart.h"
 #include "vm/jit/jit.h"
+#include "vm/resolve.h"
 
 
 /* XXX TWISTI hack: define it extern so they can be found in this file */
@@ -105,412 +111,223 @@ static jmethodID removemid = NULL;
 #define getField(obj,typ,var)     *((typ*) ((long int) obj + (long int) var->offset))
 #define setfield_critical(clazz,obj,name,sig,jdatatype,val) setField(obj,jdatatype,getFieldID_critical(env,clazz,name,sig),val); 
 
-
-
-u4 get_parametercount(methodinfo *m)
-{
-       utf  *descr    =  m->descriptor;    /* method-descriptor */
-       char *utf_ptr  =  descr->text;      /* current position in utf-text */
-       char *desc_end =  utf_end(descr);   /* points behind utf string     */
-       u4 parametercount = 0;
-
-       /* skip '(' */
-       utf_nextu2(&utf_ptr);
-
-    /* determine number of parameters */
-       while (*utf_ptr != ')') {
-               get_type(&utf_ptr, desc_end, true);
-               parametercount++;
-       }
-
-       return parametercount;
-}
-
-
-
-void fill_callblock(void *obj, utf *descr, jni_callblock blk[], va_list data, char ret)
+static void fill_callblock(void *obj, methoddesc *descr, jni_callblock blk[], va_list data, int rettype)
 {
-    char *utf__ptr = descr->text;      /* current position in utf-text */
-    char **utf_ptr = &utf__ptr;
-    char *desc_end = utf_end(descr);   /* points behind utf string     */
     int cnt;
     u4 dummy;
-    char c;
-
-       /*
-    log_text("fill_callblock");
-    utf_display(descr);
-    log_text("====");
-       */
-    /* skip '(' */
-    utf_nextu2(utf_ptr);
+       int i;
+       typedesc *paramtype;
 
-    /* determine number of parameters */
        if (obj) {
+               /* the this pointer */
                blk[0].itemtype = TYPE_ADR;
                blk[0].item = PTR_TO_ITEM(obj);
                cnt = 1;
-       } else cnt = 0;
-
-       while (**utf_ptr != ')') {
-               if (*utf_ptr >= desc_end)
-               panic("illegal method descriptor");
+       } 
+       else 
+               cnt = 0;
 
-               switch (utf_nextu2(utf_ptr)) {
+       paramtype = descr->paramtypes;
+       for (i=0; i<descr->paramcount; ++i,++cnt,++paramtype) {
+               switch (paramtype->decltype) {
                        /* primitive types */
-               case 'B':
-               case 'C':
-               case 'S'
-               case 'Z':
+               case PRIMITIVETYPE_BYTE:
+               case PRIMITIVETYPE_CHAR:
+               case PRIMITIVETYPE_SHORT
+               case PRIMITIVETYPE_BOOLEAN: 
                        blk[cnt].itemtype = TYPE_INT;
                        blk[cnt].item = (u8) va_arg(data, int);
                        break;
 
-               case 'I':
+               case PRIMITIVETYPE_INT:
                        blk[cnt].itemtype = TYPE_INT;
                        dummy = va_arg(data, u4);
                        /*printf("fill_callblock: pos:%d, value:%d\n",cnt,dummy);*/
                        blk[cnt].item = (u8) dummy;
                        break;
 
-               case 'J':
+               case PRIMITIVETYPE_LONG:
                        blk[cnt].itemtype = TYPE_LNG;
                        blk[cnt].item = (u8) va_arg(data, jlong);
                        break;
 
-               case 'F':
+               case PRIMITIVETYPE_FLOAT:
                        blk[cnt].itemtype = TYPE_FLT;
                        *((jfloat *) (&blk[cnt].item)) = (jfloat) va_arg(data, jdouble);
                        break;
 
-               case 'D':
+               case PRIMITIVETYPE_DOUBLE:
                        blk[cnt].itemtype = TYPE_DBL;
                        *((jdouble *) (&blk[cnt].item)) = (jdouble) va_arg(data, jdouble);
                        break;
 
-               case 'V':
-                       panic ("V not allowed as function parameter");
-                       break;
-                       
-               case 'L':
-                       while (utf_nextu2(utf_ptr) != ';')
-                           blk[cnt].itemtype = TYPE_ADR;
+               case TYPE_ADR: 
+                       blk[cnt].itemtype = TYPE_ADR;
                        blk[cnt].item = PTR_TO_ITEM(va_arg(data, void*));
                        break;
-                       
-               case '[':
-                       {
-                               /* XXX */
-                               /* arrayclass */
-/*                             char *start = *utf_ptr; */
-                               char ch;
-                               while ((ch = utf_nextu2(utf_ptr)) == '[')
-                                       if (ch == 'L') {
-                                               while (utf_nextu2(utf_ptr) != ';') {}
-                                       }
-       
-                               ch = utf_nextu2(utf_ptr);
-                               blk[cnt].itemtype = TYPE_ADR;
-                               blk[cnt].item = PTR_TO_ITEM(va_arg(data, void*));
-                               break;                  
-                       }
                }
-               cnt++;
        }
 
        /*the standard doesn't say anything about return value checking, but it appears to be usefull*/
-       c = utf_nextu2(utf_ptr);
-       c = utf_nextu2(utf_ptr);
-       /*printf("%c  %c\n",ret,c);*/
-       if (ret == 'O') {
-               if (!((c == 'L') || (c == '[')))
-                       log_text("\n====\nWarning call*Method called for function with wrong return type\n====");
-       } else if (ret != c)
+       if (rettype != descr->returntype.decltype)
                log_text("\n====\nWarning call*Method called for function with wrong return type\n====");
 }
 
-
 /* XXX it could be considered if we should do typechecking here in the future */
-char fill_callblock_objA(void *obj, utf *descr, jni_callblock blk[], java_objectarray* params)
+static bool fill_callblock_objA(void *obj, methoddesc *descr, jni_callblock blk[], java_objectarray* params,
+                                                               int *rettype)
 {
-    char *utf__ptr = descr->text;      /* current position in utf-text */
-    char **utf_ptr = &utf__ptr;
-    char *desc_end = utf_end(descr);   /* points behind utf string     */
-
     jobject param;
     int cnt;
     int cnts;
-    char c;
-
-       /*
-         log_text("fill_callblock");
-         utf_display(descr);
-         log_text("====");
-       */
-    /* skip '(' */
-    utf_nextu2(utf_ptr);
+       typedesc *paramtype;
 
     /* determine number of parameters */
        if (obj) {
+               /* this pointer */
                blk[0].itemtype = TYPE_ADR;
                blk[0].item = PTR_TO_ITEM(obj);
                cnt=1;
-
        } else {
                cnt = 0;
        }
 
-       cnts = 0;
-       while (**utf_ptr != ')') {
-               if (*utf_ptr >= desc_end)
-               panic("illegal method descriptor");
-
-               /* primitive types */
-               switch (utf_nextu2(utf_ptr)) {
-               case 'B':
-                       param = params->data[cnts];
-                       if (param == 0) {
-                               *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
-                               return 0;
-                       }
-                       if (param->vftbl->class->name == utf_java_lang_Byte) {
-                               blk[cnt].itemtype = TYPE_INT;
-                               blk[cnt].item = (u8) ((java_lang_Byte *) param)->value;
-
-                       } else  {
-                               *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
-                               return 0;
-                       }
-                       break;
-
-               case 'C':
-                       param = params->data[cnts];
-                       if (param == 0) {
-                               *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
-                               return 0;
-                       }
-                       if (param->vftbl->class->name == utf_java_lang_Character) {
-                               blk[cnt].itemtype = TYPE_INT;
-                               blk[cnt].item = (u8) ((java_lang_Character *) param)->value;
-
-                       } else  {
-                               *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
-                               return 0;
-                       }
-                       break;
-
-               case 'S':
-                       param = params->data[cnts];
-                       if (param == 0) {
-                               *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
-                               return 0;
-                       }
-                       if (param->vftbl->class->name == utf_java_lang_Short) {
-                               blk[cnt].itemtype = TYPE_INT;
-                               blk[cnt].item = (u8) ((java_lang_Short *) param)->value;
-
-                       } else  {
-                               if (param->vftbl->class->name == utf_java_lang_Byte) {
-                                       blk[cnt].itemtype = TYPE_INT;
-                                       blk[cnt].item = (u8) ((java_lang_Byte *) param)->value;
-
-                               } else {
-                                       *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
-                                       return 0;
-                               }
-                       }
-                       break;
-
-               case 'Z':
-                       param = params->data[cnts];
-                       if (param == 0) {
-                               *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
-                               return 0;
-                       }
-                       if (param->vftbl->class->name == utf_java_lang_Boolean) {
-                               blk[cnt].itemtype = TYPE_INT;
-                               blk[cnt].item = (u8) ((java_lang_Boolean *) param)->value;
-
-                       } else {
-                               *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
-                               return 0;
-                       }
-                       break;
-
-               case 'I':
-                       /*log_text("fill_callblock_objA: param 'I'");*/
-                       param = params->data[cnts];
-                       if (param == 0) {
-                               *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
-                               return 0;
-                       }
-                       if (param->vftbl->class->name == utf_java_lang_Integer) {
-                               blk[cnt].itemtype = TYPE_INT;
-                               blk[cnt].item = (u8) ((java_lang_Integer *) param)->value;
-                               /*printf("INT VALUE :%d\n",((struct java_lang_Integer * )param)->value);*/
-                       } else {
-                               if (param->vftbl->class->name == utf_java_lang_Short) {
-                                       blk[cnt].itemtype = TYPE_INT;
-                                       blk[cnt].item = (u8) ((java_lang_Short *) param)->value;
-
-                               } else  {
-                                       if (param->vftbl->class->name == utf_java_lang_Byte) {
-                                               blk[cnt].itemtype = TYPE_INT;
-                                               blk[cnt].item = (u8) ((java_lang_Byte *) param)->value;
-
-                                       } else  {
-                                               *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
-                                               return 0;
-                                       }
-                               }
-                       }
-                       break;
-
-               case 'J':
-                       param = params->data[cnts];
-                       if (param == 0) {
-                               *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
-                               return 0;
-                       }
-                       if (param->vftbl->class->name == utf_java_lang_Long) {
-                               blk[cnt].itemtype = TYPE_LNG;
-                               blk[cnt].item = (u8) ((java_lang_Long *) param)->value;
-
-                       } else  {
-                               if (param->vftbl->class->name == utf_java_lang_Integer) {
-                                       blk[cnt].itemtype = TYPE_LNG;
-                                       blk[cnt].item = (u8) ((java_lang_Integer *) param)->value;
-
-                               } else {
-                                       if (param->vftbl->class->name == utf_java_lang_Short) {
-                                               blk[cnt].itemtype = TYPE_LNG;
-                                               blk[cnt].item = (u8) ((java_lang_Short *) param)->value;
-
-                                       } else  {
-                                               if (param->vftbl->class->name == utf_java_lang_Byte) {
-                                                       blk[cnt].itemtype = TYPE_LNG;
-                                                       blk[cnt].item = (u8) ((java_lang_Byte *) param)->value;
-                                               } else  {
-                                                       *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
-                                                       return 0;
+       paramtype = descr->paramtypes;
+       for (cnts=0; cnts < descr->paramcount; ++cnts,++cnt,++paramtype) {
+               switch (paramtype->type) {
+                       /* primitive types */
+                       case TYPE_INT:
+                       case TYPE_LONG:
+                       case TYPE_FLOAT:
+                       case TYPE_DOUBLE:
+                       
+                               param = params->data[cnts];
+                               if (!param)
+                                       goto illegal_arg;
+
+                               /* internally used data type */
+                               blk[cnt].itemtype = paramtype->type;
+
+                               /* convert the value according to its declared type */
+                               switch (paramtype->decltype) {
+                                               case PRIMITIVETYPE_BOOLEAN:
+                                                       if (param->vftbl->class == primitivetype_table[paramtype->decltype].class_wrap)
+                                                               blk[cnt].item = (u8) ((java_lang_Boolean *) param)->value;
+                                                       else
+                                                               goto illegal_arg;
+                                                       break;
+                                               case PRIMITIVETYPE_BYTE:
+                                                       if (param->vftbl->class == primitivetype_table[paramtype->decltype].class_wrap)
+                                                               blk[cnt].item = (u8) ((java_lang_Byte *) param)->value;
+                                                       else
+                                                               goto illegal_arg;
+                                                       break;
+                                               case PRIMITIVETYPE_CHAR:
+                                                       if (param->vftbl->class == primitivetype_table[paramtype->decltype].class_wrap)
+                                                               blk[cnt].item = (u8) ((java_lang_Character *) param)->value;
+                                                       else
+                                                               goto illegal_arg;
+                                                       break;
+                                               case PRIMITIVETYPE_SHORT:
+                                                       if (param->vftbl->class == primitivetype_table[paramtype->decltype].class_wrap)
+                                                               blk[cnt].item = (u8) ((java_lang_Short *) param)->value;
+                                                       else if (param->vftbl->class == primitivetype_table[PRIMITIVETYPE_BYTE].class_wrap)
+                                                               blk[cnt].item = (u8) ((java_lang_Byte *) param)->value;
+                                                       else
+                                                               goto illegal_arg;
+                                                       break;
+                                               case PRIMITIVETYPE_INT:
+                                                       if (param->vftbl->class == primitivetype_table[paramtype->decltype].class_wrap)
+                                                               blk[cnt].item = (u8) ((java_lang_Integer *) param)->value;
+                                                       else if (param->vftbl->class == primitivetype_table[PRIMITIVETYPE_SHORT].class_wrap)
+                                                               blk[cnt].item = (u8) ((java_lang_Short *) param)->value;
+                                                       else if (param->vftbl->class == primitivetype_table[PRIMITIVETYPE_BYTE].class_wrap)
+                                                               blk[cnt].item = (u8) ((java_lang_Byte *) param)->value;
+                                                       else
+                                                               goto illegal_arg;
+                                                       break;
+                                               case PRIMITIVETYPE_LONG:
+                                                       if (param->vftbl->class == primitivetype_table[paramtype->decltype].class_wrap)
+                                                               blk[cnt].item = (u8) ((java_lang_Long *) param)->value;
+                                                       else if (param->vftbl->class == primitivetype_table[PRIMITIVETYPE_INT].class_wrap)
+                                                               blk[cnt].item = (u8) ((java_lang_Integer *) param)->value;
+                                                       else if (param->vftbl->class == primitivetype_table[PRIMITIVETYPE_SHORT].class_wrap)
+                                                               blk[cnt].item = (u8) ((java_lang_Short *) param)->value;
+                                                       else if (param->vftbl->class == primitivetype_table[PRIMITIVETYPE_BYTE].class_wrap)
+                                                               blk[cnt].item = (u8) ((java_lang_Byte *) param)->value;
+                                                       else
+                                                               goto illegal_arg;
+                                                       break;
+                                               case PRIMITIVETYPE_FLOAT:
+                                                       if (param->vftbl->class == primitivetype_table[paramtype->decltype].class_wrap)
+                                                               *((jfloat *) (&blk[cnt].item)) = (jfloat) ((java_lang_Float *) param)->value;
+                                                       else
+                                                               goto illegal_arg;
+                                                       break;
+                                               case PRIMITIVETYPE_DOUBLE:
+                                                       if (param->vftbl->class == primitivetype_table[paramtype->decltype].class_wrap)
+                                                               *((jdouble *) (&blk[cnt].item)) = (jdouble) ((java_lang_Float *) param)->value;
+                                                       else if (param->vftbl->class == primitivetype_table[PRIMITIVETYPE_FLOAT].class_wrap)
+                                                               *((jfloat *) (&blk[cnt].item)) = (jfloat) ((java_lang_Float *) param)->value;
+                                                       else
+                                                               goto illegal_arg;
+                                                       break;
+                                               default:
+                                                       goto illegal_arg;
+                               } /* end declared type switch */
+                               break;
+               
+                       case TYPE_ADDRESS:
+                               {
+                                       classinfo *cls;
+                                  
+                                       if (!resolve_class_from_typedesc(paramtype,true,&cls))
+                                               return false; /* exception */
+                                       if (params->data[cnts] != 0) {
+                                               if (paramtype->arraydim > 0) {
+                                                       if (!builtin_arrayinstanceof(params->data[cnts], cls->vftbl))
+                                                               goto illegal_arg;
+                                               }
+                                               else {
+                                                       if (!builtin_instanceof(params->data[cnts], cls))
+                                                               goto illegal_arg;
                                                }
                                        }
+                                       blk[cnt].itemtype = TYPE_ADR;
+                                       blk[cnt].item = PTR_TO_ITEM(params->data[cnts]);
                                }
-
-                       }
-                       break;
-
-               case 'F':
-                       param = params->data[cnts];
-                       if (param == 0) {
-                               *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
-                               return 0;
-                       }
-
-                       if (param->vftbl->class->name == utf_java_lang_Float) {
-                               blk[cnt].itemtype = TYPE_FLT;
-                               *((jfloat *) (&blk[cnt].item)) = (jfloat) ((java_lang_Float *) param)->value;
-
-                       } else  {
-                               *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
-                               return 0;
-                       }
-                       break;
-
-               case 'D':
-                       param = params->data[cnts];
-                       if (param == 0) {
-                               *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
-                               return 0;
-                       }
-
-                       if (param->vftbl->class->name == utf_java_lang_Double) {
-                               blk[cnt].itemtype = TYPE_DBL;
-                               *((jdouble *) (&blk[cnt].item)) = (jdouble) ((java_lang_Float *) param)->value;
-
-                       } else  {
-                               if (param->vftbl->class->name == utf_java_lang_Float) {
-                                       blk[cnt].itemtype = TYPE_DBL;
-                                       *((jdouble *) (&blk[cnt].item)) = (jdouble) ((java_lang_Float *) param)->value;
-
-                               } else  {
-                                       *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
-                                       return 0;
-                               }
-                       }
-                       break;
-
-               case 'V':
-                       panic("V not allowed as function parameter");
-                       break;
-
-               case 'L':
-                       {
-                               char *start = (*utf_ptr) - 1;
-                               /*char *end = NULL;
-
-                               while (utf_nextu2(utf_ptr) != ';')
-                                       end = (*utf_ptr) + 1;*/
-
-                               if (!builtin_instanceof(params->data[cnts], class_from_descriptor(start, desc_end, utf_ptr, CLASSLOAD_LOAD))) {
-                                       if (params->data[cnts] != 0) {
-                                               *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
-                                               return 0;
-                                       }                       
-                               }
-                               blk[cnt].itemtype = TYPE_ADR;
-                               blk[cnt].item = PTR_TO_ITEM(params->data[cnts]);
                                break;                  
-                       }
-
-               case '[':
-                       {
-                               char *start = (*utf_ptr) - 1;
-                               /*char *end;
-                               
-                               char ch;
-                               while ((ch = utf_nextu2(utf_ptr)) == '[')
-                                       if (ch == 'L') {
-                                               while (utf_nextu2(utf_ptr) != ';') {}
-                                       }
 
-                               end = (*utf_ptr) - 1;
-                               ch = utf_nextu2(utf_ptr); */
+                       default:
+                               goto illegal_arg;
+               } /* end param type switch */
 
-                               if (!builtin_arrayinstanceof(params->data[cnts], class_from_descriptor(start, desc_end, utf_ptr, CLASSLOAD_LOAD)->vftbl)) {
-                                       *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
-                                       return 0;
-                               }
+       } /* end param loop */
 
-                               blk[cnt].itemtype = TYPE_ADR;
-                               blk[cnt].item = PTR_TO_ITEM(params->data[cnts]);
-                               break;
-                       }
-               }
-               cnt++;
-               cnts++;
-       }
+       if (rettype)
+               *rettype = descr->returntype.decltype;
+       return true;
 
-       c = utf_nextu2(utf_ptr);
-       c = utf_nextu2(utf_ptr);
-       return c; /*return type needed usage of the right lowlevel methods*/
+illegal_arg:
+       *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
+       return false;
 }
 
 
-jmethodID get_virtual(jobject obj,jmethodID methodID) {
+static jmethodID get_virtual(jobject obj,jmethodID methodID) {
        if (obj->vftbl->class==methodID->class) return methodID;
        return class_resolvemethod (obj->vftbl->class, methodID->name, methodID->descriptor);
 }
 
 
-jmethodID get_nonvirtual(jclass clazz,jmethodID methodID) {
+static 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);
 }
 
 
-jobject callObjectMethod (jobject obj, jmethodID methodID, va_list args)
+static jobject callObjectMethod (jobject obj, jmethodID methodID, va_list args)
 {      
        int argcount;
        jni_callblock *blk;
@@ -523,7 +340,7 @@ jobject callObjectMethod (jobject obj, jmethodID methodID, va_list args)
                return 0;
        }
 
-       argcount = get_parametercount(methodID);
+       argcount = methodID->parseddesc->paramcount;
 
        if (!( ((methodID->flags & ACC_STATIC) && (obj == 0)) ||
                ((!(methodID->flags & ACC_STATIC)) && (obj != 0)) )) {
@@ -547,7 +364,7 @@ jobject callObjectMethod (jobject obj, jmethodID methodID, va_list args)
 
        blk = MNEW(jni_callblock, /*4 */argcount+2);
 
-       fill_callblock(obj, methodID->descriptor, blk, args, 'O');
+       fill_callblock(obj, methodID->parseddesc, blk, args, TYPE_ADR);
        /*      printf("parameter: obj: %p",blk[0].item); */
        ret = asm_calljavafunction2(methodID,
                                                                argcount + 1,
@@ -564,14 +381,12 @@ jobject callObjectMethod (jobject obj, jmethodID methodID, va_list args)
   core function for integer class methods (bool, byte, short, integer)
   This is basically needed for i386
 */
-jint callIntegerMethod(jobject obj, jmethodID methodID, char retType, va_list args)
+static jint callIntegerMethod(jobject obj, jmethodID methodID, int retType, va_list args)
 {
        int argcount;
        jni_callblock *blk;
        jint ret;
 
-/*     printf("%p,     %c\n",retType,methodID,retType);*/
-
         /*
         log_text("JNI-Call: CallObjectMethodV");
         utf_display(methodID->name);
@@ -585,7 +400,7 @@ jint callIntegerMethod(jobject obj, jmethodID methodID, char retType, va_list ar
                return 0;
        }
         
-       argcount = get_parametercount(methodID);
+       argcount = methodID->parseddesc->paramcount;
 
        if (!( ((methodID->flags & ACC_STATIC) && (obj == 0)) ||
                ((!(methodID->flags & ACC_STATIC)) && (obj != 0)) )) {
@@ -608,7 +423,7 @@ jint callIntegerMethod(jobject obj, jmethodID methodID, char retType, va_list ar
 
        blk = MNEW(jni_callblock, /*4 */ argcount+2);
 
-       fill_callblock(obj, methodID->descriptor, blk, args, retType);
+       fill_callblock(obj, methodID->parseddesc, blk, args, retType);
 
        /*      printf("parameter: obj: %p",blk[0].item); */
        ret = asm_calljavafunction2int(methodID,
@@ -624,7 +439,7 @@ jint callIntegerMethod(jobject obj, jmethodID methodID, char retType, va_list ar
 
 
 /*core function for long class functions*/
-jlong callLongMethod(jobject obj, jmethodID methodID, va_list args)
+static jlong callLongMethod(jobject obj, jmethodID methodID, va_list args)
 {
        int argcount;
        jni_callblock *blk;
@@ -643,7 +458,7 @@ jlong callLongMethod(jobject obj, jmethodID methodID, va_list args)
                return 0;
        }
 
-       argcount = get_parametercount(methodID);
+       argcount = methodID->parseddesc->paramcount;
 
        if (!( ((methodID->flags & ACC_STATIC) && (obj == 0)) ||
                   ((!(methodID->flags & ACC_STATIC)) && (obj!=0)) )) {
@@ -666,7 +481,7 @@ jlong callLongMethod(jobject obj, jmethodID methodID, va_list args)
 
        blk = MNEW(jni_callblock,/* 4 */argcount+2);
 
-       fill_callblock(obj, methodID->descriptor, blk, args, 'J');
+       fill_callblock(obj, methodID->parseddesc, blk, args, TYPE_LNG);
 
        /*      printf("parameter: obj: %p",blk[0].item); */
        ret = asm_calljavafunction2long(methodID,
@@ -682,9 +497,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)
+static jdouble callFloatMethod(jobject obj, jmethodID methodID, va_list args,int retType)
 {
-       int argcount = get_parametercount(methodID);
+       int argcount = methodID->parseddesc->paramcount;
        jni_callblock *blk;
        jdouble ret;
 
@@ -707,7 +522,7 @@ jdouble callFloatMethod(jobject obj, jmethodID methodID, va_list args,char retTy
 
        blk = MNEW(jni_callblock, /*4 */ argcount+2);
 
-       fill_callblock(obj, methodID->descriptor, blk, args, retType);
+       fill_callblock(obj, methodID->parseddesc, blk, args, retType);
 
        /*      printf("parameter: obj: %p",blk[0].item); */
        ret = asm_calljavafunction2double(methodID,
@@ -729,7 +544,7 @@ jdouble callFloatMethod(jobject obj, jmethodID methodID, va_list args,char retTy
 
 ************************************************************************************/
 
-fieldinfo *jclass_findfield (classinfo *c, utf *name, utf *desc)
+static fieldinfo *jclass_findfield (classinfo *c, utf *name, utf *desc)
 {
        s4 i;
 /*     printf(" FieldCount: %d\n",c->fieldscount);
@@ -743,7 +558,7 @@ fieldinfo *jclass_findfield (classinfo *c, utf *name, utf *desc)
                        return &(c->fields[i]);
                }
 
-       if (c->super) return jclass_findfield(c->super,name,desc);
+       if (c->super.cls) return jclass_findfield(c->super.cls,name,desc);
 
        return NULL;
 }
@@ -777,73 +592,17 @@ jint GetVersion(JNIEnv *env)
 jclass DefineClass(JNIEnv *env, const char *name, jobject loader, const jbyte *buf, jsize bufLen)
 {
        jclass c;
-       jclass r;
-       classbuffer *cb;
-
-       c = class_new(utf_new_char_classname((char *) name));
-
-#if defined(USE_THREADS)
-       /* enter a monitor on the class */
-
-       builtin_monitorenter((java_objectheader *) c);
-#endif
-
-#if defined(STATISTICS)
-       /* measure time */
-
-       if (getloadingtime)
-               loadingtime_start();
-#endif
-
-       /* build a classbuffer with the given data */
-
-       cb = NEW(classbuffer);
-       cb->class = c;
-       cb->size = bufLen;
-       cb->data = (u1 *) buf;
-       cb->pos = cb->data - 1;
-
-       /* load the class from this buffer */
-
-       r = load_class_from_classbuffer(cb);
 
-       /* if return value is NULL, we had a problem and the class is not loaded */
+       c = (jclass) Java_java_lang_VMClassLoader_defineClass(env,
+                                                                                                                 NULL,
+                                                                                                                 (java_lang_ClassLoader *) loader,
+                                                                                                                 javastring_new_char(name),
+                                                                                                                 (java_bytearray *) buf,
+                                                                                                                 0,
+                                                                                                                 bufLen,
+                                                                                                                 NULL);
 
-       if (!r) {
-               c->loaded = false;
-
-               /* now free the allocated memory, otherwise we could ran into a DOS */
-
-               class_remove(c);
-       }
-
-       /* free memory */
-
-       FREE(cb, classbuffer);
-
-#if defined(STATISTICS)
-       /* measure time */
-
-       if (getloadingtime)
-               loadingtime_stop();
-#endif
-
-#if defined(USE_THREADS)
-       /* leave the monitor */
-
-       builtin_monitorexit((java_objectheader *) c);
-#endif
-
-       /* XXX link the class here? */
-/*     if (class_link(c)) */
-/*             return NULL; */
-
-       if (r) {
-               c->classloader = loader;
-               use_class_as_object(r);
-       }
-
-       return r;
+       return c;
 }
 
 
@@ -859,9 +618,7 @@ jclass FindClass(JNIEnv *env, const char *name)
 {
        classinfo *c;  
   
-       c = class_new(utf_new_char_classname((char *) name));
-
-       if (!load_class_bootstrap(c) || !link_class(c)) {
+       if (!load_class_bootstrap(utf_new_char_classname((char *) name),&c) || !link_class(c)) {
                class_remove(c);
 
                return NULL;
@@ -900,7 +657,7 @@ jclass GetSuperclass(JNIEnv *env, jclass sub)
 {
        classinfo *c;
 
-       c = ((classinfo *) sub)->super;
+       c = ((classinfo *) sub)->super.cls;
 
        if (!c)
                return NULL;
@@ -919,7 +676,10 @@ jclass GetSuperclass(JNIEnv *env, jclass sub)
 
 jboolean IsAssignableFrom(JNIEnv *env, jclass sub, jclass sup)
 {
-       return builtin_isanysubclass(sub, sup);
+       return Java_java_lang_VMClass_isAssignableFrom(env,
+                                                                                                  NULL,
+                                                                                                  (java_lang_Class *) sup,
+                                                                                                  (java_lang_Class *) sub);
 }
 
 
@@ -1059,7 +819,7 @@ void FatalError(JNIEnv *env, const char *msg)
 
 jint PushLocalFrame(JNIEnv* env, jint capacity)
 {
-       /* empty */
+       log_text("JNI-Call: PushLocalFrame: IMPLEMENT ME!");
 
        return 0;
 }
@@ -1161,7 +921,7 @@ jobject NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
 {
        java_objectheader *o;
        void* args[3];
-       int argcount=get_parametercount(methodID);
+       int argcount=methodID->parseddesc->paramcount;
        int i;
        va_list vaargs;
 
@@ -1233,19 +993,29 @@ jobject NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID, jvalue *args)
 
 jclass GetObjectClass(JNIEnv *env, jobject obj)
 {
-       classinfo *c = obj->vftbl->class;
+       classinfo *c;
+       
+       if (!obj || !obj->vftbl)
+               return NULL;
 
+       c = obj->vftbl->class;
        use_class_as_object(c);
-
        return c;
 }
 
 
-/************* tests whether an object is an instance of a class ******************/
+/* IsInstanceOf ****************************************************************
+
+   Tests whether an object is an instance of a class.
+
+*******************************************************************************/
 
-jboolean IsInstanceOf(JNIEnvenv, jobject obj, jclass clazz)
+jboolean IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz)
 {
-       return builtin_instanceof(obj,clazz);
+       return Java_java_lang_VMClass_isInstance(env,
+                                                                                        NULL,
+                                                                                        (java_lang_Class *) clazz,
+                                                                                        (java_lang_Object *) obj);
 }
 
 
@@ -1340,7 +1110,7 @@ jboolean CallBooleanMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...)
 /*     log_text("JNI-Call: CallBooleanMethod");*/
 
        va_start(vaargs,methodID);
-       ret = (jboolean)callIntegerMethod(obj,get_virtual(obj,methodID),'Z',vaargs);
+       ret = (jboolean)callIntegerMethod(obj,get_virtual(obj,methodID),PRIMITIVETYPE_BOOLEAN,vaargs);
        va_end(vaargs);
        return ret;
 
@@ -1348,7 +1118,7 @@ jboolean CallBooleanMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...)
 
 jboolean CallBooleanMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
 {
-       return (jboolean)callIntegerMethod(obj,get_virtual(obj,methodID),'Z',args);
+       return (jboolean)callIntegerMethod(obj,get_virtual(obj,methodID),PRIMITIVETYPE_BOOLEAN,args);
 
 }
 
@@ -1367,7 +1137,7 @@ jbyte CallByteMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...)
 /*     log_text("JNI-Call: CallVyteMethod");*/
 
        va_start(vaargs,methodID);
-       ret = callIntegerMethod(obj,get_virtual(obj,methodID),'B',vaargs);
+       ret = callIntegerMethod(obj,get_virtual(obj,methodID),PRIMITIVETYPE_BYTE,vaargs);
        va_end(vaargs);
        return ret;
 
@@ -1376,7 +1146,7 @@ jbyte CallByteMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...)
 jbyte CallByteMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
 {
 /*     log_text("JNI-Call: CallByteMethodV");*/
-       return callIntegerMethod(obj,methodID,'B',args);
+       return callIntegerMethod(obj,methodID,PRIMITIVETYPE_BYTE,args);
 }
 
 
@@ -1396,7 +1166,7 @@ jchar CallCharMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
 /*     log_text("JNI-Call: CallCharMethod");*/
 
        va_start(vaargs,methodID);
-       ret = callIntegerMethod(obj, get_virtual(obj, methodID), 'C', vaargs);
+       ret = callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_CHAR, vaargs);
        va_end(vaargs);
 
        return ret;
@@ -1406,7 +1176,7 @@ jchar CallCharMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
 jchar CallCharMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
 {
 /*     log_text("JNI-Call: CallCharMethodV");*/
-       return callIntegerMethod(obj,get_virtual(obj,methodID),'C',args);
+       return callIntegerMethod(obj,get_virtual(obj,methodID),PRIMITIVETYPE_CHAR,args);
 }
 
 
@@ -1426,7 +1196,7 @@ jshort CallShortMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
 /*     log_text("JNI-Call: CallShortMethod");*/
 
        va_start(vaargs, methodID);
-       ret = callIntegerMethod(obj, get_virtual(obj, methodID), 'S', vaargs);
+       ret = callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_SHORT, vaargs);
        va_end(vaargs);
 
        return ret;
@@ -1435,7 +1205,7 @@ jshort CallShortMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
 
 jshort CallShortMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
 {
-       return callIntegerMethod(obj, get_virtual(obj, methodID), 'S', args);
+       return callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_SHORT, args);
 }
 
 
@@ -1454,7 +1224,7 @@ jint CallIntMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
        va_list vaargs;
 
        va_start(vaargs,methodID);
-       ret = callIntegerMethod(obj, get_virtual(obj, methodID), 'I', vaargs);
+       ret = callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_INT, vaargs);
        va_end(vaargs);
 
        return ret;
@@ -1463,7 +1233,7 @@ jint CallIntMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
 
 jint CallIntMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
 {
-       return callIntegerMethod(obj, get_virtual(obj, methodID), 'I', args);
+       return callIntegerMethod(obj, get_virtual(obj, methodID),PRIMITIVETYPE_INT, args);
 }
 
 
@@ -1512,7 +1282,7 @@ jfloat CallFloatMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
 /*     log_text("JNI-Call: CallFloatMethod");*/
 
        va_start(vaargs,methodID);
-       ret = callFloatMethod(obj, get_virtual(obj, methodID), vaargs, 'F');
+       ret = callFloatMethod(obj, get_virtual(obj, methodID), vaargs, PRIMITIVETYPE_FLOAT);
        va_end(vaargs);
 
        return ret;
@@ -1522,7 +1292,7 @@ jfloat CallFloatMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
 jfloat CallFloatMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
 {
        log_text("JNI-Call: CallFloatMethodV");
-       return callFloatMethod(obj, get_virtual(obj, methodID), args, 'F');
+       return callFloatMethod(obj, get_virtual(obj, methodID), args, PRIMITIVETYPE_FLOAT);
 }
 
 
@@ -1543,7 +1313,7 @@ jdouble CallDoubleMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
 /*     log_text("JNI-Call: CallDoubleMethod");*/
 
        va_start(vaargs,methodID);
-       ret = callFloatMethod(obj, get_virtual(obj, methodID), vaargs, 'D');
+       ret = callFloatMethod(obj, get_virtual(obj, methodID), vaargs, PRIMITIVETYPE_DOUBLE);
        va_end(vaargs);
 
        return ret;
@@ -1553,7 +1323,7 @@ jdouble CallDoubleMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
 jdouble CallDoubleMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
 {
        log_text("JNI-Call: CallDoubleMethodV");
-       return callFloatMethod(obj, get_virtual(obj, methodID), args, 'D');
+       return callFloatMethod(obj, get_virtual(obj, methodID), args, PRIMITIVETYPE_DOUBLE);
 }
 
 
@@ -1570,7 +1340,7 @@ void CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
        va_list vaargs;
 
        va_start(vaargs,methodID);
-       (void) callIntegerMethod(obj, get_virtual(obj, methodID), 'V', vaargs);
+       (void) callIntegerMethod(obj, get_virtual(obj, methodID),TYPE_VOID, vaargs);
        va_end(vaargs);
 }
 
@@ -1578,7 +1348,7 @@ void CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
 void CallVoidMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
 {
        log_text("JNI-Call: CallVoidMethodV");
-       (void)callIntegerMethod(obj,get_virtual(obj,methodID),'V',args);
+       (void)callIntegerMethod(obj,get_virtual(obj,methodID),TYPE_VOID,args);
 }
 
 
@@ -1622,7 +1392,7 @@ jboolean CallNonvirtualBooleanMethod (JNIEnv *env, jobject obj, jclass clazz, jm
 /*     log_text("JNI-Call: CallNonvirtualBooleanMethod");*/
 
        va_start(vaargs,methodID);
-       ret = (jboolean)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'Z',vaargs);
+       ret = (jboolean)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_BOOLEAN,vaargs);
        va_end(vaargs);
        return ret;
 
@@ -1632,7 +1402,7 @@ jboolean CallNonvirtualBooleanMethod (JNIEnv *env, jobject obj, jclass clazz, jm
 jboolean CallNonvirtualBooleanMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
 {
 /*     log_text("JNI-Call: CallNonvirtualBooleanMethodV");*/
-       return (jboolean)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'Z',args);
+       return (jboolean)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_BOOLEAN,args);
 }
 
 
@@ -1653,7 +1423,7 @@ jbyte CallNonvirtualByteMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodI
 /*     log_text("JNI-Call: CallNonvirutalByteMethod");*/
 
        va_start(vaargs,methodID);
-       ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'B',vaargs);
+       ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_BYTE,vaargs);
        va_end(vaargs);
        return ret;
 }
@@ -1662,7 +1432,7 @@ jbyte CallNonvirtualByteMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodI
 jbyte CallNonvirtualByteMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
 {
        /*log_text("JNI-Call: CallNonvirtualByteMethodV"); */
-       return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'B',args);
+       return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_BYTE,args);
 
 }
 
@@ -1684,7 +1454,7 @@ jchar CallNonvirtualCharMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodI
 /*     log_text("JNI-Call: CallNonVirtualCharMethod");*/
 
        va_start(vaargs,methodID);
-       ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'C',vaargs);
+       ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_CHAR,vaargs);
        va_end(vaargs);
        return ret;
 }
@@ -1693,7 +1463,7 @@ jchar CallNonvirtualCharMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodI
 jchar CallNonvirtualCharMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
 {
        /*log_text("JNI-Call: CallNonvirtualCharMethodV");*/
-       return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'C',args);
+       return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_CHAR,args);
 }
 
 
@@ -1714,7 +1484,7 @@ jshort CallNonvirtualShortMethod (JNIEnv *env, jobject obj, jclass clazz, jmetho
        /*log_text("JNI-Call: CallNonvirtualShortMethod");*/
 
        va_start(vaargs,methodID);
-       ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'S',vaargs);
+       ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_SHORT,vaargs);
        va_end(vaargs);
        return ret;
 }
@@ -1723,7 +1493,7 @@ jshort CallNonvirtualShortMethod (JNIEnv *env, jobject obj, jclass clazz, jmetho
 jshort CallNonvirtualShortMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
 {
        /*log_text("JNI-Call: CallNonvirtualShortMethodV");*/
-       return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'S',args);
+       return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_SHORT,args);
 }
 
 
@@ -1745,7 +1515,7 @@ jint CallNonvirtualIntMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID
        /*log_text("JNI-Call: CallNonvirtualIntMethod");*/
 
         va_start(vaargs,methodID);
-        ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'I',vaargs);
+        ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_INT,vaargs);
         va_end(vaargs);
         return ret;
 }
@@ -1754,7 +1524,7 @@ jint CallNonvirtualIntMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID
 jint CallNonvirtualIntMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
 {
        /*log_text("JNI-Call: CallNonvirtualIntMethodV");*/
-        return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'I',args);
+        return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),PRIMITIVETYPE_INT,args);
 }
 
 
@@ -1801,7 +1571,7 @@ jfloat CallNonvirtualFloatMethod (JNIEnv *env, jobject obj, jclass clazz, jmetho
 
 
        va_start(vaargs,methodID);
-       ret = callFloatMethod(obj,get_nonvirtual(clazz,methodID),vaargs,'F');
+       ret = callFloatMethod(obj,get_nonvirtual(clazz,methodID),vaargs,PRIMITIVETYPE_FLOAT);
        va_end(vaargs);
        return ret;
 
@@ -1811,7 +1581,7 @@ jfloat CallNonvirtualFloatMethod (JNIEnv *env, jobject obj, jclass clazz, jmetho
 jfloat CallNonvirtualFloatMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
 {
        log_text("JNI-Call: CallNonvirtualFloatMethodV");
-       return callFloatMethod(obj,get_nonvirtual(clazz,methodID),args,'F');
+       return callFloatMethod(obj,get_nonvirtual(clazz,methodID),args,PRIMITIVETYPE_FLOAT);
 }
 
 
@@ -1831,7 +1601,7 @@ jdouble CallNonvirtualDoubleMethod (JNIEnv *env, jobject obj, jclass clazz, jmet
        log_text("JNI-Call: CallNonvirtualDoubleMethod");
 
        va_start(vaargs,methodID);
-       ret = callFloatMethod(obj,get_nonvirtual(clazz,methodID),vaargs,'D');
+       ret = callFloatMethod(obj,get_nonvirtual(clazz,methodID),vaargs,PRIMITIVETYPE_DOUBLE);
        va_end(vaargs);
        return ret;
 
@@ -1841,7 +1611,7 @@ jdouble CallNonvirtualDoubleMethod (JNIEnv *env, jobject obj, jclass clazz, jmet
 jdouble CallNonvirtualDoubleMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
 {
 /*     log_text("JNI-Call: CallNonvirtualDoubleMethodV");*/
-       return callFloatMethod(obj,get_nonvirtual(clazz,methodID),args,'D');
+       return callFloatMethod(obj,get_nonvirtual(clazz,methodID),args,PRIMITIVETYPE_DOUBLE);
 }
 
 
@@ -1861,7 +1631,7 @@ void CallNonvirtualVoidMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID
 /*      log_text("JNI-Call: CallNonvirtualVoidMethod");*/
 
         va_start(vaargs,methodID);
-        (void)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'V',vaargs);
+        (void)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),TYPE_VOID,vaargs);
         va_end(vaargs);
 
 }
@@ -1871,7 +1641,7 @@ void CallNonvirtualVoidMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodI
 {
 /*     log_text("JNI-Call: CallNonvirtualVoidMethodV");*/
 
-        (void)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'V',args);
+        (void)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),TYPE_VOID,args);
 
 }
 
@@ -2116,7 +1886,7 @@ jboolean CallStaticBooleanMethod(JNIEnv *env, jclass clazz, jmethodID methodID,
        va_list vaargs;
 
        va_start(vaargs, methodID);
-       ret = (jboolean) callIntegerMethod(0, methodID, 'Z', vaargs);
+       ret = (jboolean) callIntegerMethod(0, methodID, PRIMITIVETYPE_BOOLEAN, vaargs);
        va_end(vaargs);
 
        return ret;
@@ -2125,7 +1895,7 @@ jboolean CallStaticBooleanMethod(JNIEnv *env, jclass clazz, jmethodID methodID,
 
 jboolean CallStaticBooleanMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
 {
-       return (jboolean) callIntegerMethod(0, methodID, 'Z', args);
+       return (jboolean) callIntegerMethod(0, methodID, PRIMITIVETYPE_BOOLEAN, args);
 }
 
 
@@ -2145,7 +1915,7 @@ jbyte CallStaticByteMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
        /*      log_text("JNI-Call: CallStaticByteMethod");*/
 
        va_start(vaargs, methodID);
-       ret = (jbyte) callIntegerMethod(0, methodID, 'B', vaargs);
+       ret = (jbyte) callIntegerMethod(0, methodID, PRIMITIVETYPE_BYTE, vaargs);
        va_end(vaargs);
 
        return ret;
@@ -2154,7 +1924,7 @@ jbyte CallStaticByteMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
 
 jbyte CallStaticByteMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
 {
-       return (jbyte) callIntegerMethod(0, methodID, 'B', args);
+       return (jbyte) callIntegerMethod(0, methodID, PRIMITIVETYPE_BYTE, args);
 }
 
 
@@ -2174,7 +1944,7 @@ jchar CallStaticCharMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
        /*      log_text("JNI-Call: CallStaticByteMethod");*/
 
        va_start(vaargs, methodID);
-       ret = (jchar) callIntegerMethod(0, methodID, 'C', vaargs);
+       ret = (jchar) callIntegerMethod(0, methodID, PRIMITIVETYPE_CHAR, vaargs);
        va_end(vaargs);
 
        return ret;
@@ -2183,7 +1953,7 @@ jchar CallStaticCharMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
 
 jchar CallStaticCharMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
 {
-       return (jchar) callIntegerMethod(0, methodID, 'C', args);
+       return (jchar) callIntegerMethod(0, methodID, PRIMITIVETYPE_CHAR, args);
 }
 
 
@@ -2204,7 +1974,7 @@ jshort CallStaticShortMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
        /*      log_text("JNI-Call: CallStaticByteMethod");*/
 
        va_start(vaargs, methodID);
-       ret = (jshort) callIntegerMethod(0, methodID, 'S', vaargs);
+       ret = (jshort) callIntegerMethod(0, methodID, PRIMITIVETYPE_SHORT, vaargs);
        va_end(vaargs);
 
        return ret;
@@ -2214,7 +1984,7 @@ jshort CallStaticShortMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
 jshort CallStaticShortMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
 {
        /*log_text("JNI-Call: CallStaticShortMethodV");*/
-       return (jshort) callIntegerMethod(0, methodID, 'S', args);
+       return (jshort) callIntegerMethod(0, methodID, PRIMITIVETYPE_SHORT, args);
 }
 
 
@@ -2235,7 +2005,7 @@ jint CallStaticIntMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
        /*      log_text("JNI-Call: CallStaticIntMethod");*/
 
        va_start(vaargs, methodID);
-       ret = callIntegerMethod(0, methodID, 'I', vaargs);
+       ret = callIntegerMethod(0, methodID, PRIMITIVETYPE_INT, vaargs);
        va_end(vaargs);
 
        return ret;
@@ -2246,7 +2016,7 @@ jint CallStaticIntMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list
 {
        log_text("JNI-Call: CallStaticIntMethodV");
 
-       return callIntegerMethod(0, methodID, 'I', args);
+       return callIntegerMethod(0, methodID, PRIMITIVETYPE_INT, args);
 }
 
 
@@ -2299,7 +2069,7 @@ jfloat CallStaticFloatMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
        /*      log_text("JNI-Call: CallStaticLongMethod");*/
 
        va_start(vaargs, methodID);
-       ret = callFloatMethod(0, methodID, vaargs, 'F');
+       ret = callFloatMethod(0, methodID, vaargs, PRIMITIVETYPE_FLOAT);
        va_end(vaargs);
 
        return ret;
@@ -2309,7 +2079,7 @@ jfloat CallStaticFloatMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
 jfloat CallStaticFloatMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
 {
 
-       return callFloatMethod(0, methodID, args, 'F');
+       return callFloatMethod(0, methodID, args, PRIMITIVETYPE_FLOAT);
 
 }
 
@@ -2331,7 +2101,7 @@ jdouble CallStaticDoubleMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ..
        /*      log_text("JNI-Call: CallStaticDoubleMethod");*/
 
        va_start(vaargs,methodID);
-       ret = callFloatMethod(0, methodID, vaargs, 'D');
+       ret = callFloatMethod(0, methodID, vaargs, PRIMITIVETYPE_DOUBLE);
        va_end(vaargs);
 
        return ret;
@@ -2342,7 +2112,7 @@ jdouble CallStaticDoubleMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, v
 {
        log_text("JNI-Call: CallStaticDoubleMethodV");
 
-       return callFloatMethod(0, methodID, args, 'D');
+       return callFloatMethod(0, methodID, args, PRIMITIVETYPE_DOUBLE);
 }
 
 
@@ -2359,7 +2129,7 @@ void CallStaticVoidMethod(JNIEnv *env, jclass cls, jmethodID methodID, ...)
        va_list vaargs;
 
        va_start(vaargs, methodID);
-       (void) callIntegerMethod(0, methodID, 'V', vaargs);
+       (void) callIntegerMethod(0, methodID, TYPE_VOID, vaargs);
        va_end(vaargs);
 }
 
@@ -2367,7 +2137,7 @@ void CallStaticVoidMethod(JNIEnv *env, jclass cls, jmethodID methodID, ...)
 void CallStaticVoidMethodV(JNIEnv *env, jclass cls, jmethodID methodID, va_list args)
 {
        log_text("JNI-Call: CallStaticVoidMethodV");
-       (void)callIntegerMethod(0, methodID, 'V', args);
+       (void)callIntegerMethod(0, methodID, TYPE_VOID, args);
 }
 
 
@@ -3873,7 +3643,7 @@ jobject *jni_method_invokeNativeHelper(JNIEnv *env, struct methodinfo *methodID,
 {
        int argcount;
        jni_callblock *blk;
-       char retT;
+       int retT;
        jobject retVal;
 
        if (methodID == 0) {
@@ -3881,7 +3651,7 @@ jobject *jni_method_invokeNativeHelper(JNIEnv *env, struct methodinfo *methodID,
                return NULL;
        }
 
-       argcount = get_parametercount(methodID);
+       argcount = methodID->parseddesc->paramcount;
 
        /* the method is an instance method the obj has to be an instance of the 
           class the method belongs to. For static methods the obj parameter
@@ -3924,10 +3694,11 @@ jobject *jni_method_invokeNativeHelper(JNIEnv *env, struct methodinfo *methodID,
 
        blk = MNEW(jni_callblock, /*4 */argcount+2);
 
-       retT = fill_callblock_objA(obj, methodID->descriptor, blk, params);
+       if (!fill_callblock_objA(obj, methodID->parseddesc, blk, params,&retT))
+               return 0; /* exception */
 
        switch (retT) {
-       case 'V':
+       case TYPE_VOID:
                (void) asm_calljavafunction2(methodID,
                                                                         argcount + 1,
                                                                         (argcount + 1) * sizeof(jni_callblock),
@@ -3935,7 +3706,7 @@ jobject *jni_method_invokeNativeHelper(JNIEnv *env, struct methodinfo *methodID,
                retVal = NULL; /*native_new_and_init(loader_load(utf_new_char("java/lang/Void")));*/
                break;
 
-       case 'I': {
+       case PRIMITIVETYPE_INT: {
                s4 intVal;
                intVal = asm_calljavafunction2int(methodID,
                                                                                  argcount + 1,
@@ -3951,7 +3722,7 @@ jobject *jni_method_invokeNativeHelper(JNIEnv *env, struct methodinfo *methodID,
        }
        break;
 
-       case 'B': {
+       case PRIMITIVETYPE_BYTE: {
                s4 intVal;
                intVal = asm_calljavafunction2int(methodID,
                                                                                  argcount + 1,
@@ -3967,7 +3738,7 @@ jobject *jni_method_invokeNativeHelper(JNIEnv *env, struct methodinfo *methodID,
        }
        break;
 
-       case 'C': {
+       case PRIMITIVETYPE_CHAR: {
                s4 intVal;
                intVal = asm_calljavafunction2int(methodID,
                                                                                  argcount + 1,
@@ -3983,7 +3754,7 @@ jobject *jni_method_invokeNativeHelper(JNIEnv *env, struct methodinfo *methodID,
        }
        break;
 
-       case 'S': {
+       case PRIMITIVETYPE_SHORT: {
                s4 intVal;
                intVal = asm_calljavafunction2int(methodID,
                                                                                  argcount + 1,
@@ -3999,7 +3770,7 @@ jobject *jni_method_invokeNativeHelper(JNIEnv *env, struct methodinfo *methodID,
        }
        break;
 
-       case 'Z': {
+       case PRIMITIVETYPE_BOOLEAN: {
                s4 intVal;
                intVal = asm_calljavafunction2int(methodID,
                                                                                  argcount + 1,
@@ -4031,7 +3802,7 @@ jobject *jni_method_invokeNativeHelper(JNIEnv *env, struct methodinfo *methodID,
        }
        break;
 
-       case 'F': {
+       case PRIMITIVETYPE_FLOAT: {
                jdouble floatVal;       
                floatVal = asm_calljavafunction2float(methodID,
                                                                                          argcount + 1,
@@ -4047,7 +3818,7 @@ jobject *jni_method_invokeNativeHelper(JNIEnv *env, struct methodinfo *methodID,
        }
        break;
 
-       case 'D': {
+       case PRIMITIVETYPE_DOUBLE: {
                jdouble doubleVal;
                doubleVal = asm_calljavafunction2double(methodID,
                                                                                                argcount + 1,
@@ -4063,8 +3834,7 @@ jobject *jni_method_invokeNativeHelper(JNIEnv *env, struct methodinfo *methodID,
        }
        break;
 
-       case 'L': /* fall through */
-       case '[':
+       case TYPE_ADR:
                retVal = asm_calljavafunction2(methodID,
                                                                           argcount + 1,
                                                                           (argcount + 1) * sizeof(jni_callblock),