nativeLoad remove #ifdef JOWENNDEBUG
[cacao.git] / jni.c
diff --git a/jni.c b/jni.c
index 7fa8843dfedc1c63aa8ed9ee3eeba0d9f02ead49..632125e90d57f9960c4d49b438fbf9d3d073b35b 100644 (file)
--- a/jni.c
+++ b/jni.c
@@ -3,7 +3,7 @@
    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,
    Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
    R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser,
    M. Probst, S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck,
-   P. Tomsich, J. Wenninger
+   P. Tomsich, J. Wenninger, M. Platter
 
    This file is part of CACAO.
 
 
    This file is part of CACAO.
 
 
    Authors: ?
 
 
    Authors: ?
 
-   Changes: Joseph Wenninger
+   Changes: Joseph Wenninger, Martin Platter
 
 
-   $Id: jni.c 791 2003-12-16 18:49:19Z edwin $
+   $Id: jni.c 1426 2004-11-01 12:21:59Z twisti $
 
 */
 
 
 #include <string.h>
 
 */
 
 
 #include <string.h>
+#include "exceptions.h"
+#include "main.h"
 #include "jni.h"
 #include "global.h"
 #include "loader.h"
 #include "tables.h"
 #include "native.h"
 #include "builtin.h"
 #include "jni.h"
 #include "global.h"
 #include "loader.h"
 #include "tables.h"
 #include "native.h"
 #include "builtin.h"
+#include "options.h"
+#include "statistics.h"
 #include "threads/thread.h"
 #include "threads/thread.h"
-#include "toolbox/loging.h"
+#include "toolbox/logging.h"
 #include "toolbox/memory.h"
 #include "nat/java_lang_Byte.h"
 #include "nat/java_lang_Character.h"
 #include "toolbox/memory.h"
 #include "nat/java_lang_Byte.h"
 #include "nat/java_lang_Character.h"
@@ -53,7 +57,8 @@
 #include "nat/java_lang_Double.h"
 #include "nat/java_lang_Throwable.h"
 #include "jit/jit.h"
 #include "nat/java_lang_Double.h"
 #include "nat/java_lang_Throwable.h"
 #include "jit/jit.h"
-#include "asmpart.h"   
+#include "asmpart.h"
+#include "mm/boehm.h"
 #define JNI_VERSION       0x00010002
 
 
 #define JNI_VERSION       0x00010002
 
 
@@ -68,6 +73,18 @@ static utf* utf_long = 0;
 static utf* utf_float = 0;
 static utf* utf_double = 0;
 
 static utf* utf_float = 0;
 static utf* utf_double = 0;
 
+/* global reference table */
+static jobject *global_ref_table;
+
+/* jmethodID and jclass caching variables for NewGlobalRef and DeleteGlobalRef*/
+static jmethodID getmid = NULL;
+static jmethodID putmid = NULL;
+static jclass intclass = NULL;
+static jmethodID intvalue = NULL;
+static jmethodID newint = NULL;
+static jclass ihmclass = NULL;
+static jmethodID removemid = NULL;
+
 
 /********************* accessing instance-fields **********************************/
 
 
 /********************* accessing instance-fields **********************************/
 
@@ -79,38 +96,34 @@ static utf* utf_double = 0;
 
 u4 get_parametercount(methodinfo *m)
 {
 
 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     */
-    java_objectarray* result;
-    int parametercount = 0;
-   int i;
+       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);
+       /* skip '(' */
+       utf_nextu2(&utf_ptr);
 
     /* determine number of parameters */
 
     /* determine number of parameters */
-    while ( *utf_ptr != ')' ) {
-        get_type(&utf_ptr,desc_end,true);
-        parametercount++;
-    }
+       while (*utf_ptr != ')') {
+               get_type(&utf_ptr, desc_end, true);
+               parametercount++;
+       }
 
 
-    return parametercount;
+       return parametercount;
 }
 
 
 
 }
 
 
 
-void fill_callblock(void *obj,utf *descr,jni_callblock blk[], va_list data, char ret) {
-    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     */
-
+void fill_callblock(void *obj, utf *descr, jni_callblock blk[], va_list data, char ret)
+{
+    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;
     int cnt;
-
-    jdouble d;
-    jlong l;
     u4 dummy;
     char c;
     u4 dummy;
     char c;
+
        /*
     log_text("fill_callblock");
     utf_display(descr);
        /*
     log_text("fill_callblock");
     utf_display(descr);
@@ -120,98 +133,105 @@ void fill_callblock(void *obj,utf *descr,jni_callblock blk[], va_list data, char
     utf_nextu2(utf_ptr);
 
     /* determine number of parameters */
     utf_nextu2(utf_ptr);
 
     /* determine number of parameters */
-   if (obj) {
-          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)
+       if (obj) {
+               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");
 
                panic("illegal method descriptor");
 
-       switch (utf_nextu2(utf_ptr)) {
-       /* primitive types */
-             case 'B' :
-             case 'C' :
-             case 'S' : 
-             case 'Z' :
-                        blk[cnt].itemtype=TYPE_INT;
-                        blk[cnt].item=(u8) va_arg(data,int);
-                        break;
-             case 'I' :
-                        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' : 
-                        blk[cnt].itemtype=TYPE_LNG;
-                        blk[cnt].item=(u8)va_arg(data,jlong);
-                                break;
-             case 'F' : 
-                        blk[cnt].itemtype=TYPE_FLT;
-                        *((jfloat*)(&blk[cnt].item))=((jfloat)va_arg(data,jdouble));
-                        break;
-
-             case 'D' : 
-                        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;
-                               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)!=';') {}
-                                   }
+               switch (utf_nextu2(utf_ptr)) {
+                       /* primitive types */
+               case 'B':
+               case 'C':
+               case 'S': 
+               case 'Z':
+                       blk[cnt].itemtype = TYPE_INT;
+                       blk[cnt].item = (u8) va_arg(data, int);
+                       break;
+
+               case 'I':
+                       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':
+                       blk[cnt].itemtype = TYPE_LNG;
+                       blk[cnt].item = (u8) va_arg(data, jlong);
+                       break;
+
+               case 'F':
+                       blk[cnt].itemtype = TYPE_FLT;
+                       *((jfloat *) (&blk[cnt].item)) = (jfloat) va_arg(data, jdouble);
+                       break;
+
+               case 'D':
+                       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;
+                       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;                      
-                        }
+                               ch = utf_nextu2(utf_ptr);
+                               blk[cnt].itemtype = TYPE_ADR;
+                               blk[cnt].item = PTR_TO_ITEM(va_arg(data, void*));
+                               break;                  
+                       }
+               }
+               cnt++;
        }
        }
-       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) log_text("\n====\nWarning call*Method called for function with wrong return type\n====");
 
 
+       /*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)
+               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)
 {
 /* 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)
 {
-    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     */
+    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;
 
     jobject param;
     int cnt;
     int cnts;
-
-    u4 dummy;
     char c;
     char c;
-    char *cp;
+
+#if defined(USE_THREADS) && !defined(NATIVE_THREADS)
     intsDisable();
     intsDisable();
+#endif
        if (utf_char==0) {
                utf_char=utf_new_char("java/lang/Character");
                utf_bool=utf_new_char("java/lang/Boolean");
        if (utf_char==0) {
                utf_char=utf_new_char("java/lang/Character");
                utf_bool=utf_new_char("java/lang/Boolean");
@@ -222,7 +242,9 @@ char fill_callblock_objA(void *obj, utf *descr, jni_callblock blk[], java_object
                utf_float=utf_new_char("java/lang/Float");
                utf_double=utf_new_char("java/lang/Double");
        }
                utf_float=utf_new_char("java/lang/Float");
                utf_double=utf_new_char("java/lang/Double");
        }
+#if defined(USE_THREADS) && !defined(NATIVE_THREADS)
     intsRestore();
     intsRestore();
+#endif
 
        /*
          log_text("fill_callblock");
 
        /*
          log_text("fill_callblock");
@@ -242,194 +264,213 @@ char fill_callblock_objA(void *obj, utf *descr, jni_callblock blk[], java_object
                cnt = 0;
        }
 
                cnt = 0;
        }
 
-       cnts=0;
+       cnts = 0;
        while (**utf_ptr != ')') {
                if (*utf_ptr >= desc_end)
                panic("illegal method descriptor");
 
                /* primitive types */
                switch (utf_nextu2(utf_ptr)) {
        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=native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
-                                       return 0;
-                               }
-                               if (param->vftbl->class->name==utf_byte) {
-                                       blk[cnt].itemtype=TYPE_INT;
-                                       blk[cnt].item = (u8) ((struct java_lang_Byte * )param)->value;
-                               } else  {
-                                       exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
-                                       return 0;
-                               }
-                               break;
+               case 'B':
+                       param = params->data[cnts];
+                       if (param == 0) {
+                               *exceptionptr = new_exception("java/lang/IllegalArgumentException");
+                               return 0;
+                       }
+                       if (param->vftbl->class->name == utf_byte) {
+                               blk[cnt].itemtype = TYPE_INT;
+                               blk[cnt].item = (u8) ((java_lang_Byte *) param)->value;
+
+                       } else  {
+                               *exceptionptr = new_exception("java/lang/IllegalArgumentException");
+                               return 0;
+                       }
+                       break;
+
                case 'C':
                case 'C':
-                               param=params->data[cnts];
-                               if (param==0) {
-                                       exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
-                                       return 0;
-                               }
-                               if (param->vftbl->class->name==utf_char) {
-                                       blk[cnt].itemtype=TYPE_INT;
-                                       blk[cnt].item = (u8) ((struct java_lang_Character * )param)->value;
-                               } else  {
-                                       exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
-                                       return 0;
-                               }
-                               break;
+                       param = params->data[cnts];
+                       if (param == 0) {
+                               *exceptionptr = new_exception("java/lang/IllegalArgumentException");
+                               return 0;
+                       }
+                       if (param->vftbl->class->name == utf_char) {
+                               blk[cnt].itemtype = TYPE_INT;
+                               blk[cnt].item = (u8) ((java_lang_Character *) param)->value;
 
 
-               case 'S': 
-                               param=params->data[cnts];
-                               if (param==0) {
-                                       exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
+                       } else  {
+                               *exceptionptr = new_exception("java/lang/IllegalArgumentException");
+                               return 0;
+                       }
+                       break;
+
+               case 'S':
+                       param = params->data[cnts];
+                       if (param == 0) {
+                               *exceptionptr = new_exception("java/lang/IllegalArgumentException");
+                               return 0;
+                       }
+                       if (param->vftbl->class->name == utf_short) {
+                               blk[cnt].itemtype = TYPE_INT;
+                               blk[cnt].item = (u8) ((java_lang_Short *) param)->value;
+
+                       } else  {
+                               if (param->vftbl->class->name == utf_byte) {
+                                       blk[cnt].itemtype = TYPE_INT;
+                                       blk[cnt].item = (u8) ((java_lang_Byte *) param)->value;
+
+                               } else {
+                                       *exceptionptr = new_exception("java/lang/IllegalArgumentException");
                                        return 0;
                                }
                                        return 0;
                                }
-                               if (param->vftbl->class->name==utf_short) {
-                                       blk[cnt].itemtype=TYPE_INT;
-                                       blk[cnt].item = (u8) ((struct java_lang_Short* )param)->value;
+                       }
+                       break;
+
+               case 'Z':
+                       param = params->data[cnts];
+                       if (param == 0) {
+                               *exceptionptr = new_exception("java/lang/IllegalArgumentException");
+                               return 0;
+                       }
+                       if (param->vftbl->class->name == utf_bool) {
+                               blk[cnt].itemtype = TYPE_INT;
+                               blk[cnt].item = (u8) ((java_lang_Boolean *) param)->value;
+
+                       } else {
+                               *exceptionptr = new_exception("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("java/lang/IllegalArgumentException");
+                               return 0;
+                       }
+                       if (param->vftbl->class->name == utf_int) {
+                               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_short) {
+                                       blk[cnt].itemtype = TYPE_INT;
+                                       blk[cnt].item = (u8) ((java_lang_Short *) param)->value;
+
                                } else  {
                                } else  {
-                                       if (param->vftbl->class->name==utf_byte) {
-                                               blk[cnt].itemtype=TYPE_INT;
-                                               blk[cnt].item = (u8) ((struct java_lang_Byte * )param)->value;
-                                       } else {
-                                               exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
+                                       if (param->vftbl->class->name == utf_byte) {
+                                               blk[cnt].itemtype = TYPE_INT;
+                                               blk[cnt].item = (u8) ((java_lang_Byte *) param)->value;
+
+                                       } else  {
+                                               *exceptionptr = new_exception("java/lang/IllegalArgumentException");
                                                return 0;
                                        }
                                }
                                                return 0;
                                        }
                                }
-                               break;
+                       }
+                       break;
 
 
-               case 'Z':
-                               param=params->data[cnts];
-                               if (param==0) {
-                                       exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
-                                       return 0;
-                               }
-                               if (param->vftbl->class->name==utf_bool) {
-                                       blk[cnt].itemtype=TYPE_INT;
-                                       blk[cnt].item = (u8) ((struct java_lang_Boolean * )param)->value;
-                               } else  {
-                                       exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
-                                       return 0;
-                               }
-                               break;
+               case 'J':
+                       param = params->data[cnts];
+                       if (param == 0) {
+                               *exceptionptr = new_exception("java/lang/IllegalArgumentException");
+                               return 0;
+                       }
+                       if (param->vftbl->class->name == utf_long) {
+                               blk[cnt].itemtype = TYPE_LNG;
+                               blk[cnt].item = (u8) ((java_lang_Long *) param)->value;
+
+                       } else  {
+                               if (param->vftbl->class->name == utf_int) {
+                                       blk[cnt].itemtype = TYPE_LNG;
+                                       blk[cnt].item = (u8) ((java_lang_Integer *) param)->value;
 
 
-               case 'I':
-                               /*log_text("fill_callblock_objA: param 'I'");*/
-                               param=params->data[cnts];
-                               if (param==0) {
-                                       exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
-                                       return 0;
-                               }
-                               if (param->vftbl->class->name==utf_int) {
-                                       blk[cnt].itemtype=TYPE_INT;
-                                       blk[cnt].item = (u8) ((struct java_lang_Integer * )param)->value;
-                                       /*printf("INT VALUE :%d\n",((struct java_lang_Integer * )param)->value);*/
                                } else {
                                } else {
-                                       if (param->vftbl->class->name==utf_short) {
-                                               blk[cnt].itemtype=TYPE_INT;
-                                               blk[cnt].item = (u8) ((struct java_lang_Short* )param)->value;
-                                       } else  {
-                                               if (param->vftbl->class->name==utf_byte) {
-                                                       blk[cnt].itemtype=TYPE_INT;
-                                                       blk[cnt].item = (u8) ((struct java_lang_Byte * )param)->value;
+                                       if (param->vftbl->class->name == utf_short) {
+                                               blk[cnt].itemtype = TYPE_LNG;
+                                               blk[cnt].item = (u8) ((java_lang_Short *) param)->value;
 
 
+                                       } else  {
+                                               if (param->vftbl->class->name == utf_byte) {
+                                                       blk[cnt].itemtype = TYPE_LNG;
+                                                       blk[cnt].item = (u8) ((java_lang_Byte *) param)->value;
                                                } else  {
                                                } else  {
-                                                       exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
+                                                       *exceptionptr = new_exception("java/lang/IllegalArgumentException");
                                                        return 0;
                                                }
                                        }
                                }
                                                        return 0;
                                                }
                                        }
                                }
-                               break;
-               case 'J':
-                               param=params->data[cnts];
-                               if (param==0) {
-                                       exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
-                                       return 0;
-                               }
-                               if (param->vftbl->class->name==utf_long) {
-                                       blk[cnt].itemtype=TYPE_LNG;
-                                       blk[cnt].item = (u8) ((struct java_lang_Long * )param)->value;
-                               } else  {
-                                       if (param->vftbl->class->name==utf_int) {
-                                               blk[cnt].itemtype=TYPE_LNG;
-                                               blk[cnt].item = (u8) ((struct java_lang_Integer * )param)->value;
-                                       } else {
-                                               if (param->vftbl->class->name==utf_short) {
-                                                       blk[cnt].itemtype=TYPE_LNG;
-                                                       blk[cnt].item = (u8) ((struct java_lang_Short* )param)->value;
-                                               } else  {
-                                                       if (param->vftbl->class->name==utf_byte) {
-                                                               blk[cnt].itemtype=TYPE_LNG;
-                                                               blk[cnt].item = (u8) ((struct java_lang_Byte * )param)->value;
-                                                       } else  {
-                                                               exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
-                                                               return 0;
-                                                       }
-                                               }
-                                       }
 
 
-                               }
-                               break;
+                       }
+                       break;
 
 
-               case 'F' : 
-                               param=params->data[cnts];
-                               if (param==0) {
-                                       exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
-                                       return 0;
-                               }
+               case 'F':
+                       param = params->data[cnts];
+                       if (param == 0) {
+                               *exceptionptr = new_exception("java/lang/IllegalArgumentException");
+                               return 0;
+                       }
+
+                       if (param->vftbl->class->name == utf_float) {
+                               blk[cnt].itemtype = TYPE_FLT;
+                               *((jfloat *) (&blk[cnt].item)) = (jfloat) ((java_lang_Float *) param)->value;
+
+                       } else  {
+                               *exceptionptr = new_exception("java/lang/IllegalArgumentException");
+                               return 0;
+                       }
+                       break;
+
+               case 'D':
+                       param = params->data[cnts];
+                       if (param == 0) {
+                               *exceptionptr = new_exception("java/lang/IllegalArgumentException");
+                               return 0;
+                       }
+
+                       if (param->vftbl->class->name == utf_double) {
+                               blk[cnt].itemtype = TYPE_DBL;
+                               *((jdouble *) (&blk[cnt].item)) = (jdouble) ((java_lang_Float *) param)->value;
+
+                       } else  {
+                               if (param->vftbl->class->name == utf_float) {
+                                       blk[cnt].itemtype = TYPE_DBL;
+                                       *((jdouble *) (&blk[cnt].item)) = (jdouble) ((java_lang_Float *) param)->value;
 
 
-                               if (param->vftbl->class->name==utf_float) {
-                                       blk[cnt].itemtype=TYPE_FLT;
-                                       *((jfloat*)(&blk[cnt].item))=(jfloat) ((struct java_lang_Float*)param)->value;
                                } else  {
                                } else  {
-                                       exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
-                                       return 0;
-                               }
-                               break;
-               case 'D' : 
-                               param=params->data[cnts];
-                               if (param==0) {
-                                       exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
+                                       *exceptionptr = new_exception("java/lang/IllegalArgumentException");
                                        return 0;
                                }
                                        return 0;
                                }
+                       }
+                       break;
 
 
-                               if (param->vftbl->class->name==utf_double) {
-                                       blk[cnt].itemtype=TYPE_DBL;
-                                       *((jdouble*)(&blk[cnt].item))=(jdouble) ((struct java_lang_Float*)param)->value;
-                               } else  {
-                                       if (param->vftbl->class->name==utf_float) {
-                                               blk[cnt].itemtype=TYPE_DBL;
-                                               *((jdouble*)(&blk[cnt].item))=(jdouble) ((struct java_lang_Float*)param)->value;
-                                       } else  {
-                                               exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
-                                               return 0;
-                                       }
-                               }
-                               break;
                case 'V':
                        panic("V not allowed as function parameter");
                        break;
 
                case 'V':
                        panic("V not allowed as function parameter");
                        break;
 
-               case 'L': {
-                               char *start=(*utf_ptr)-1;
-                               char *end;
+               case 'L':
+                       {
+                               char *start = (*utf_ptr) - 1;
+                               char *end = NULL;
 
                                while (utf_nextu2(utf_ptr) != ';')
 
                                while (utf_nextu2(utf_ptr) != ';')
-                               end=(*utf_ptr)+1;
-                               if (!builtin_instanceof(params->data[cnts],class_from_descriptor(start,end,0,CLASSLOAD_LOAD))) {
-                                       if (params->data[cnts]!=0) {
-                                               exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
+                                       end = (*utf_ptr) + 1;
+
+                               if (!builtin_instanceof(params->data[cnts], class_from_descriptor(start, end, 0, CLASSLOAD_LOAD))) {
+                                       if (params->data[cnts] != 0) {
+                                               *exceptionptr = new_exception("java/lang/IllegalArgumentException");
                                                return 0;
                                        }                       
                                }
                                                return 0;
                                        }                       
                                }
-                               blk[cnt].itemtype = TYPE_ADR;
-                               blk[cnt].item= PTR_TO_ITEM(params->data[cnts]);
+
+                               blk[cnt].itemtype = TYPE_ADR;
+                               blk[cnt].item = PTR_TO_ITEM(params->data[cnts]);
                                break;                  
                                break;                  
+                       }
 
 
-                         }
-               case '[' :
+               case '[':
                        {
                        {
-                               char *start=(*utf_ptr)-1;
+                               char *start = (*utf_ptr) - 1;
                                char *end;
 
                                char ch;
                                char *end;
 
                                char ch;
@@ -437,12 +478,13 @@ char fill_callblock_objA(void *obj, utf *descr, jni_callblock blk[], java_object
                                        if (ch == 'L') {
                                                while (utf_nextu2(utf_ptr) != ';') {}
                                        }
                                        if (ch == 'L') {
                                                while (utf_nextu2(utf_ptr) != ';') {}
                                        }
-                               end=(*utf_ptr)-1;
+
+                               end = (*utf_ptr) - 1;
                                ch = utf_nextu2(utf_ptr);
                                ch = utf_nextu2(utf_ptr);
-                               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")));
+
+                               if (!builtin_arrayinstanceof(params->data[cnts], class_from_descriptor(start, end, 0, CLASSLOAD_LOAD)->vftbl)) {
+                                       *exceptionptr = new_exception("java/lang/IllegalArgumentException");
                                        return 0;
                                        return 0;
-                                       
                                }
        
                                blk[cnt].itemtype = TYPE_ADR;
                                }
        
                                blk[cnt].itemtype = TYPE_ADR;
@@ -480,6 +522,7 @@ jmethodID get_virtual(jobject obj,jmethodID methodID) {
 
 jmethodID get_nonvirtual(jclass clazz,jmethodID methodID) {
        if (clazz==methodID->class) return methodID;
 
 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);
 }
 
        return class_resolvemethod (clazz, methodID->name, methodID->descriptor);
 }
 
@@ -491,17 +534,10 @@ jobject callObjectMethod (jobject obj, jmethodID methodID, va_list args)
        jni_callblock *blk;
        jobject ret;
 
        jni_callblock *blk;
        jobject ret;
 
-       /*
-         log_text("JNI-Call: CallObjectMethodV");
-         utf_display(methodID->name);
-         utf_display(methodID->descriptor);
-         printf("\nParmaeter count: %d\n",argcount);
-         utf_display(obj->vftbl->class->name);
-         printf("\n");
-       */
+
 
        if (methodID == 0) {
 
        if (methodID == 0) {
-               exceptionptr = native_new_and_init(class_java_lang_NoSuchMethodError); 
+               *exceptionptr = new_exception(string_java_lang_NoSuchMethodError); 
                return 0;
        }
 
                return 0;
        }
 
@@ -509,33 +545,35 @@ jobject callObjectMethod (jobject obj, jmethodID methodID, va_list args)
 
        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);
+               *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
                return 0;
        }
                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);
+               *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
                return 0;
        }
 
                return 0;
        }
 
+#ifdef arglimit
+
        if (argcount > 3) {
        if (argcount > 3) {
-               exceptionptr = native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
+               *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
                log_text("Too many arguments. CallObjectMethod does not support that");
                return 0;
        }
                log_text("Too many arguments. CallObjectMethod does not support that");
                return 0;
        }
+#endif
 
        blk = MNEW(jni_callblock, 4 /*argcount+2*/);
 
        fill_callblock(obj, methodID->descriptor, blk, args, 'O');
 
        blk = MNEW(jni_callblock, 4 /*argcount+2*/);
 
        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);
        /*      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);
        /*      printf("(CallObjectMethodV)-->%p\n",ret); */
        MFREE(blk, jni_callblock, argcount + 1);
        /*      printf("(CallObjectMethodV)-->%p\n",ret); */
+
        return ret;
 }
 
        return ret;
 }
 
@@ -561,7 +599,7 @@ jint callIntegerMethod(jobject obj, jmethodID methodID, char retType, va_list ar
         printf("\n");
         */
        if (methodID == 0) {
         printf("\n");
         */
        if (methodID == 0) {
-               exceptionptr = native_new_and_init(class_java_lang_NoSuchMethodError); 
+               *exceptionptr = new_exception(string_java_lang_NoSuchMethodError); 
                return 0;
        }
         
                return 0;
        }
         
@@ -569,21 +607,22 @@ jint callIntegerMethod(jobject obj, jmethodID methodID, char retType, va_list ar
 
        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);
+               *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
                return 0;
        }
 
        if (obj && !builtin_instanceof(obj, methodID->class)) {
                return 0;
        }
 
        if (obj && !builtin_instanceof(obj, methodID->class)) {
-               exceptionptr = native_new_and_init(class_java_lang_NoSuchMethodError);
+               *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
                return 0;
        }
 
                return 0;
        }
 
-
+#ifdef arglimit
        if (argcount > 3) {
        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");
+               *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
+               log_text("Too many arguments. CallIntegerMethod does not support that");
                return 0;
        }
                return 0;
        }
+#endif
 
        blk = MNEW(jni_callblock, 4 /*argcount+2*/);
 
 
        blk = MNEW(jni_callblock, 4 /*argcount+2*/);
 
@@ -609,16 +648,16 @@ jlong callLongMethod(jobject obj, jmethodID methodID, va_list args)
        jni_callblock *blk;
        jlong ret;
 
        jni_callblock *blk;
        jlong ret;
 
-       /*
+/*     
         log_text("JNI-Call: CallObjectMethodV");
         utf_display(methodID->name);
         utf_display(methodID->descriptor);
         printf("\nParmaeter count: %d\n",argcount);
         utf_display(obj->vftbl->class->name);
         printf("\n");
         log_text("JNI-Call: CallObjectMethodV");
         utf_display(methodID->name);
         utf_display(methodID->descriptor);
         printf("\nParmaeter count: %d\n",argcount);
         utf_display(obj->vftbl->class->name);
         printf("\n");
-        */
+*/      
        if (methodID == 0) {
        if (methodID == 0) {
-               exceptionptr = native_new_and_init(class_java_lang_NoSuchMethodError); 
+               *exceptionptr = new_exception(string_java_lang_NoSuchMethodError); 
                return 0;
        }
 
                return 0;
        }
 
@@ -626,25 +665,26 @@ jlong callLongMethod(jobject obj, jmethodID methodID, va_list args)
 
        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);
+               *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
                return 0;
        }
 
        if (obj && !builtin_instanceof(obj,methodID->class)) {
                return 0;
        }
 
        if (obj && !builtin_instanceof(obj,methodID->class)) {
-               exceptionptr = native_new_and_init(class_java_lang_NoSuchMethodError);
+               *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
                return 0;
        }
 
                return 0;
        }
 
-
+#ifdef arglimit
        if (argcount > 3) {
        if (argcount > 3) {
-               exceptionptr = native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
+               *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
                log_text("Too many arguments. CallObjectMethod does not support that");
                return 0;
        }
                log_text("Too many arguments. CallObjectMethod does not support that");
                return 0;
        }
+#endif
 
        blk = MNEW(jni_callblock, 4 /*argcount+2*/);
 
 
        blk = MNEW(jni_callblock, 4 /*argcount+2*/);
 
-       fill_callblock(obj, methodID->descriptor, blk, args, 'L');
+       fill_callblock(obj, methodID->descriptor, blk, args, 'J');
 
        /*      printf("parameter: obj: %p",blk[0].item); */
        ret = asm_calljavafunction2long(methodID,
 
        /*      printf("parameter: obj: %p",blk[0].item); */
        ret = asm_calljavafunction2long(methodID,
@@ -675,11 +715,13 @@ jdouble callFloatMethod(jobject obj, jmethodID methodID, va_list args,char retTy
         printf("\n");
         */
 
         printf("\n");
         */
 
+#ifdef arglimit
        if (argcount > 3) {
        if (argcount > 3) {
-               exceptionptr = native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
+               *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
                log_text("Too many arguments. CallObjectMethod does not support that");
                return 0;
        }
                log_text("Too many arguments. CallObjectMethod does not support that");
                return 0;
        }
+#endif
 
        blk = MNEW(jni_callblock, 4 /*argcount+2*/);
 
 
        blk = MNEW(jni_callblock, 4 /*argcount+2*/);
 
@@ -731,48 +773,88 @@ jint GetVersion (JNIEnv* env)
        return JNI_VERSION;
 }
 
        return JNI_VERSION;
 }
 
-/****************** loads a class from a buffer of raw class data *****************/
+
+/************** loads a class from a buffer of raw class data *****************/
 
 jclass DefineClass(JNIEnv* env, const char *name, jobject loader, const jbyte *buf, jsize len) 
 {
 
 jclass DefineClass(JNIEnv* env, const char *name, jobject loader, const jbyte *buf, jsize len) 
 {
-        jclass clazz; 
+       jclass c; 
+       jclass r;
+       classbuffer *cb;
+
+       c = class_new(utf_new_char_classname((char *) name));
+
+       /* enter a monitor on the class */
+
+       builtin_monitorenter((java_objectheader *) c);
+
+       /* measure time */
+       if (getloadingtime)
+               loadingtime_start();
+
+       /* build a classbuffer with the given data */
+       cb = NEW(classbuffer);
+       cb->class = c;
+       cb->size = len;
+       cb->data = (u1 *) buf;
+       cb->pos = cb->data - 1;
+
+       r = class_load_intern(cb);
+
+       /* if return value is NULL, we had a problem and the class is not loaded */
+       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);
+
+       /* measure time */
+       if (getloadingtime)
+               loadingtime_stop();
 
 
-       /* change suck-mode, so subsequent class_load will read from memory-buffer */
-       classload_buffer( (u1*) buf,len);
+       /* leave the monitor */
 
 
-        clazz = loader_load(utf_new_char ((char *) name));
+       builtin_monitorexit((java_objectheader *) c);
 
 
-       /* restore old suck-mode */
-       classload_buffer(NULL,0);
+       /* XXX link the class here? */
+/*     if (class_link(c)) */
+/*             return NULL; */
 
 
-       return clazz;
+       if (r)
+               c->classloader = loader;
+
+       return r;
 }
 
 
 }
 
 
-/*************** loads locally defined class with the specified name **************/
+/*********** loads locally defined class with the specified name **************/
 
 
-jclass FindClass (JNIEnv* env, const char *name) 
+jclass FindClass(JNIEnv* env, const char *name) 
 {
        classinfo *c;  
   
 {
        classinfo *c;  
   
-/*     if (strcmp(name,"[B")==0) {
-               c = loader_load(utf_new_char("The_Array_Class"));
-       }
-       else*/
-               c = loader_load(utf_new_char_classname ((char *) name));
+       c = class_new(utf_new_char_classname((char *) name));
 
 
-       if (!c) exceptionptr = native_new_and_init(class_java_lang_ClassFormatError);
+       if (!class_load(c))
+               return NULL;
+
+       if (!class_link(c))
+               return NULL;
 
        return c;
 }
   
 
 
        return c;
 }
   
 
-/*********************************************************************************** 
+/*******************************************************************************
 
        converts java.lang.reflect.Method or 
        java.lang.reflect.Constructor object to a method ID  
   
 
        converts java.lang.reflect.Method or 
        java.lang.reflect.Constructor object to a method ID  
   
- **********************************************************************************/   
+*******************************************************************************/
   
 jmethodID FromReflectedMethod(JNIEnv* env, jobject method)
 {
   
 jmethodID FromReflectedMethod(JNIEnv* env, jobject method)
 {
@@ -820,47 +902,48 @@ jobject ToReflectedField(JNIEnv* env, jclass cls, jfieldID fieldID, jboolean isS
 
 jint Throw(JNIEnv* env, jthrowable obj)
 {
 
 jint Throw(JNIEnv* env, jthrowable obj)
 {
-       exceptionptr = (java_objectheader*) obj;
+       *exceptionptr = (java_objectheader*) obj;
 
        return 0;
 }
 
 
 
        return 0;
 }
 
 
-/*********************************************************************************** 
+/*******************************************************************************
 
        create exception object from the class clazz with the 
        specified message and cause it to be thrown
 
 
        create exception object from the class clazz with the 
        specified message and cause it to be thrown
 
- **********************************************************************************/   
-
+*******************************************************************************/
 
 
-jint ThrowNew (JNIEnv* env, jclass clazz, const char *msg) 
+jint ThrowNew(JNIEnv* env, jclass clazz, const char *msg) 
 {
        java_lang_Throwable *o;
 
        /* instantiate exception object */
 {
        java_lang_Throwable *o;
 
        /* instantiate exception object */
-       o = (java_lang_Throwable *) native_new_and_init ((classinfo*) clazz);
+       o = (java_lang_Throwable *) native_new_and_init((classinfo*) clazz);
 
        if (!o) return (-1);
 
 
        if (!o) return (-1);
 
-       o->detailMessage = (java_lang_String*) javastring_new_char((char *) msg);
+       o->detailMessage = (java_lang_String *) javastring_new_char((char *) msg);
+
+       *exceptionptr = (java_objectheader *) o;
 
 
-       exceptionptr = (java_objectheader*) o;  
        return 0;
 }
 
        return 0;
 }
 
+
 /************************* check if exception occured *****************************/
 
 jthrowable ExceptionOccurred (JNIEnv* env) 
 {
 /************************* check if exception occured *****************************/
 
 jthrowable ExceptionOccurred (JNIEnv* env) 
 {
-       return (jthrowable) exceptionptr;
+       return (jthrowable) *exceptionptr;
 }
 
 /********** print exception and a backtrace of the stack (for debugging) **********/
 
 void ExceptionDescribe (JNIEnv* env) 
 {
 }
 
 /********** print exception and a backtrace of the stack (for debugging) **********/
 
 void ExceptionDescribe (JNIEnv* env) 
 {
-       utf_display(exceptionptr->vftbl->class->name);
+       utf_display((*exceptionptr)->vftbl->class->name);
        printf ("\n");
        fflush (stdout);        
 }
        printf ("\n");
        fflush (stdout);        
 }
@@ -870,7 +953,7 @@ void ExceptionDescribe (JNIEnv* env)
 
 void ExceptionClear (JNIEnv* env) 
 {
 
 void ExceptionClear (JNIEnv* env) 
 {
-       exceptionptr = NULL;    
+       *exceptionptr = NULL;   
 }
 
 
 }
 
 
@@ -894,31 +977,18 @@ jint PushLocalFrame(JNIEnv* env, jint capacity)
 
 jobject PopLocalFrame(JNIEnv* env, jobject result)
 {
 
 jobject PopLocalFrame(JNIEnv* env, jobject result)
 {
+    log_text("JNI-Call: PopLocalFrame");
        /* empty */
 
        return NULL;
 }
        /* empty */
 
        return NULL;
 }
-    
-
-/** Creates a new global reference to the object referred to by the obj argument **/
-    
-jobject NewGlobalRef(JNIEnv* env, jobject lobj)
-{
-       return lobj;
-}
-
-/*************  Deletes the global reference pointed to by globalRef **************/
-
-void DeleteGlobalRef (JNIEnv* env, jobject gref)
-{
-       /* empty */
-}
 
 
 /*************** Deletes the local reference pointed to by localRef ***************/
 
 void DeleteLocalRef (JNIEnv* env, jobject localRef)
 {
 
 
 /*************** Deletes the local reference pointed to by localRef ***************/
 
 void DeleteLocalRef (JNIEnv* env, jobject localRef)
 {
+/*    log_text("JNI-Call: DeleteLocalRef");*/
        /* empty */
 }
 
        /* empty */
 }
 
@@ -975,12 +1045,13 @@ jobject NewObject (JNIEnv* env, jclass clazz, jmethodID methodID, ...)
 
        /* log_text("JNI-Call: NewObject"); */
 
 
        /* log_text("JNI-Call: NewObject"); */
 
-       if  (argcount>3) {
-               exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
+#ifdef arglimit
+       if (argcount > 3) {
+               *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
                log_text("Too many arguments. NewObject does not support that");
                return 0;
        }
                log_text("Too many arguments. NewObject does not support that");
                return 0;
        }
-
+#endif
        
        o = builtin_new (clazz);         /*          create object */
        
        
        o = builtin_new (clazz);         /*          create object */
        
@@ -1033,11 +1104,9 @@ jobject NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID, jvalue *args)
 jclass GetObjectClass(JNIEnv* env, jobject obj)
 {
        classinfo *c = obj->vftbl->class;
 jclass GetObjectClass(JNIEnv* env, jobject obj)
 {
        classinfo *c = obj->vftbl->class;
-/*     log_text("GetObjectClass");
-       utf_display(obj->vftbl->class->name);*/
+
        use_class_as_object(c);
 
        use_class_as_object(c);
 
-       /*printf("\nPointer: %p\n",c);*/
        return c;
 }
 
        return c;
 }
 
@@ -1087,8 +1156,11 @@ jmethodID GetMethodID(JNIEnv* env, jclass clazz, const char *name, const char *s
                utf_new_char ((char*) sig)
        );
 
                utf_new_char ((char*) sig)
        );
 
-       if (!m) exceptionptr = native_new_and_init(class_java_lang_NoSuchMethodError);          
-
+       if (!m) *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
+       else if (m->flags & ACC_STATIC)   {
+               m=0;
+               *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
+       }
        return m;
 }
 
        return m;
 }
 
@@ -1272,17 +1344,20 @@ jint CallIntMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
 
 jlong CallLongMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
 {
 
 jlong CallLongMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
 {
-       log_text("JNI-Call: CallLongMethod");
+       jlong ret;
+       va_list vaargs;
+       
+       va_start(vaargs,methodID);
+       ret = callLongMethod(obj,get_virtual(obj, methodID),vaargs);
+       va_end(vaargs);
 
 
-       return 0;
+       return ret;
 }
 
 
 jlong CallLongMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
 {
 }
 
 
 jlong CallLongMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
 {
-       log_text("JNI-Call: CallLongMethodV");
-
-       return 0;
+       return  callLongMethod(obj,get_virtual(obj, methodID),args);
 }
 
 
 }
 
 
@@ -1689,10 +1764,10 @@ jfieldID GetFieldID (JNIEnv *env, jclass clazz, const char *name, const char *si
                            ); 
        
        if (!f) { 
                            ); 
        
        if (!f) { 
-/*             utf_display(clazz->name);
+               utf_display(clazz->name);
                log_text(name);
                log_text(name);
-               log_text(sig);*/
-               exceptionptr =  native_new_and_init(class_java_lang_NoSuchFieldError);  
+               log_text(sig);
+               *exceptionptr = new_exception(string_java_lang_NoSuchFieldError);  
        }
        return f;
 }
        }
        return f;
 }
@@ -1718,7 +1793,33 @@ jfieldID getFieldID_critical(JNIEnv *env, jclass clazz, char *name, char *sig)
 
 jobject GetObjectField (JNIEnv *env, jobject obj, jfieldID fieldID)
 {
 
 jobject GetObjectField (JNIEnv *env, jobject obj, jfieldID fieldID)
 {
-       return getField(obj,jobject,fieldID);
+       jobject dbg,dretval,*dpretval;  
+       long int dli1, dli2, dli3;
+
+/*     printf("GetObjectField(1): thread: %s obj: %p name: %s desc: %s \n",GetStringUTFChars(env,
+                        ((threadobject *) THREADOBJECT)->o
+                        .thread->name,NULL)
+                        ,obj,((fieldinfo*)fieldID)->name->text,(fieldID->descriptor)->text);*/
+
+       dbg = getField(obj,jobject,fieldID);
+       dli1 = (long int) obj;
+       dli2 = (long int) fieldID->offset;
+       dli3 = dli1+dli2;
+       dpretval = (jobject*) dli3;
+       dretval = *dpretval;
+/*     jclass tmp;
+       jmethodID mid;
+       jstring jstr;
+
+       tmp = FindClass(env, "java/lang/Object");
+       mid = GetMethodID(env,tmp,"toString","()Ljava/lang/String;");
+       jstr = CallObjectMethod(env,dbg,mid);*/
+
+/*     printf("GetObjectField(2): retval %p (obj: %#lx + offset: %#lx = %#lx (jobject*) %p (jobject) %p\n"
+       ,dbg, dli1, dli2, dli3,dpretval, dretval);*/
+
+
+       return dbg;
 }
 
 jboolean GetBooleanField (JNIEnv *env, jobject obj, jfieldID fieldID)
 }
 
 jboolean GetBooleanField (JNIEnv *env, jobject obj, jfieldID fieldID)
@@ -1821,40 +1922,51 @@ void SetDoubleField (JNIEnv *env, jobject obj, jfieldID fieldID, jdouble val)
         setField(obj,jdouble,fieldID,val);
 }
 
         setField(obj,jdouble,fieldID,val);
 }
 
+
 /**************** JNI-functions for calling static methods **********************/ 
 
 /**************** JNI-functions for calling static methods **********************/ 
 
-jmethodID GetStaticMethodID (JNIEnv *env, jclass clazz, const char *name, const char *sig)
+jmethodID GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name, const char *sig)
 {
        jmethodID m;
 
 {
        jmethodID m;
 
-       m = class_resolvemethod (
-               clazz, 
-               utf_new_char ((char*) name), 
-               utf_new_char ((char*) sig)
-       );
+       m = class_resolvemethod(clazz,
+                                                       utf_new_char((char *) name),
+                                                       utf_new_char((char *) sig));
 
 
-       if (!m) exceptionptr =  native_new_and_init(class_java_lang_NoSuchMethodError);  
+       if (!m) *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
+       else if (!(m->flags & ACC_STATIC))   {
+               m=0;
+               *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
+       }
 
        return m;
 }
 
 
        return m;
 }
 
-jobject CallStaticObjectMethod (JNIEnv *env, jclass clazz, jmethodID methodID, ...)
+
+jobject CallStaticObjectMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
 {
 {
-       log_text("JNI-Call: CallStaticObjectMethod");
+       jobject ret;
+       va_list vaargs;
 
 
-       return NULL;
+       /* log_text("JNI-Call: CallStaticObjectMethod");*/
+
+       va_start(vaargs, methodID);
+       ret = callObjectMethod(0, methodID, vaargs);
+       va_end(vaargs);
+
+       return ret;
 }
 
 
 }
 
 
-jobject CallStaticObjectMethodV (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
+jobject CallStaticObjectMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
 {
 {
-       log_text("JNI-Call: CallStaticObjectMethodV");
-
-       return NULL;
+       /* log_text("JNI-Call: CallStaticObjectMethodV"); */
+       
+       return callObjectMethod(0,methodID,args);
 }
 
 
 }
 
 
-jobject CallStaticObjectMethodA (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
+jobject CallStaticObjectMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
 {
        log_text("JNI-Call: CallStaticObjectMethodA");
 
 {
        log_text("JNI-Call: CallStaticObjectMethodA");
 
@@ -1862,18 +1974,16 @@ jobject CallStaticObjectMethodA (JNIEnv *env, jclass clazz, jmethodID methodID,
 }
 
 
 }
 
 
-jboolean CallStaticBooleanMethod (JNIEnv *env, jclass clazz, jmethodID methodID, ...)
+jboolean CallStaticBooleanMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
 {
 {
-        jboolean ret;
-        va_list vaargs;
-
-/*      log_text("JNI-Call: CallStaticBooleanMethod");*/
+       jboolean ret;
+       va_list vaargs;
 
 
-        va_start(vaargs,methodID);
-        ret = (jboolean)callIntegerMethod(0,methodID,'Z',vaargs);
-        va_end(vaargs);
-        return ret;
+       va_start(vaargs, methodID);
+       ret = (jboolean) callIntegerMethod(0, methodID, 'Z', vaargs);
+       va_end(vaargs);
 
 
+       return ret;
 }
 
 
 }
 
 
@@ -1882,6 +1992,7 @@ jboolean CallStaticBooleanMethodV(JNIEnv *env, jclass clazz, jmethodID methodID,
        return (jboolean) callIntegerMethod(0, methodID, 'Z', args);
 }
 
        return (jboolean) callIntegerMethod(0, methodID, 'Z', args);
 }
 
+
 jboolean CallStaticBooleanMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
 {
        log_text("JNI-Call: CallStaticBooleanMethodA");
 jboolean CallStaticBooleanMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
 {
        log_text("JNI-Call: CallStaticBooleanMethodA");
@@ -1956,7 +2067,7 @@ jshort CallStaticShortMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
 
        /*      log_text("JNI-Call: CallStaticByteMethod");*/
 
 
        /*      log_text("JNI-Call: CallStaticByteMethod");*/
 
-       va_start(vaargs,methodID);
+       va_start(vaargs, methodID);
        ret = (jshort) callIntegerMethod(0, methodID, 'S', vaargs);
        va_end(vaargs);
 
        ret = (jshort) callIntegerMethod(0, methodID, 'S', vaargs);
        va_end(vaargs);
 
@@ -2143,7 +2254,7 @@ jfieldID GetStaticFieldID (JNIEnv *env, jclass clazz, const char *name, const ch
                            utf_new_char ((char*) sig)
                            ); 
        
                            utf_new_char ((char*) sig)
                            ); 
        
-       if (!f) exceptionptr =  native_new_and_init(class_java_lang_NoSuchFieldError);  
+       if (!f) *exceptionptr = new_exception(string_java_lang_NoSuchFieldError);  
 
        return f;
 }
 
        return f;
 }
@@ -2364,7 +2475,7 @@ void ReleaseStringChars (JNIEnv *env, jstring str, const jchar *chars)
 jstring NewStringUTF (JNIEnv *env, const char *utf)
 {
 /*    log_text("NewStringUTF called");*/
 jstring NewStringUTF (JNIEnv *env, const char *utf)
 {
 /*    log_text("NewStringUTF called");*/
-    return javastring_new(utf_new_char(utf));
+    return (jstring) javastring_new(utf_new_char((char *) utf));
 }
 
 /****************** returns the utf8 length in bytes of a string *******************/
 }
 
 /****************** returns the utf8 length in bytes of a string *******************/
@@ -2376,22 +2487,26 @@ jsize GetStringUTFLength (JNIEnv *env, jstring string)
     return (jsize) u2_utflength(s->value->data, s->count); 
 }
 
     return (jsize) u2_utflength(s->value->data, s->count); 
 }
 
+
 /************ converts a Javastring to an array of UTF-8 characters ****************/
 
 /************ converts a Javastring to an array of UTF-8 characters ****************/
 
-const char* GetStringUTFChars (JNIEnv *env, jstring string, jboolean *isCopy)
+const char* GetStringUTFChars(JNIEnv *env, jstring string, jboolean *isCopy)
 {
     utf *u;
 {
     utf *u;
-    if (verbose) log_text("GetStringUTFChars:");
 
 
-    u=javastring_toutf((java_lang_String*) string,false);
-    if (isCopy) *isCopy=JNI_FALSE;
-    if (u) {
-       return u->text;
-    }
+    u = javastring_toutf((java_lang_String *) string, false);
+
+    if (isCopy)
+               *isCopy = JNI_FALSE;
+       
+    if (u)
+               return u->text;
+
     return emptyString;
        
 }
 
     return emptyString;
        
 }
 
+
 /***************** native code no longer needs access to utf ***********************/
 
 void ReleaseStringUTFChars (JNIEnv *env, jstring str, const char* chars)
 /***************** native code no longer needs access to utf ***********************/
 
 void ReleaseStringUTFChars (JNIEnv *env, jstring str, const char* chars)
@@ -2406,45 +2521,50 @@ void ReleaseStringUTFChars (JNIEnv *env, jstring str, const char* chars)
 
 /************************** array operations ***************************************/
 
 
 /************************** array operations ***************************************/
 
-jsize GetArrayLength (JNIEnv *env, jarray array)
+jsize GetArrayLength(JNIEnv *env, jarray array)
 {
     return array->size;
 }
 
 {
     return array->size;
 }
 
+
 jobjectArray NewObjectArray (JNIEnv *env, jsize len, jclass clazz, jobject init)
 {
        java_objectarray *j;
 jobjectArray NewObjectArray (JNIEnv *env, jsize len, jclass clazz, jobject init)
 {
        java_objectarray *j;
-    if (len<0) {
-               exceptionptr=proto_java_lang_NegativeArraySizeException;
+
+    if (len < 0) {
+               *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
                return NULL;
     }
                return NULL;
     }
-    j = builtin_anewarray (len, clazz);
-    if (!j) exceptionptr = proto_java_lang_OutOfMemoryError;
+
+    j = builtin_anewarray(len, clazz);
+
     return j;
 }
 
     return j;
 }
 
-jobject GetObjectArrayElement (JNIEnv *env, jobjectArray array, jsize index)
+
+jobject GetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index)
 {
     jobject j = NULL;
 
 {
     jobject j = NULL;
 
-    if (index<array->header.size)      
-       j = array->data[index];
+    if (index < array->header.size)    
+               j = array->data[index];
     else
     else
-       exceptionptr = proto_java_lang_ArrayIndexOutOfBoundsException;
+               *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
     
     return j;
 }
 
     
     return j;
 }
 
-void SetObjectArrayElement (JNIEnv *env, jobjectArray array, jsize index, jobject val)
+
+void SetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index, jobject val)
 {
 {
-    if (index>=array->header.size)     
-       exceptionptr = proto_java_lang_ArrayIndexOutOfBoundsException;
-    else {
+    if (index >= array->header.size)
+               *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
 
 
-       /* check if the class of value is a subclass of the element class of the array */
+    else {
+               /* check if the class of value is a subclass of the element class of the array */
+               if (!builtin_canstore((java_objectarray *) array, (java_objectheader *) val))
+                       *exceptionptr = new_exception(string_java_lang_ArrayStoreException);
 
 
-               if (!builtin_canstore((java_objectarray*)array,(java_objectheader*)val))
-                       exceptionptr = proto_java_lang_ArrayStoreException;
                else
                        array->data[index] = val;
     }
                else
                        array->data[index] = val;
     }
@@ -2452,106 +2572,122 @@ void SetObjectArrayElement (JNIEnv *env, jobjectArray array, jsize index, jobjec
 
 
 
 
 
 
-jbooleanArray NewBooleanArray (JNIEnv *env, jsize len)
+jbooleanArray NewBooleanArray(JNIEnv *env, jsize len)
 {
        java_booleanarray *j;
 {
        java_booleanarray *j;
-    if (len<0) {
-               exceptionptr=proto_java_lang_NegativeArraySizeException;
+
+    if (len < 0) {
+               *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
                return NULL;
     }
                return NULL;
     }
+
     j = builtin_newarray_boolean(len);
     j = builtin_newarray_boolean(len);
-    if (!j) exceptionptr = proto_java_lang_OutOfMemoryError;
+
     return j;
 }
 
 
     return j;
 }
 
 
-jbyteArray NewByteArray (JNIEnv *env, jsize len)
+jbyteArray NewByteArray(JNIEnv *env, jsize len)
 {
        java_bytearray *j;
 {
        java_bytearray *j;
-    if (len<0) {
-               exceptionptr=proto_java_lang_NegativeArraySizeException;
+
+    if (len < 0) {
+               *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
                return NULL;
     }
                return NULL;
     }
+
     j = builtin_newarray_byte(len);
     j = builtin_newarray_byte(len);
-    if (!j) exceptionptr = proto_java_lang_OutOfMemoryError;
+
     return j;
 }
 
 
     return j;
 }
 
 
-jcharArray NewCharArray (JNIEnv *env, jsize len)
+jcharArray NewCharArray(JNIEnv *env, jsize len)
 {
        java_chararray *j;
 {
        java_chararray *j;
-    if (len<0) {
-               exceptionptr=proto_java_lang_NegativeArraySizeException;
+
+    if (len < 0) {
+               *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
                return NULL;
     }
                return NULL;
     }
+
     j = builtin_newarray_char(len);
     j = builtin_newarray_char(len);
-    if (!j) exceptionptr = proto_java_lang_OutOfMemoryError;
+
     return j;
 }
 
 
     return j;
 }
 
 
-jshortArray NewShortArray (JNIEnv *env, jsize len)
+jshortArray NewShortArray(JNIEnv *env, jsize len)
 {
        java_shortarray *j;
 {
        java_shortarray *j;
-    if (len<0) {
-               exceptionptr=proto_java_lang_NegativeArraySizeException;
+
+    if (len < 0) {
+               *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
                return NULL;
     }
                return NULL;
     }
-    j = builtin_newarray_short(len);   
-    if (!j) exceptionptr = proto_java_lang_OutOfMemoryError;
+
+    j = builtin_newarray_short(len);
+
     return j;
 }
 
 
     return j;
 }
 
 
-jintArray NewIntArray (JNIEnv *env, jsize len)
+jintArray NewIntArray(JNIEnv *env, jsize len)
 {
        java_intarray *j;
 {
        java_intarray *j;
-    if (len<0) {
-               exceptionptr=proto_java_lang_NegativeArraySizeException;
+
+    if (len < 0) {
+               *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
                return NULL;
     }
                return NULL;
     }
+
     j = builtin_newarray_int(len);
     j = builtin_newarray_int(len);
-    if (!j) exceptionptr = proto_java_lang_OutOfMemoryError;
+
     return j;
 }
 
 
     return j;
 }
 
 
-jlongArray NewLongArray (JNIEnv *env, jsize len)
+jlongArray NewLongArray(JNIEnv *env, jsize len)
 {
        java_longarray *j;
 {
        java_longarray *j;
-    if (len<0) {
-               exceptionptr=proto_java_lang_NegativeArraySizeException;
+
+    if (len < 0) {
+               *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
                return NULL;
     }
                return NULL;
     }
+
     j = builtin_newarray_long(len);
     j = builtin_newarray_long(len);
-    if (!j) exceptionptr = proto_java_lang_OutOfMemoryError;
+
     return j;
 }
 
 
     return j;
 }
 
 
-jfloatArray NewFloatArray (JNIEnv *env, jsize len)
+jfloatArray NewFloatArray(JNIEnv *env, jsize len)
 {
        java_floatarray *j;
 {
        java_floatarray *j;
-    if (len<0) {
-               exceptionptr=proto_java_lang_NegativeArraySizeException;
+
+    if (len < 0) {
+               *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
                return NULL;
     }
                return NULL;
     }
+
     j = builtin_newarray_float(len);
     j = builtin_newarray_float(len);
-    if (!j) exceptionptr = proto_java_lang_OutOfMemoryError;
+
     return j;
 }
 
 
     return j;
 }
 
 
-jdoubleArray NewDoubleArray (JNIEnv *env, jsize len)
+jdoubleArray NewDoubleArray(JNIEnv *env, jsize len)
 {
        java_doublearray *j;
 {
        java_doublearray *j;
-    if (len<0) {
-               exceptionptr=proto_java_lang_NegativeArraySizeException;
+
+    if (len < 0) {
+               *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
                return NULL;
     }
                return NULL;
     }
+
     j = builtin_newarray_double(len);
     j = builtin_newarray_double(len);
-    if (!j) exceptionptr = proto_java_lang_OutOfMemoryError;
+
     return j;
 }
 
     return j;
 }
 
@@ -2660,150 +2796,171 @@ void ReleaseDoubleArrayElements (JNIEnv *env, jdoubleArray array, jdouble *elems
     /* empty */
 }
 
     /* empty */
 }
 
-void GetBooleanArrayRegion (JNIEnv* env, jbooleanArray array, jsize start, jsize len, jboolean *buf)
+
+void GetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize len, jboolean *buf)
 {
 {
-    if (start<0 || len<0 || start+len>array->header.size)
-       exceptionptr = proto_java_lang_ArrayIndexOutOfBoundsException;
+    if (start < 0 || len < 0 || start + len > array->header.size)
+               *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
+
     else
     else
-       memcpy(buf,&array->data[start],len*sizeof(array->data[0]));     
+               memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
 }
 
 
 }
 
 
-void GetByteArrayRegion (JNIEnv* env, jbyteArray array, jsize start, jsize len, jbyte *buf)
+void GetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize len, jbyte *buf)
 {
 {
-    if (start<0 || len<0 || start+len>array->header.size) 
-       exceptionptr = proto_java_lang_ArrayIndexOutOfBoundsException;
+    if (start < 0 || len < 0 || start + len > array->header.size) 
+               *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
+
     else
     else
-       memcpy(buf,&array->data[start],len*sizeof(array->data[0]));
+               memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
 }
 
 
 }
 
 
-void GetCharArrayRegion (JNIEnv* env, jcharArray array, jsize start, jsize len, jchar *buf)
+void GetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize len, jchar *buf)
 {
 {
-    if (start<0 || len<0 || start+len>array->header.size)
-       exceptionptr = proto_java_lang_ArrayIndexOutOfBoundsException;
+    if (start < 0 || len < 0 || start + len > array->header.size)
+               *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
+
     else
     else
-       memcpy(buf,&array->data[start],len*sizeof(array->data[0]));     
+               memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
 }
 
 
 }
 
 
-void GetShortArrayRegion (JNIEnv* env, jshortArray array, jsize start, jsize len, jshort *buf)
+void GetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize len, jshort *buf)
 {
 {
-    if (start<0 || len<0 || start+len>array->header.size)
-       exceptionptr = proto_java_lang_ArrayIndexOutOfBoundsException;
+    if (start < 0 || len < 0 || start + len > array->header.size)
+               *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
+
     else       
     else       
-       memcpy(buf,&array->data[start],len*sizeof(array->data[0]));     
+               memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
 }
 
 
 }
 
 
-void GetIntArrayRegion (JNIEnv* env, jintArray array, jsize start, jsize len, jint *buf)
+void GetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize len, jint *buf)
 {
 {
-    if (start<0 || len<0 || start+len>array->header.size)      
-       exceptionptr = proto_java_lang_ArrayIndexOutOfBoundsException;
+    if (start < 0 || len < 0 || start + len > array->header.size)
+               *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
+
     else
     else
-       memcpy(buf,&array->data[start],len*sizeof(array->data[0]));     
+               memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
 }
 
 
 }
 
 
-void GetLongArrayRegion (JNIEnv* env, jlongArray array, jsize start, jsize len, jlong *buf)
+void GetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize len, jlong *buf)
 {
 {
-    if (start<0 || len<0 || start+len>array->header.size)      
-       exceptionptr = proto_java_lang_ArrayIndexOutOfBoundsException;
+    if (start < 0 || len < 0 || start + len > array->header.size)
+               *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
+
     else
     else
-       memcpy(buf,&array->data[start],len*sizeof(array->data[0]));     
+               memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
 }
 
 
 }
 
 
-void GetFloatArrayRegion (JNIEnv* env, jfloatArray array, jsize start, jsize len, jfloat *buf)
+void GetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize len, jfloat *buf)
 {
 {
-    if (start<0 || len<0 || start+len>array->header.size)      
-       exceptionptr = proto_java_lang_ArrayIndexOutOfBoundsException;
+    if (start < 0 || len < 0 || start + len > array->header.size)
+               *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
+
     else
     else
-       memcpy(buf,&array->data[start],len*sizeof(array->data[0]));     
+               memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
 }
 
 
 }
 
 
-void GetDoubleArrayRegion (JNIEnv* env, jdoubleArray array, jsize start, jsize len, jdouble *buf)
+void GetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize len, jdouble *buf)
 {
 {
-    if (start<0 || len<0 || start+len>array->header.size) 
-       exceptionptr = proto_java_lang_ArrayIndexOutOfBoundsException;
+    if (start < 0 || len < 0 || start+len>array->header.size)
+               *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
+
     else
     else
-       memcpy(buf,&array->data[start],len*sizeof(array->data[0]));     
+               memcpy(buf, &array->data[start], len * sizeof(array->data[0]));
 }
 
 
 }
 
 
-void SetBooleanArrayRegion (JNIEnv* env, jbooleanArray array, jsize start, jsize len, jboolean *buf)
+void SetBooleanArrayRegion(JNIEnv* env, jbooleanArray array, jsize start, jsize len, jboolean *buf)
 {
 {
-    if (start<0 || len<0 || start+len>array->header.size)
-       exceptionptr = proto_java_lang_ArrayIndexOutOfBoundsException;
+    if (start < 0 || len < 0 || start + len > array->header.size)
+               *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
+
     else
     else
-       memcpy(&array->data[start],buf,len*sizeof(array->data[0]));     
+               memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
 }
 
 
 }
 
 
-void SetByteArrayRegion (JNIEnv* env, jbyteArray array, jsize start, jsize len, jbyte *buf)
+void SetByteArrayRegion(JNIEnv* env, jbyteArray array, jsize start, jsize len, jbyte *buf)
 {
 {
-    if (start<0 || len<0 || start+len>array->header.size)
-       exceptionptr = proto_java_lang_ArrayIndexOutOfBoundsException;
+    if (start < 0 || len < 0 || start + len > array->header.size)
+               *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
+
     else
     else
-       memcpy(&array->data[start],buf,len*sizeof(array->data[0]));     
+               memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
 }
 
 
 }
 
 
-void SetCharArrayRegion (JNIEnv* env, jcharArray array, jsize start, jsize len, jchar *buf)
+void SetCharArrayRegion(JNIEnv* env, jcharArray array, jsize start, jsize len, jchar *buf)
 {
 {
-    if (start<0 || len<0 || start+len>array->header.size)
-       exceptionptr = proto_java_lang_ArrayIndexOutOfBoundsException;
+    if (start < 0 || len < 0 || start + len > array->header.size)
+               *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
+
     else
     else
-       memcpy(&array->data[start],buf,len*sizeof(array->data[0]));     
+               memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
 
 }
 
 
 
 }
 
 
-void SetShortArrayRegion (JNIEnv* env, jshortArray array, jsize start, jsize len, jshort *buf)
+void SetShortArrayRegion(JNIEnv* env, jshortArray array, jsize start, jsize len, jshort *buf)
 {
 {
-    if (start<0 || len<0 || start+len>array->header.size)
-       exceptionptr = proto_java_lang_ArrayIndexOutOfBoundsException;
+    if (start < 0 || len < 0 || start + len > array->header.size)
+               *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
+
     else
     else
-       memcpy(&array->data[start],buf,len*sizeof(array->data[0]));     
+               memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
 }
 
 
 }
 
 
-void SetIntArrayRegion (JNIEnv* env, jintArray array, jsize start, jsize len, jint *buf)
+void SetIntArrayRegion(JNIEnv* env, jintArray array, jsize start, jsize len, jint *buf)
 {
 {
-    if (start<0 || len<0 || start+len>array->header.size)
-       exceptionptr = proto_java_lang_ArrayIndexOutOfBoundsException;
+    if (start < 0 || len < 0 || start + len > array->header.size)
+               *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
+
     else
     else
-       memcpy(&array->data[start],buf,len*sizeof(array->data[0]));     
+               memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
 
 }
 
 
 }
 
-void SetLongArrayRegion (JNIEnv* env, jlongArray array, jsize start, jsize len, jlong *buf)
+
+void SetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize len, jlong *buf)
 {
 {
-    if (start<0 || len<0 || start+len>array->header.size)
-       exceptionptr = proto_java_lang_ArrayIndexOutOfBoundsException;
+    if (start < 0 || len < 0 || start + len > array->header.size)
+               *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
+
     else
     else
-       memcpy(&array->data[start],buf,len*sizeof(array->data[0]));     
+               memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
 
 }
 
 
 }
 
-void SetFloatArrayRegion (JNIEnv* env, jfloatArray array, jsize start, jsize len, jfloat *buf)
+
+void SetFloatArrayRegion(JNIEnv* env, jfloatArray array, jsize start, jsize len, jfloat *buf)
 {
 {
-    if (start<0 || len<0 || start+len>array->header.size)
-       exceptionptr = proto_java_lang_ArrayIndexOutOfBoundsException;
+    if (start < 0 || len < 0 || start + len > array->header.size)
+               *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
+
     else
     else
-       memcpy(&array->data[start],buf,len*sizeof(array->data[0]));     
+               memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
 
 }
 
 
 }
 
-void SetDoubleArrayRegion (JNIEnv* env, jdoubleArray array, jsize start, jsize len, jdouble *buf)
+
+void SetDoubleArrayRegion(JNIEnv* env, jdoubleArray array, jsize start, jsize len, jdouble *buf)
 {
 {
-    if (start<0 || len<0 || start+len>array->header.size)
-       exceptionptr = proto_java_lang_ArrayIndexOutOfBoundsException;
+    if (start < 0 || len < 0 || start + len > array->header.size)
+               *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
+
     else
     else
-       memcpy(&array->data[start],buf,len*sizeof(array->data[0]));     
+               memcpy(&array->data[start], buf, len * sizeof(array->data[0]));
 }
 
 }
 
+
 jint RegisterNatives (JNIEnv* env, jclass clazz, const JNINativeMethod *methods, jint nMethods)
 {
     log_text("JNI-Call: RegisterNatives");
 jint RegisterNatives (JNIEnv* env, jclass clazz, const JNINativeMethod *methods, jint nMethods)
 {
     log_text("JNI-Call: RegisterNatives");
@@ -2857,7 +3014,7 @@ void GetStringUTFRegion (JNIEnv* env, jstring str, jsize start, jsize len, char
 
 }
 
 
 }
 
-/****************** obtain direct pointer to array elements ***********************/
+/************** obtain direct pointer to array elements ***********************/
 
 void * GetPrimitiveArrayCritical (JNIEnv* env, jarray array, jboolean *isCopy)
 {
 
 void * GetPrimitiveArrayCritical (JNIEnv* env, jarray array, jboolean *isCopy)
 {
@@ -2877,7 +3034,7 @@ void ReleasePrimitiveArrayCritical (JNIEnv* env, jarray array, void *carray, jin
        /* empty */
 }
 
        /* empty */
 }
 
-/********* returns a pointer to an array of Unicode characters of the string *******/
+/**** returns a pointer to an array of Unicode characters of the string *******/
 
 const jchar * GetStringCritical (JNIEnv* env, jstring string, jboolean *isCopy)
 {
 
 const jchar * GetStringCritical (JNIEnv* env, jstring string, jboolean *isCopy)
 {
@@ -2886,7 +3043,7 @@ const jchar * GetStringCritical (JNIEnv* env, jstring string, jboolean *isCopy)
        return GetStringChars(env,string,isCopy);
 }
 
        return GetStringChars(env,string,isCopy);
 }
 
-/**************** native code no longer needs access to chars **********************/
+/*********** native code no longer needs access to chars **********************/
 
 void ReleaseStringCritical (JNIEnv* env, jstring string, const jchar *cstring)
 {
 
 void ReleaseStringCritical (JNIEnv* env, jstring string, const jchar *cstring)
 {
@@ -2912,6 +3069,67 @@ void DeleteWeakGlobalRef (JNIEnv* env, jweak ref)
 }
 
 
 }
 
 
+/** Creates a new global reference to the object referred to by the obj argument **/
+    
+jobject NewGlobalRef(JNIEnv* env, jobject lobj)
+{
+       jobject refcount;
+       jint val;
+       jobject newval;
+
+       MonitorEnter(env, *global_ref_table);
+       
+       refcount = CallObjectMethod(env, *global_ref_table, getmid, lobj);
+       val = (refcount == NULL) ? 0 : CallIntMethod(env, refcount, intvalue);
+       newval = NewObject(env, intclass, newint, val + 1);
+
+       if (newval != NULL) {
+               CallObjectMethod(env, *global_ref_table, putmid, lobj, newval);
+               MonitorExit(env, *global_ref_table);
+               return lobj;
+
+       } else {
+               log_text("JNI-NewGlobalRef: unable to create new java.lang.Integer");
+               MonitorExit(env, *global_ref_table);
+               return NULL;
+       }
+}
+
+/*************  Deletes the global reference pointed to by globalRef **************/
+
+void DeleteGlobalRef(JNIEnv* env, jobject gref)
+{
+       jobject refcount;
+       jint val;
+
+       MonitorEnter(env, *global_ref_table);
+       refcount = CallObjectMethod(env, *global_ref_table, getmid, gref);
+
+       if (refcount == NULL) {
+               log_text("JNI-DeleteGlobalRef: unable to find global reference");
+               return;
+       }
+
+       val = CallIntMethod(env, refcount, intvalue);
+       val--;
+
+       if (val == 0) {
+               CallObjectMethod(env, *global_ref_table, removemid,refcount);
+
+       } else {
+               jobject newval = NewObject(env, intclass, newint, val);
+
+               if (newval != NULL) {
+                       CallObjectMethod(env,*global_ref_table, putmid,newval);
+
+               } else {
+                       log_text("JNI-DeleteGlobalRef: unable to create new java.lang.Integer");
+               }
+       }
+
+       MonitorExit(env,*global_ref_table);
+}
+
 /******************************* check for pending exception ***********************/
 
 
 /******************************* check for pending exception ***********************/
 
 
@@ -2919,7 +3137,7 @@ jboolean ExceptionCheck(JNIEnv* env)
 {
        log_text("JNI-Call: ExceptionCheck");
 
 {
        log_text("JNI-Call: ExceptionCheck");
 
-       return exceptionptr ? JNI_TRUE : JNI_FALSE;
+       return *exceptionptr ? JNI_TRUE : JNI_FALSE;
 }
 
 
 }
 
 
@@ -2967,15 +3185,6 @@ jint AttachCurrentThreadAsDaemon(JavaVM *vm, void **par1, void *par2)
 }
 
 
 }
 
 
-
-
-
-
-
-
-
-
-
 /********************************* JNI invocation table ******************************/
 
 struct _JavaVM javaVMTable={
 /********************************* JNI invocation table ******************************/
 
 struct _JavaVM javaVMTable={
@@ -3226,171 +3435,293 @@ struct JNI_Table envTable = {
     &ExceptionCheck
 };
 
     &ExceptionCheck
 };
 
-
 JNIEnv env = &envTable;
 
 
 JNIEnv env = &envTable;
 
 
-
-
-
-
-
-
-jobject *jni_method_invokeNativeHelper(JNIEnv *env,struct methodinfo *methodID,jobject obj, java_objectarray *params) {
+jobject *jni_method_invokeNativeHelper(JNIEnv *env, struct methodinfo *methodID, jobject obj, java_objectarray *params)
+{
        int argcount;
        jni_callblock *blk;
        int argcount;
        jni_callblock *blk;
-       jobject ret;
        char retT;
        jobject retVal;
        char retT;
        jobject retVal;
-       if (methodID==0) {
-               exceptionptr = native_new_and_init(class_java_lang_NoSuchMethodError); 
-               return 0;
+
+       if (methodID == 0) {
+               *exceptionptr = new_exception(string_java_lang_NoSuchMethodError); 
+               return NULL;
        }
        }
-        argcount=get_parametercount(methodID);
 
 
-       if (obj && (!builtin_instanceof((java_objectheader*)obj,methodID->class))) {
-               (*env)->ThrowNew(env,loader_load(utf_new_char("java/lang/IllegalArgumentException")),
-                       "Object parameter of wrong type in Java_java_lang_reflect_Method_invokeNative");
-               return 0;
-       }
+       argcount = get_parametercount(methodID);
 
 
+       if (obj && (!builtin_instanceof((java_objectheader *) obj, methodID->class))) {
+               *exceptionptr = new_exception_message(string_java_lang_IllegalArgumentException,
+                                                                                         "Object parameter of wrong type in Java_java_lang_reflect_Method_invokeNative");
+               return 0;
+       }
 
 
 
 
-       if  (argcount>3) {
-               exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
+#ifdef arglimit
+       if (argcount > 3) {
+               *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
                log_text("Too many arguments. invokeNativeHelper does not support that");
                return 0;
        }
                log_text("Too many arguments. invokeNativeHelper does not support that");
                return 0;
        }
+#endif
 
 
-       if ( ((!params) && (argcount!=0)) || 
-               (params && (params->header.size!=argcount))
-          ) {
-               exceptionptr = native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
+       if (((!params) && (argcount != 0)) || (params && (params->header.size != argcount))) {
+               *exceptionptr = new_exception(string_java_lang_IllegalArgumentException);
                return 0;
        }
 
 
                return 0;
        }
 
 
-         if (!(methodID->flags & ACC_STATIC) && (!obj))  {
-               (*env)->ThrowNew(env,loader_load(utf_new_char("java/lang/NullPointerException")),
-                       "Static mismatch in Java_java_lang_reflect_Method_invokeNative");
-               return 0;
-       }
+       if (!(methodID->flags & ACC_STATIC) && (!obj))  {
+               *exceptionptr = new_exception_message(string_java_lang_NullPointerException,
+                                                                                         "Static mismatch in Java_java_lang_reflect_Method_invokeNative");
+               return 0;
+       }
 
 
-       if ((methodID->flags & ACC_STATIC) && (obj)) obj=0;
+       if ((methodID->flags & ACC_STATIC) && (obj)) obj = 0;
 
        blk = MNEW(jni_callblock, 4 /*argcount+2*/);
 
 
        blk = MNEW(jni_callblock, 4 /*argcount+2*/);
 
-       retT=fill_callblock_objA(obj,methodID->descriptor,blk,params);
+       retT = fill_callblock_objA(obj, methodID->descriptor, blk, params);
 
        switch (retT) {
 
        switch (retT) {
-               case 'V':       (void)asm_calljavafunction2(methodID,argcount+1,(argcount+1)*sizeof(jni_callblock),blk);
-                               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_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);
-                               }
-                               break;
-               case 'B':       {
-                                       s4 intVal;      
-                                       intVal=(s4)asm_calljavafunction2(methodID,
-                                               argcount+1,(argcount+1)*sizeof(jni_callblock),blk);                                                                                             
-                                       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);
-                               }
-                               break;
-               case 'C':       {
-                                       s4 intVal;      
-                                       intVal=(s4)asm_calljavafunction2(methodID,
-                                               argcount+1,(argcount+1)*sizeof(jni_callblock),blk);                                                                                             
-                                       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);
-                               }
-                               break;
-               case 'S':       {
-                                       s4 intVal;      
-                                       intVal=(s4)asm_calljavafunction2(methodID,
-                                               argcount+1,(argcount+1)*sizeof(jni_callblock),blk);                                                                                             
-                                       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);
-                               }
+       case 'V':
+               (void) asm_calljavafunction2(methodID,
+                                                                        argcount + 1,
+                                                                        (argcount + 1) * sizeof(jni_callblock),
+                                                                        blk);
+               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(class_new(utf_new_char("java/lang/Integer")));
+               CallVoidMethod(env,
+                                          retVal,
+                                          class_resolvemethod(retVal->vftbl->class,
+                                                                                  utf_new_char("<init>"),
+                                                                                  utf_new_char("(I)V")),
+                                          intVal);
+       }
+       break;
+
+       case 'B': {
+               s4 intVal;      
+               intVal = (s4) asm_calljavafunction2(methodID,
+                                                                                       argcount + 1,
+                                                                                       (argcount + 1) * sizeof(jni_callblock),
+                                                                                       blk);
+               retVal = builtin_new(class_new(utf_new_char("java/lang/Byte")));
+               CallVoidMethod(env,
+                                          retVal,
+                                          class_resolvemethod(retVal->vftbl->class,
+                                                                                  utf_new_char("<init>"),
+                                                                                  utf_new_char("(B)V")),
+                                          intVal);
+       }
+       break;
+
+       case 'C': {
+               s4 intVal;      
+               intVal = (s4) asm_calljavafunction2(methodID,
+                                                                                       argcount + 1,
+                                                                                       (argcount + 1) * sizeof(jni_callblock),
+                                                                                       blk);
+               retVal = builtin_new(class_new(utf_new_char("java/lang/Character")));
+               CallVoidMethod(env,
+                                          retVal,
+                                          class_resolvemethod(retVal->vftbl->class,
+                                                                                  utf_new_char("<init>"),
+                                                                                  utf_new_char("(C)V")),
+                                          intVal);
+       }
+       break;
+
+       case 'S': {
+               s4 intVal;      
+               intVal = (s4) asm_calljavafunction2(methodID,
+                                                                                       argcount + 1,
+                                                                                       (argcount + 1) * sizeof(jni_callblock),
+                                                                                       blk);
+               retVal = builtin_new(class_new(utf_new_char("java/lang/Short")));
+               CallVoidMethod(env,
+                                          retVal,
+                                          class_resolvemethod(retVal->vftbl->class,
+                                                                                  utf_new_char("<init>"),
+                                                                                  utf_new_char("(S)V")),
+                                          intVal);
+       }
+       break;
+
+       case 'Z': {
+               s4 intVal;      
+               intVal = (s4) asm_calljavafunction2(methodID,
+                                                                                       argcount + 1,
+                                                                                       (argcount + 1) * sizeof(jni_callblock),
+                                                                                       blk);
+               retVal = builtin_new(class_new(utf_new_char("java/lang/Boolean")));
+               CallVoidMethod(env,
+                                          retVal,
+                                          class_resolvemethod(retVal->vftbl->class,
+                                                                                  utf_new_char("<init>"),
+                                                                                  utf_new_char("(Z)V")),
+                                          intVal);
+       }
+       break;
+
+       case 'J': {
+               jlong intVal;   
+               intVal = asm_calljavafunction2long(methodID,
+                                                                                  argcount + 1,
+                                                                                  (argcount + 1) * sizeof(jni_callblock),
+                                                                                  blk);
+               retVal = builtin_new(class_new(utf_new_char("java/lang/Long")));
+               CallVoidMethod(env,
+                                          retVal,
+                                          class_resolvemethod(retVal->vftbl->class,
+                                                                                  utf_new_char("<init>"),
+                                                                                  utf_new_char("(J)V")),
+                                          intVal);
+       }
+       break;
+
+       case 'F': {
+               jdouble floatVal;       
+               floatVal = asm_calljavafunction2double(methodID,
+                                                                                          argcount + 1,
+                                                                                          (argcount + 1) * sizeof(jni_callblock),
+                                                                                          blk);
+               retVal = builtin_new(class_new(utf_new_char("java/lang/Float")));
+               CallVoidMethod(env,
+                                          retVal,
+                                          class_resolvemethod(retVal->vftbl->class,
+                                                                                  utf_new_char("<init>"),
+                                                                                  utf_new_char("(F)V")),
+                                          floatVal);
+       }
+       break;
+
+       case 'D': {
+               jdouble floatVal;       
+               floatVal = asm_calljavafunction2double(methodID,
+                                                                                          argcount + 1,
+                                                                                          (argcount + 1) * sizeof(jni_callblock),
+                                                                                          blk);
+               retVal = builtin_new(class_new(utf_new_char("java/lang/Double")));
+               CallVoidMethod(env,
+                                          retVal,
+                                          class_resolvemethod(retVal->vftbl->class,
+                                                                                  utf_new_char("<init>"),
+                                                                                  utf_new_char("(D)V")),
+                                          floatVal);
+       }
+       break;
 
 
-               case 'Z':       {
-                                       s4 intVal;      
-                                       intVal=(s4)asm_calljavafunction2(methodID,
-                                               argcount+1,(argcount+1)*sizeof(jni_callblock),blk);                                                                                             
-                                       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);
-                               }
-                               break;
-               case 'J':       {
-                                       jlong intVal;   
-                                       intVal=asm_calljavafunction2long(methodID,
-                                               argcount+1,(argcount+1)*sizeof(jni_callblock),blk);                                                                                             
-                                       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);
-                               }
-                               break;
-               case 'F':       {
-                                       jdouble floatVal;       
-                                       floatVal=asm_calljavafunction2double(methodID,
-                                               argcount+1,(argcount+1)*sizeof(jni_callblock),blk);                                                                                             
-                                       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);
-                               }
-                               break;
-               case 'D':       {
-                                       jdouble floatVal;       
-                                       floatVal=asm_calljavafunction2double(methodID,
-                                               argcount+1,(argcount+1)*sizeof(jni_callblock),blk);                                                                                             
-                                       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);
-                               }
-                               break;
+       case 'L': /* fall through */
+       case '[':
+               retVal = asm_calljavafunction2(methodID,
+                                                                          argcount + 1,
+                                                                          (argcount + 1) * sizeof(jni_callblock),
+                                                                          blk);
+               break;
 
 
-               case 'L':       /* fall through */
-               case '[':       retVal=asm_calljavafunction2(methodID,argcount+1,(argcount+1)*sizeof(jni_callblock),blk);
-                               break;
-               default:        { 
-                                       /* if this happens the acception has already been set by fill_callblock_objA*/
-                                       MFREE(blk, jni_callblock, 4 /*argcount+2*/);
-                                       return (jobject*)0;
-                               }
+       default:
+               /* if this happens the acception has already been set by fill_callblock_objA*/
+               MFREE(blk, jni_callblock, 4 /*argcount+2*/);
+               return (jobject *) 0;
        }
        }
+
        MFREE(blk, jni_callblock, 4 /*argcount+2*/);
 
        MFREE(blk, jni_callblock, 4 /*argcount+2*/);
 
-       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;
+       if (*exceptionptr) {
+               java_objectheader *exceptionToWrap = *exceptionptr;
+               classinfo *ivtec;
+               java_objectheader *ivte;
+
+               *exceptionptr = NULL;
+               ivtec = class_new(utf_new_char("java/lang/reflect/InvocationTargetException"));
+               ivte = builtin_new(ivtec);
+               asm_calljavafunction(class_resolvemethod(ivtec,
+                                                                                                utf_new_char("<init>"),
+                                                                                                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;  
 
 
+       return (jobject *) retVal;
 }
 
 }
 
+void jni_init() {
+       jmethodID mid;
+
+       log_text("JNI-Init: initialize global_ref_table");
+       // initalize global reference table
+       ihmclass = FindClass(NULL, "java/util/IdentityHashMap");
+       
+       if (ihmclass == NULL) {
+               log_text("JNI-Init: unable to find java.util.IdentityHashMap");
+       }
+
+       mid = GetMethodID(NULL, ihmclass, "<init>","()V");
+       if (mid == NULL) {
+               log_text("JNI-Init: unable to find constructor in java.util.IdentityHashMap");
+       }
+       
+       global_ref_table = (jobject*)heap_allocate(sizeof(jobject),true,NULL);
+
+       *global_ref_table = NewObject(NULL,ihmclass,mid);
+
+       if (*global_ref_table == NULL) {
+               log_text("JNI-Init: unable to create new global_ref_table");
+       }
+       
+       getmid = GetMethodID(NULL, ihmclass, "get","(Ljava/lang/Object;)Ljava/lang/Object;");
+       if (mid == NULL) {
+               log_text("JNI-Init: unable to find method \"get\" in java.util.IdentityHashMap");
+       }
+
+       getmid = GetMethodID(NULL ,ihmclass, "get","(Ljava/lang/Object;)Ljava/lang/Object;");
+       if (getmid == NULL) {
+               log_text("JNI-Init: unable to find method \"get\" in java.util.IdentityHashMap");
+       }
+
+       putmid = GetMethodID(NULL, ihmclass, "put","(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
+       if (putmid == NULL) {
+               log_text("JNI-Init: unable to find method \"put\" in java.util.IdentityHashMap");
+       }
+
+       intclass = FindClass(NULL, "java/lang/Integer");
+       if (intclass == NULL) {
+               log_text("JNI-Init: unable to find java.lang.Integer");
+       }
+
+       newint = GetMethodID(NULL, intclass, "<init>","(I)V");
+       if (newint == NULL) {
+               log_text("JNI-Init: unable to find constructor in java.lang.Integer");
+       }
+
+       intvalue = GetMethodID(NULL, intclass, "intValue","()I");
+       if (intvalue == NULL) {
+               log_text("JNI-Init: unable to find method \"intValue\" in java.lang.Integer");
+       }
+
+       removemid = GetMethodID(NULL, ihmclass, "remove","(Ljava/lang/Object;)Ljava/lang/Object;");
+       if (removemid == NULL) {
+               log_text("JNI-DeleteGlobalRef: unable to find method \"remove\" in java.lang.Object");
+       }
+}
 
 
 /*
 
 
 /*