GNU header update.
[cacao.git] / src / native / jni.c
index e3e5ca983d59496c49b1c19b4c1834f09f319e94..44bde5b31fe65184c6997ad55d9c7db918dbebc4 100644 (file)
@@ -1,9 +1,9 @@
-/* jni.c - implementation of the Java Native Interface functions
+/* native/jni.c - implementation of the Java Native Interface functions
 
-   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
+   Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
+   R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
+   C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
+   Institut f. Computersprachen - TU Wien
 
    This file is part of CACAO.
 
 
    Authors: ?
 
-   Changes: Joseph Wenninger
+   Changes: Joseph Wenninger, Martin Platter
 
-   $Id: jni.c 897 2004-01-21 00:49:42Z stefan $
+   $Id: jni.c 1735 2004-12-07 14:33:27Z twisti $
 
 */
 
 
 #include <string.h>
-#include "jni.h"
-#include "global.h"
-#include "loader.h"
-#include "tables.h"
-#include "native.h"
-#include "builtin.h"
-#include "threads/thread.h"
-#include "toolbox/loging.h"
-#include "toolbox/memory.h"
-#include "nat/java_lang_Byte.h"
-#include "nat/java_lang_Character.h"
-#include "nat/java_lang_Short.h"
-#include "nat/java_lang_Integer.h"
-#include "nat/java_lang_Boolean.h"
-#include "nat/java_lang_Long.h"
-#include "nat/java_lang_Float.h"
-#include "nat/java_lang_Double.h"
-#include "nat/java_lang_Throwable.h"
-#include "jit/jit.h"
-#include "asmpart.h"   
+
+#include "mm/boehm.h"
+#include "mm/memory.h"
+#include "native/jni.h"
+#include "native/native.h"
+#include "native/include/java_lang_Byte.h"
+#include "native/include/java_lang_Character.h"
+#include "native/include/java_lang_Short.h"
+#include "native/include/java_lang_Integer.h"
+#include "native/include/java_lang_Boolean.h"
+#include "native/include/java_lang_Long.h"
+#include "native/include/java_lang_Float.h"
+#include "native/include/java_lang_Double.h"
+#include "native/include/java_lang_Throwable.h"
+
+#if defined(USE_THREADS)
+# if defined(NATIVE_THREADS)
+#  include "threads/native/threads.h"
+# else
+#  include "threads/green/threads.h"
+# endif
+#endif
+
+#include "toolbox/logging.h"
+#include "vm/builtin.h"
+#include "vm/exceptions.h"
+#include "vm/global.h"
+#include "vm/loader.h"
+#include "vm/options.h"
+#include "vm/statistics.h"
+#include "vm/tables.h"
+#include "vm/jit/asmpart.h"
+#include "vm/jit/jit.h"
+
+
 #define JNI_VERSION       0x00010002
 
 
@@ -68,6 +83,19 @@ static utf* utf_long = 0;
 static utf* utf_float = 0;
 static utf* utf_double = 0;
 
+/* global reference table */
+static jobject *global_ref_table;
+static bool initrunning=false;
+
+/* 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 **********************************/
 
@@ -82,16 +110,14 @@ 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;
+       u4 parametercount = 0;
 
        /* skip '(' */
        utf_nextu2(&utf_ptr);
 
     /* determine number of parameters */
-       while ( *utf_ptr != ')' ) {
-               get_type(&utf_ptr,desc_end,true);
+       while (*utf_ptr != ')') {
+               get_type(&utf_ptr, desc_end, true);
                parametercount++;
        }
 
@@ -105,13 +131,10 @@ void fill_callblock(void *obj, utf *descr, jni_callblock blk[], va_list data, ch
     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;
-
-    jdouble d;
-    jlong l;
     u4 dummy;
     char c;
+
        /*
     log_text("fill_callblock");
     utf_display(descr);
@@ -126,64 +149,69 @@ void fill_callblock(void *obj, utf *descr, jni_callblock blk[], va_list data, ch
                blk[0].item = PTR_TO_ITEM(obj);
                cnt = 1;
        } else cnt = 0;
+
        while (**utf_ptr != ')') {
                if (*utf_ptr >= desc_end)
                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);
+               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);
+
+               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;
+                       blk[cnt].item = (u8) dummy;
+                       break;
 
+               case 'J':
+                       blk[cnt].itemtype = TYPE_LNG;
+                       blk[cnt].item = (u8) va_arg(data, jlong);
                        break;
 
-               case 'J' : 
-                       blk[cnt].itemtype=TYPE_LNG;
-                       blk[cnt].item=(u8)va_arg(data,jlong);
+               case 'F':
+                       blk[cnt].itemtype = TYPE_FLT;
+                       *((jfloat *) (&blk[cnt].item)) = (jfloat) va_arg(data, jdouble);
                        break;
-               case 'F' : 
-                       blk[cnt].itemtype=TYPE_FLT;
-                       *((jfloat*)(&blk[cnt].item))=((jfloat)va_arg(data,jdouble));
+
+               case 'D':
+                       blk[cnt].itemtype = TYPE_DBL;
+                       *((jdouble *) (&blk[cnt].item)) = (jdouble) va_arg(data, jdouble);
                        break;
 
-               case 'D' : 
-                       blk[cnt].itemtype=TYPE_DBL;
-                       *((jdouble*)(&blk[cnt].item))=(jdouble)va_arg(data,jdouble);
+               case 'V':
+                       panic ("V not allowed as function parameter");
                        break;
-               case 'V' : panic ("V not allowed as function parameter");
+                       
+               case 'L':
+                       while (utf_nextu2(utf_ptr) != ';')
+                           blk[cnt].itemtype = TYPE_ADR;
+                       blk[cnt].item = PTR_TO_ITEM(va_arg(data, void*));
                        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)!=';') {}
-                               }
+                       
+               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++;
        }
@@ -192,26 +220,26 @@ void fill_callblock(void *obj, utf *descr, jni_callblock blk[], va_list data, ch
        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====");
+       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)
 {
-    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;
-
-    u4 dummy;
     char c;
-    char *cp;
+
 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
     intsDisable();
 #endif
@@ -247,194 +275,213 @@ char fill_callblock_objA(void *obj, utf *descr, jni_callblock blk[], java_object
                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)) {
-               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':
-                               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;
                                }
-                               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  {
-                                       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;
                                        }
                                }
-                               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 {
-                                       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  {
-                                                       *exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
+                                                       *exceptionptr = new_exception("java/lang/IllegalArgumentException");
                                                        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  {
-                                       *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;
                                }
+                       }
+                       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 'L': {
-                               char *start=(*utf_ptr)-1;
-                               char *end;
+               case 'L':
+                       {
+                               char *start = (*utf_ptr) - 1;
+                               char *end = NULL;
 
                                while (utf_nextu2(utf_ptr) != ';')
-                               end=(*utf_ptr)+1;
-                               if (!builtin_instanceof(params->data[cnts],class_from_descriptor(start,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;
                                        }                       
                                }
-                               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;                  
+                       }
 
-                         }
-               case '[' :
+               case '[':
                        {
-                               char *start=(*utf_ptr)-1;
+                               char *start = (*utf_ptr) - 1;
                                char *end;
 
                                char ch;
@@ -442,12 +489,13 @@ char fill_callblock_objA(void *obj, utf *descr, jni_callblock blk[], java_object
                                        if (ch == 'L') {
                                                while (utf_nextu2(utf_ptr) != ';') {}
                                        }
-                               end=(*utf_ptr)-1;
+
+                               end = (*utf_ptr) - 1;
                                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;
-                                       
                                }
        
                                blk[cnt].itemtype = TYPE_ADR;
@@ -485,6 +533,7 @@ jmethodID get_virtual(jobject obj,jmethodID 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);
 }
 
@@ -496,17 +545,10 @@ jobject callObjectMethod (jobject obj, jmethodID methodID, va_list args)
        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) {
-               *exceptionptr = native_new_and_init(class_java_lang_NoSuchMethodError); 
+               *exceptionptr = new_exception(string_java_lang_NoSuchMethodError); 
                return 0;
        }
 
@@ -514,33 +556,35 @@ jobject callObjectMethod (jobject obj, jmethodID methodID, va_list args)
 
        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)) {
-               *exceptionptr = native_new_and_init(class_java_lang_NoSuchMethodError);
+               *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
                return 0;
        }
 
+#ifdef arglimit
+
        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;
        }
+#endif
 
-       blk = MNEW(jni_callblock, 4 /*argcount+2*/);
+       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);
-
        MFREE(blk, jni_callblock, argcount + 1);
        /*      printf("(CallObjectMethodV)-->%p\n",ret); */
+
        return ret;
 }
 
@@ -566,7 +610,7 @@ jint callIntegerMethod(jobject obj, jmethodID methodID, char retType, va_list ar
         printf("\n");
         */
        if (methodID == 0) {
-               *exceptionptr = native_new_and_init(class_java_lang_NoSuchMethodError); 
+               *exceptionptr = new_exception(string_java_lang_NoSuchMethodError); 
                return 0;
        }
         
@@ -574,23 +618,24 @@ jint callIntegerMethod(jobject obj, jmethodID methodID, char retType, va_list ar
 
        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)) {
-               *exceptionptr = native_new_and_init(class_java_lang_NoSuchMethodError);
+               *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
                return 0;
        }
 
-
+#ifdef arglimit
        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;
        }
+#endif
 
-       blk = MNEW(jni_callblock, 4 /*argcount+2*/);
+       blk = MNEW(jni_callblock, /*4 */ argcount+2);
 
        fill_callblock(obj, methodID->descriptor, blk, args, retType);
 
@@ -614,16 +659,16 @@ jlong callLongMethod(jobject obj, jmethodID methodID, va_list args)
        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");
-        */
+*/      
        if (methodID == 0) {
-               *exceptionptr = native_new_and_init(class_java_lang_NoSuchMethodError); 
+               *exceptionptr = new_exception(string_java_lang_NoSuchMethodError); 
                return 0;
        }
 
@@ -631,25 +676,26 @@ jlong callLongMethod(jobject obj, jmethodID methodID, va_list args)
 
        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)) {
-               *exceptionptr = native_new_and_init(class_java_lang_NoSuchMethodError);
+               *exceptionptr = new_exception(string_java_lang_NoSuchMethodError);
                return 0;
        }
 
-
+#ifdef arglimit
        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;
        }
+#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,
@@ -680,13 +726,15 @@ jdouble callFloatMethod(jobject obj, jmethodID methodID, va_list args,char retTy
         printf("\n");
         */
 
+#ifdef arglimit
        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;
        }
+#endif
 
-       blk = MNEW(jni_callblock, 4 /*argcount+2*/);
+       blk = MNEW(jni_callblock, /*4 */ argcount+2);
 
        fill_callblock(obj, methodID->descriptor, blk, args, retType);
 
@@ -736,48 +784,88 @@ jint GetVersion (JNIEnv* env)
        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 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);
+       }
 
-       /* change suck-mode, so subsequent class_load will read from memory-buffer */
-       classload_buffer( (u1*) buf,len);
+       /* free memory */
+       FREE(cb, classbuffer);
 
-        clazz = loader_load(utf_new_char ((char *) name));
+       /* measure time */
+       if (getloadingtime)
+               loadingtime_stop();
 
-       /* restore old suck-mode */
-       classload_buffer(NULL,0);
+       /* leave the monitor */
 
-       return clazz;
+       builtin_monitorexit((java_objectheader *) c);
+
+       /* XXX link the class here? */
+/*     if (class_link(c)) */
+/*             return NULL; */
+
+       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;  
   
-/*     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 (!class_load(c))
+               return NULL;
 
-       if (!c) *exceptionptr = native_new_and_init(class_java_lang_ClassFormatError);
+       if (!class_link(c))
+               return NULL;
 
        return c;
 }
   
 
-/*********************************************************************************** 
+/*******************************************************************************
 
        converts java.lang.reflect.Method or 
        java.lang.reflect.Constructor object to a method ID  
   
- **********************************************************************************/   
+*******************************************************************************/
   
 jmethodID FromReflectedMethod(JNIEnv* env, jobject method)
 {
@@ -831,25 +919,25 @@ jint Throw(JNIEnv* env, jthrowable obj)
 }
 
 
-/*********************************************************************************** 
+/*******************************************************************************
 
        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) 
 {
        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);
 
-       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;
 }
@@ -900,31 +988,18 @@ jint PushLocalFrame(JNIEnv* env, jint capacity)
 
 jobject PopLocalFrame(JNIEnv* env, jobject result)
 {
+    log_text("JNI-Call: PopLocalFrame");
        /* 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)
 {
+/*    log_text("JNI-Call: DeleteLocalRef");*/
        /* empty */
 }
 
@@ -981,12 +1056,13 @@ jobject NewObject (JNIEnv* env, jclass clazz, jmethodID methodID, ...)
 
        /* 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;
        }
-
+#endif
        
        o = builtin_new (clazz);         /*          create object */
        
@@ -1039,11 +1115,9 @@ jobject NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID, jvalue *args)
 jclass GetObjectClass(JNIEnv* env, jobject obj)
 {
        classinfo *c = obj->vftbl->class;
-/*     log_text("GetObjectClass");
-       utf_display(obj->vftbl->class->name);*/
+
        use_class_as_object(c);
 
-       /*printf("\nPointer: %p\n",c);*/
        return c;
 }
 
@@ -1093,8 +1167,11 @@ jmethodID GetMethodID(JNIEnv* env, jclass clazz, const char *name, const char *s
                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;
 }
 
@@ -1278,17 +1355,20 @@ jint CallIntMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
 
 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)
 {
-       log_text("JNI-Call: CallLongMethodV");
-
-       return 0;
+       return  callLongMethod(obj,get_virtual(obj, methodID),args);
 }
 
 
@@ -1695,10 +1775,10 @@ jfieldID GetFieldID (JNIEnv *env, jclass clazz, const char *name, const char *si
                            ); 
        
        if (!f) { 
-/*             utf_display(clazz->name);
+               utf_display(clazz->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;
 }
@@ -1724,7 +1804,33 @@ jfieldID getFieldID_critical(JNIEnv *env, jclass clazz, char *name, char *sig)
 
 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)
@@ -1834,34 +1940,44 @@ jmethodID GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name, const c
 {
        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;
 }
 
 
-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");
 
@@ -1869,18 +1985,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;
 }
 
 
@@ -1889,6 +2003,7 @@ jboolean CallStaticBooleanMethodV(JNIEnv *env, jclass clazz, jmethodID methodID,
        return (jboolean) callIntegerMethod(0, methodID, 'Z', args);
 }
 
+
 jboolean CallStaticBooleanMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
 {
        log_text("JNI-Call: CallStaticBooleanMethodA");
@@ -1963,7 +2078,7 @@ jshort CallStaticShortMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
 
        /*      log_text("JNI-Call: CallStaticByteMethod");*/
 
-       va_start(vaargs,methodID);
+       va_start(vaargs, methodID);
        ret = (jshort) callIntegerMethod(0, methodID, 'S', vaargs);
        va_end(vaargs);
 
@@ -2150,7 +2265,7 @@ jfieldID GetStaticFieldID (JNIEnv *env, jclass clazz, const char *name, const ch
                            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;
 }
@@ -2383,22 +2498,26 @@ jsize GetStringUTFLength (JNIEnv *env, jstring string)
     return (jsize) u2_utflength(s->value->data, s->count); 
 }
 
+
 /************ 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;
-    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;
        
 }
 
+
 /***************** native code no longer needs access to utf ***********************/
 
 void ReleaseStringUTFChars (JNIEnv *env, jstring str, const char* chars)
@@ -2413,45 +2532,50 @@ void ReleaseStringUTFChars (JNIEnv *env, jstring str, const char* chars)
 
 /************************** array operations ***************************************/
 
-jsize GetArrayLength (JNIEnv *env, jarray array)
+jsize GetArrayLength(JNIEnv *env, jarray array)
 {
     return array->size;
 }
 
+
 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;
     }
-    j = builtin_anewarray (len, clazz);
-    if (!j) *exceptionptr = proto_java_lang_OutOfMemoryError;
+
+    j = builtin_anewarray(len, clazz);
+
     return j;
 }
 
-jobject GetObjectArrayElement (JNIEnv *env, jobjectArray array, jsize index)
+
+jobject GetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index)
 {
     jobject j = NULL;
 
-    if (index<array->header.size)      
+    if (index < array->header.size)    
                j = array->data[index];
     else
-               *exceptionptr = proto_java_lang_ArrayIndexOutOfBoundsException;
+               *exceptionptr = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
     
     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;
     }
@@ -2459,106 +2583,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;
-    if (len<0) {
-               *exceptionptr=proto_java_lang_NegativeArraySizeException;
+
+    if (len < 0) {
+               *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
                return NULL;
     }
+
     j = builtin_newarray_boolean(len);
-    if (!j) *exceptionptr = proto_java_lang_OutOfMemoryError;
+
     return j;
 }
 
 
-jbyteArray NewByteArray (JNIEnv *env, jsize len)
+jbyteArray NewByteArray(JNIEnv *env, jsize len)
 {
        java_bytearray *j;
-    if (len<0) {
-               *exceptionptr=proto_java_lang_NegativeArraySizeException;
+
+    if (len < 0) {
+               *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
                return NULL;
     }
+
     j = builtin_newarray_byte(len);
-    if (!j) *exceptionptr = proto_java_lang_OutOfMemoryError;
+
     return j;
 }
 
 
-jcharArray NewCharArray (JNIEnv *env, jsize len)
+jcharArray NewCharArray(JNIEnv *env, jsize len)
 {
        java_chararray *j;
-    if (len<0) {
-               *exceptionptr=proto_java_lang_NegativeArraySizeException;
+
+    if (len < 0) {
+               *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
                return NULL;
     }
+
     j = builtin_newarray_char(len);
-    if (!j) *exceptionptr = proto_java_lang_OutOfMemoryError;
+
     return j;
 }
 
 
-jshortArray NewShortArray (JNIEnv *env, jsize len)
+jshortArray NewShortArray(JNIEnv *env, jsize len)
 {
        java_shortarray *j;
-    if (len<0) {
-               *exceptionptr=proto_java_lang_NegativeArraySizeException;
+
+    if (len < 0) {
+               *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
                return NULL;
     }
-    j = builtin_newarray_short(len);   
-    if (!j) *exceptionptr = proto_java_lang_OutOfMemoryError;
+
+    j = builtin_newarray_short(len);
+
     return j;
 }
 
 
-jintArray NewIntArray (JNIEnv *env, jsize len)
+jintArray NewIntArray(JNIEnv *env, jsize len)
 {
        java_intarray *j;
-    if (len<0) {
-               *exceptionptr=proto_java_lang_NegativeArraySizeException;
+
+    if (len < 0) {
+               *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
                return NULL;
     }
+
     j = builtin_newarray_int(len);
-    if (!j) *exceptionptr = proto_java_lang_OutOfMemoryError;
+
     return j;
 }
 
 
-jlongArray NewLongArray (JNIEnv *env, jsize len)
+jlongArray NewLongArray(JNIEnv *env, jsize len)
 {
        java_longarray *j;
-    if (len<0) {
-               *exceptionptr=proto_java_lang_NegativeArraySizeException;
+
+    if (len < 0) {
+               *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
                return NULL;
     }
+
     j = builtin_newarray_long(len);
-    if (!j) *exceptionptr = proto_java_lang_OutOfMemoryError;
+
     return j;
 }
 
 
-jfloatArray NewFloatArray (JNIEnv *env, jsize len)
+jfloatArray NewFloatArray(JNIEnv *env, jsize len)
 {
        java_floatarray *j;
-    if (len<0) {
-               *exceptionptr=proto_java_lang_NegativeArraySizeException;
+
+    if (len < 0) {
+               *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
                return NULL;
     }
+
     j = builtin_newarray_float(len);
-    if (!j) *exceptionptr = proto_java_lang_OutOfMemoryError;
+
     return j;
 }
 
 
-jdoubleArray NewDoubleArray (JNIEnv *env, jsize len)
+jdoubleArray NewDoubleArray(JNIEnv *env, jsize len)
 {
        java_doublearray *j;
-    if (len<0) {
-               *exceptionptr=proto_java_lang_NegativeArraySizeException;
+
+    if (len < 0) {
+               *exceptionptr = new_exception(string_java_lang_NegativeArraySizeException);
                return NULL;
     }
+
     j = builtin_newarray_double(len);
-    if (!j) *exceptionptr = proto_java_lang_OutOfMemoryError;
+
     return j;
 }
 
@@ -2667,150 +2807,171 @@ void ReleaseDoubleArrayElements (JNIEnv *env, jdoubleArray array, jdouble *elems
     /* 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
-               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
-               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
-               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       
-               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
-               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
-               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
-               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
-               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
-               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
-               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
-               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
-               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
-               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
-               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
-               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
-               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");
@@ -2864,7 +3025,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)
 {
@@ -2884,7 +3045,7 @@ void ReleasePrimitiveArrayCritical (JNIEnv* env, jarray array, void *carray, jin
        /* 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)
 {
@@ -2893,7 +3054,7 @@ const jchar * GetStringCritical (JNIEnv* env, jstring string, jboolean *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)
 {
@@ -2919,6 +3080,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 ***********************/
 
 
@@ -2973,6 +3195,109 @@ jint AttachCurrentThreadAsDaemon(JavaVM *vm, void **par1, void *par2)
        return 0;
 }
 
+/************* JNI Initialization ****************************************************/
+
+jobject jni_init1(JNIEnv* env, jobject lobj) {
+#if defined(USE_THREADS)
+       while (initrunning) {yieldThread();} /* wait until init is done */
+#endif
+       if (global_ref_table == NULL) {
+               jni_init();
+       } 
+#if defined(USE_THREADS)
+       else {
+               /* wait until jni_init is done */
+               MonitorEnter(env, *global_ref_table) ;
+               MonitorExit(env, *global_ref_table);
+       }
+#endif
+       return NewGlobalRef(env, lobj); 
+}
+void jni_init2(JNIEnv* env, jobject gref) {
+       log_text("DeleteGlobalref called before NewGlobalref");
+#if defined(USE_THREADS)
+       while (initrunning) {yieldThread();} /* wait until init is done */
+#endif
+       if (global_ref_table == NULL) {
+               jni_init();
+       } 
+#if defined(USE_THREADS)
+       else {
+               /* wait until jni_init is done */
+               MonitorEnter(env, *global_ref_table) ;
+               MonitorExit(env, *global_ref_table);
+       }
+#endif
+       DeleteGlobalRef(env, gref); 
+}
+
+void jni_init(){
+       jmethodID mid;
+
+       initrunning = true;
+       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");
+       }
+
+       initrunning = false;
+
+       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");
+       }
+       
+       /* set NewGlobalRef, DeleteGlobalRef envTable entry to real implementation */
+       envTable.NewGlobalRef = &NewGlobalRef;
+       envTable.DeleteGlobalRef = &DeleteGlobalRef;
+}
+
 
 /********************************* JNI invocation table ******************************/
 
@@ -3014,8 +3339,8 @@ struct JNI_Table envTable = {
     &FatalError,
     &PushLocalFrame,
     &PopLocalFrame,
-    &NewGlobalRef,
-    &DeleteGlobalRef,
+       &jni_init1, /* &NewGlobalRef,    initialize Global_Ref_Table*/
+       &jni_init2, /* &DeleteGlobalRef,*/
     &DeleteLocalRef,
     &IsSameObject,
     &NewLocalRef,
@@ -3235,42 +3560,43 @@ jobject *jni_method_invokeNativeHelper(JNIEnv *env, struct methodinfo *methodID,
        jobject retVal;
 
        if (methodID == 0) {
-               *exceptionptr = native_new_and_init(class_java_lang_NoSuchMethodError); 
-               return 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");
+       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;
        }
+#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;
        }
 
 
        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");
+               *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;
 
-       blk = MNEW(jni_callblock, 4 /*argcount+2*/);
+       blk = MNEW(jni_callblock, /*4 */argcount+2);
 
        retT = fill_callblock_objA(obj, methodID->descriptor, blk, params);
 
@@ -3289,8 +3615,7 @@ jobject *jni_method_invokeNativeHelper(JNIEnv *env, struct methodinfo *methodID,
                                                                                        argcount + 1,
                                                                                        (argcount + 1) * sizeof(jni_callblock),
                                                                                        blk);
-               retVal = builtin_new(loader_load_sysclass(NULL,
-                                                                                                 utf_new_char("java/lang/Integer")));
+               retVal = builtin_new(class_new(utf_new_char("java/lang/Integer")));
                CallVoidMethod(env,
                                           retVal,
                                           class_resolvemethod(retVal->vftbl->class,
@@ -3306,8 +3631,7 @@ jobject *jni_method_invokeNativeHelper(JNIEnv *env, struct methodinfo *methodID,
                                                                                        argcount + 1,
                                                                                        (argcount + 1) * sizeof(jni_callblock),
                                                                                        blk);
-               retVal = builtin_new(loader_load_sysclass(NULL,
-                                                                                                 utf_new_char("java/lang/Byte")));
+               retVal = builtin_new(class_new(utf_new_char("java/lang/Byte")));
                CallVoidMethod(env,
                                           retVal,
                                           class_resolvemethod(retVal->vftbl->class,
@@ -3323,8 +3647,7 @@ jobject *jni_method_invokeNativeHelper(JNIEnv *env, struct methodinfo *methodID,
                                                                                        argcount + 1,
                                                                                        (argcount + 1) * sizeof(jni_callblock),
                                                                                        blk);
-               retVal = builtin_new(loader_load_sysclass(NULL,
-                                                                                                 utf_new_char("java/lang/Character")));
+               retVal = builtin_new(class_new(utf_new_char("java/lang/Character")));
                CallVoidMethod(env,
                                           retVal,
                                           class_resolvemethod(retVal->vftbl->class,
@@ -3340,8 +3663,7 @@ jobject *jni_method_invokeNativeHelper(JNIEnv *env, struct methodinfo *methodID,
                                                                                        argcount + 1,
                                                                                        (argcount + 1) * sizeof(jni_callblock),
                                                                                        blk);
-               retVal = builtin_new(loader_load_sysclass(NULL,
-                                                                                                 utf_new_char("java/lang/Short")));
+               retVal = builtin_new(class_new(utf_new_char("java/lang/Short")));
                CallVoidMethod(env,
                                           retVal,
                                           class_resolvemethod(retVal->vftbl->class,
@@ -3357,8 +3679,7 @@ jobject *jni_method_invokeNativeHelper(JNIEnv *env, struct methodinfo *methodID,
                                                                                        argcount + 1,
                                                                                        (argcount + 1) * sizeof(jni_callblock),
                                                                                        blk);
-               retVal = builtin_new(loader_load_sysclass(NULL,
-                                                                                                 utf_new_char("java/lang/Boolean")));
+               retVal = builtin_new(class_new(utf_new_char("java/lang/Boolean")));
                CallVoidMethod(env,
                                           retVal,
                                           class_resolvemethod(retVal->vftbl->class,
@@ -3374,8 +3695,7 @@ jobject *jni_method_invokeNativeHelper(JNIEnv *env, struct methodinfo *methodID,
                                                                                   argcount + 1,
                                                                                   (argcount + 1) * sizeof(jni_callblock),
                                                                                   blk);
-               retVal = builtin_new(loader_load_sysclass(NULL,
-                                                                                                 utf_new_char("java/lang/Long")));
+               retVal = builtin_new(class_new(utf_new_char("java/lang/Long")));
                CallVoidMethod(env,
                                           retVal,
                                           class_resolvemethod(retVal->vftbl->class,
@@ -3391,8 +3711,7 @@ jobject *jni_method_invokeNativeHelper(JNIEnv *env, struct methodinfo *methodID,
                                                                                           argcount + 1,
                                                                                           (argcount + 1) * sizeof(jni_callblock),
                                                                                           blk);
-               retVal = builtin_new(loader_load_sysclass(NULL,
-                                                                                                 utf_new_char("java/lang/Float")));
+               retVal = builtin_new(class_new(utf_new_char("java/lang/Float")));
                CallVoidMethod(env,
                                           retVal,
                                           class_resolvemethod(retVal->vftbl->class,
@@ -3408,8 +3727,7 @@ jobject *jni_method_invokeNativeHelper(JNIEnv *env, struct methodinfo *methodID,
                                                                                           argcount + 1,
                                                                                           (argcount + 1) * sizeof(jni_callblock),
                                                                                           blk);
-               retVal = builtin_new(loader_load_sysclass(NULL,
-                                                                                                 utf_new_char("java/lang/Double")));
+               retVal = builtin_new(class_new(utf_new_char("java/lang/Double")));
                CallVoidMethod(env,
                                           retVal,
                                           class_resolvemethod(retVal->vftbl->class,
@@ -3429,17 +3747,20 @@ jobject *jni_method_invokeNativeHelper(JNIEnv *env, struct methodinfo *methodID,
 
        default:
                /* if this happens the acception has already been set by fill_callblock_objA*/
-               MFREE(blk, jni_callblock, 4 /*argcount+2*/);
+               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);
+               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")),
@@ -3458,6 +3779,8 @@ jobject *jni_method_invokeNativeHelper(JNIEnv *env, struct methodinfo *methodID,
 }
 
 
+
+
 /*
  * These are local overrides for various environment variables in Emacs.
  * Please do not remove this and leave it at the end of the file, where