* Removed all Id tags.
[cacao.git] / src / native / jni.c
index 100565efbe0f0eab526003ba7e832befb0ebe03b..a28cd68df14fa8481bda0f7a7d8034280a0b197d 100644 (file)
@@ -1,6 +1,6 @@
 /* src/native/jni.c - implementation of the Java Native Interface functions
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Rainhard Grafl
-            Roman Obermaisser
-
-   Changes: Joseph Wenninger
-            Martin Platter
-            Christian Thalinger
-                       Edwin Steiner
-
-   $Id: jni.c 4530 2006-02-21 09:11:53Z twisti $
-
 */
 
 
 #include "config.h"
 
 #include <assert.h>
+#include <stdint.h>
 #include <string.h>
 
 #include "vm/types.h"
 
-#include "mm/boehm.h"
+#include "mm/gc-common.h"
 #include "mm/memory.h"
+
 #include "native/jni.h"
+#include "native/llni.h"
+#include "native/localref.h"
 #include "native/native.h"
 
-#include "native/include/gnu_classpath_Pointer.h"
+#if defined(ENABLE_JAVASE)
+# if defined(WITH_CLASSPATH_GNU)
+#  include "native/include/gnu_classpath_Pointer.h"
 
-#if SIZEOF_VOID_P == 8
-# include "native/include/gnu_classpath_Pointer64.h"
-#else
-# include "native/include/gnu_classpath_Pointer32.h"
+#  if SIZEOF_VOID_P == 8
+#   include "native/include/gnu_classpath_Pointer64.h"
+#  else
+#   include "native/include/gnu_classpath_Pointer32.h"
+#  endif
+# endif
 #endif
 
 #include "native/include/java_lang_Object.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_String.h"
 #include "native/include/java_lang_Throwable.h"
-#include "native/include/java_lang_reflect_Method.h"
-#include "native/include/java_lang_reflect_Constructor.h"
-#include "native/include/java_lang_reflect_Field.h"
 
-#include "native/include/java_lang_Class.h" /* for java_lang_VMClass.h */
-#include "native/include/java_lang_VMClass.h"
-#include "native/include/java_lang_VMClassLoader.h"
-#include "native/include/java_nio_Buffer.h"
-#include "native/include/java_nio_DirectByteBufferImpl.h"
+#if defined(ENABLE_JAVASE)
+# if defined(WITH_CLASSPATH_SUN)
+#  include "native/include/java_nio_ByteBuffer.h"       /* required by j.l.CL */
+# endif
+
+# include "native/include/java_lang_ClassLoader.h"
+
+# include "native/include/java_lang_reflect_Constructor.h"
+# include "native/include/java_lang_reflect_Field.h"
+# include "native/include/java_lang_reflect_Method.h"
+
+# include "native/include/java_nio_Buffer.h"
+
+# if defined(WITH_CLASSPATH_GNU)
+#  include "native/include/java_nio_DirectByteBufferImpl.h"
+# endif
+#endif
 
 #if defined(ENABLE_JVMTI)
-# include "native/jvmti/jvmti.h"
+# include "native/jvmti/cacaodbg.h"
 #endif
 
-#if defined(USE_THREADS)
-# if defined(NATIVE_THREADS)
-#  include "threads/native/threads.h"
-# else
-#  include "threads/green/threads.h"
-# endif
+#include "native/vm/java_lang_Class.h"
+
+#if defined(ENABLE_JAVASE)
+# include "native/vm/java_lang_ClassLoader.h"
+# include "native/vm/reflect.h"
 #endif
 
+#include "threads/lock-common.h"
+#include "threads/threads-common.h"
+
 #include "toolbox/logging.h"
+
 #include "vm/builtin.h"
 #include "vm/exceptions.h"
 #include "vm/global.h"
 #include "vm/initialize.h"
-#include "vm/loader.h"
-#include "vm/options.h"
+#include "vm/primitive.h"
 #include "vm/resolve.h"
-#include "vm/statistics.h"
 #include "vm/stringlocal.h"
+#include "vm/vm.h"
+
 #include "vm/jit/asmpart.h"
 #include "vm/jit/jit.h"
-#include "vm/statistics.h"
-#include "vm/vm.h"
+#include "vm/jit/stacktrace.h"
 
+#include "vmcore/loader.h"
+#include "vmcore/options.h"
+#include "vmcore/statistics.h"
 
-/* pointers to VM and the environment needed by GetJavaVM and GetEnv */
 
-static JavaVM ptr_jvm = (JavaVM) &JNI_JavaVMTable;
-void *ptr_env = (void*) &JNI_JNIEnvTable;
+/* debug **********************************************************************/
 
+#if !defined(NDEBUG)
+# define TRACEJNICALLS(format, ...) \
+    do { \
+        if (opt_TraceJNICalls) { \
+            log_println((format), __VA_ARGS__); \
+        } \
+    } while (0)
+#else
+# define TRACEJNICALLS(format, ...)
+#endif
 
-#define PTR_TO_ITEM(ptr)   ((u8)(size_t)(ptr))
 
 /* global variables ***********************************************************/
 
 /* global reference table *****************************************************/
 
-static java_objectheader **global_ref_table;
+/* hashsize must be power of 2 */
 
-/* jmethodID and jclass caching variables for NewGlobalRef and DeleteGlobalRef*/
-static classinfo *ihmclass = NULL;
-static methodinfo *putmid = NULL;
-static methodinfo *getmid = NULL;
-static methodinfo *removemid = NULL;
+#define HASHTABLE_GLOBAL_REF_SIZE    64 /* initial size of globalref-hash     */
+
+static hashtable *hashtable_global_ref; /* hashtable for globalrefs           */
 
 
 /* direct buffer stuff ********************************************************/
 
+#if defined(ENABLE_JAVASE)
 static classinfo *class_java_nio_Buffer;
 static classinfo *class_java_nio_DirectByteBufferImpl;
 static classinfo *class_java_nio_DirectByteBufferImpl_ReadWrite;
-#if SIZEOF_VOID_P == 8
+
+# if defined(WITH_CLASSPATH_GNU)
+#  if SIZEOF_VOID_P == 8
 static classinfo *class_gnu_classpath_Pointer64;
-#else
+#  else
 static classinfo *class_gnu_classpath_Pointer32;
-#endif
+#  endif
+# endif
 
 static methodinfo *dbbirw_init;
-
-
-/* local reference table ******************************************************/
-
-#if !defined(USE_THREADS)
-localref_table *_no_threads_localref_table;
 #endif
 
 
 /* accessing instance fields macros *******************************************/
 
 #define SET_FIELD(o,type,f,value) \
-    *((type *) ((ptrint) (o) + (ptrint) ((fieldinfo *) (f))->offset)) = (type) (value)
+    *((type *) (((intptr_t) (o)) + ((intptr_t) ((fieldinfo *) (f))->offset))) = (type) (value)
 
 #define GET_FIELD(o,type,f) \
-    *((type *) ((ptrint) (o) + (ptrint) ((fieldinfo *) (f))->offset))
+    *((type *) (((intptr_t) (o)) + ((intptr_t) ((fieldinfo *) (f))->offset)))
 
 
 /* some forward declarations **************************************************/
 
-jobject NewLocalRef(JNIEnv *env, jobject ref);
+jobject _Jv_JNI_NewLocalRef(JNIEnv *env, jobject ref);
+jint _Jv_JNI_EnsureLocalCapacity(JNIEnv* env, jint capacity);
 
 
 /* jni_init ********************************************************************
@@ -169,31 +184,14 @@ jobject NewLocalRef(JNIEnv *env, jobject ref);
 
 bool jni_init(void)
 {
-       /* initalize global reference table */
+       /* create global ref hashtable */
 
-       if (!(ihmclass =
-                 load_class_bootstrap(utf_new_char("java/util/IdentityHashMap"))))
-               return false;
-
-       global_ref_table = GCNEW(jobject);
-
-       if (!(*global_ref_table = native_new_and_init(ihmclass)))
-               return false;
-
-       if (!(getmid = class_resolvemethod(ihmclass, utf_get,
-                                                                          utf_java_lang_Object__java_lang_Object)))
-               return false;
-
-       if (!(putmid = class_resolvemethod(ihmclass, utf_put,
-                                                                          utf_new_char("(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"))))
-               return false;
+       hashtable_global_ref = NEW(hashtable);
 
-       if (!(removemid =
-                 class_resolvemethod(ihmclass, utf_remove,
-                                                         utf_java_lang_Object__java_lang_Object)))
-               return false;
+       hashtable_create(hashtable_global_ref, HASHTABLE_GLOBAL_REF_SIZE);
 
 
+#if defined(ENABLE_JAVASE)
        /* direct buffer stuff */
 
        if (!(class_java_nio_Buffer =
@@ -201,6 +199,7 @@ bool jni_init(void)
                !link_class(class_java_nio_Buffer))
                return false;
 
+# if defined(WITH_CLASSPATH_GNU)
        if (!(class_java_nio_DirectByteBufferImpl =
                  load_class_bootstrap(utf_new_char("java/nio/DirectByteBufferImpl"))) ||
                !link_class(class_java_nio_DirectByteBufferImpl))
@@ -217,278 +216,139 @@ bool jni_init(void)
                                                        utf_new_char("(Ljava/lang/Object;Lgnu/classpath/Pointer;III)V"))))
                return false;
 
-#if SIZEOF_VOID_P == 8
+#  if SIZEOF_VOID_P == 8
        if (!(class_gnu_classpath_Pointer64 =
                  load_class_bootstrap(utf_new_char("gnu/classpath/Pointer64"))) ||
                !link_class(class_gnu_classpath_Pointer64))
                return false;
-#else
+#  else
        if (!(class_gnu_classpath_Pointer32 =
                  load_class_bootstrap(utf_new_char("gnu/classpath/Pointer32"))) ||
                !link_class(class_gnu_classpath_Pointer32))
                return false;
-#endif
+#  endif
+# endif
+#endif /* defined(ENABLE_JAVASE) */
 
        return true;
 }
 
 
-static void fill_callblock_from_vargs(void *obj, methoddesc *descr,
-                                                                         jni_callblock blk[], va_list data,
-                                                                         s4 rettype)
+/* _Jv_jni_CallObjectMethod ****************************************************
+
+   Internal function to call Java Object methods.
+
+*******************************************************************************/
+
+static java_handle_t *_Jv_jni_CallObjectMethod(java_handle_t *o,
+                                                                                          vftbl_t *vftbl,
+                                                                                          methodinfo *m, va_list ap)
 {
-       typedesc *paramtypes;
-       s4        i;
-
-       paramtypes = descr->paramtypes;
-
-       /* if method is non-static fill first block and skip `this' pointer */
-
-       i = 0;
-
-       if (obj != NULL) {
-               /* the `this' pointer */
-               blk[0].itemtype = TYPE_ADR;
-               blk[0].item = PTR_TO_ITEM(obj);
-
-               paramtypes++;
-               i++;
-       } 
-
-       for (; i < descr->paramcount; i++, paramtypes++) {
-               switch (paramtypes->decltype) {
-               /* primitive types */
-               case PRIMITIVETYPE_BYTE:
-               case PRIMITIVETYPE_CHAR:
-               case PRIMITIVETYPE_SHORT: 
-               case PRIMITIVETYPE_BOOLEAN: 
-                       blk[i].itemtype = TYPE_INT;
-                       blk[i].item = (s8) va_arg(data, s4);
-                       break;
-
-               case PRIMITIVETYPE_INT:
-                       blk[i].itemtype = TYPE_INT;
-                       blk[i].item = (s8) va_arg(data, s4);
-                       break;
-
-               case PRIMITIVETYPE_LONG:
-                       blk[i].itemtype = TYPE_LNG;
-                       blk[i].item = (s8) va_arg(data, s8);
-                       break;
-
-               case PRIMITIVETYPE_FLOAT:
-                       blk[i].itemtype = TYPE_FLT;
-#if defined(__ALPHA__)
-                       /* this keeps the assembler function much simpler */
-
-                       *((jdouble *) (&blk[i].item)) = (jdouble) va_arg(data, jdouble);
-#else
-                       *((jfloat *) (&blk[i].item)) = (jfloat) va_arg(data, jdouble);
-#endif
-                       break;
+       methodinfo    *resm;
+       java_handle_t *ro;
 
-               case PRIMITIVETYPE_DOUBLE:
-                       blk[i].itemtype = TYPE_DBL;
-                       *((jdouble *) (&blk[i].item)) = (jdouble) va_arg(data, jdouble);
-                       break;
+       STATISTICS(jniinvokation());
 
-               case TYPE_ADR: 
-                       blk[i].itemtype = TYPE_ADR;
-                       blk[i].item = PTR_TO_ITEM(va_arg(data, void*));
-                       break;
-               }
+       if (m == NULL) {
+               exceptions_throw_nullpointerexception();
+               return NULL;
        }
 
-       /* The standard doesn't say anything about return value checking,
-          but it appears to be useful. */
+       /* Class initialization is done by the JIT compiler.  This is ok
+          since a static method always belongs to the declaring class. */
+
+       if (m->flags & ACC_STATIC) {
+               /* For static methods we reset the object. */
 
-       if (rettype != descr->returntype.decltype)
-               log_text("\n====\nWarning call*Method called for function with wrong return type\n====");
-}
+               if (o != NULL)
+                       o = NULL;
 
+               /* for convenience */
 
-/* XXX it could be considered if we should do typechecking here in the future */
+               resm = m;
 
-static bool fill_callblock_from_objectarray(void *obj, methoddesc *descr,
-                                                                                       jni_callblock blk[],
-                                                                                       java_objectarray *params)
-{
-       java_objectheader *param;
-       s4                 paramcount;
-       typedesc          *paramtypes;
-       classinfo         *c;
-       s4                 i;
-       s4                 j;
+       } else {
+               /* For instance methods we make a virtual function table lookup. */
 
-       paramcount = descr->paramcount;
-       paramtypes = descr->paramtypes;
+               resm = method_vftbl_lookup(vftbl, m);
+       }
 
-       /* if method is non-static fill first block and skip `this' pointer */
+       STATISTICS(jnicallXmethodnvokation());
 
-       i = 0;
+       ro = vm_call_method_valist(resm, o, ap);
 
-       if (obj) {
-               /* this pointer */
-               blk[0].itemtype = TYPE_ADR;
-               blk[0].item = PTR_TO_ITEM(obj);
+       return ro;
+}
 
-               paramtypes++;
-               paramcount--;
-               i++;
-       }
 
-       for (j = 0; j < paramcount; i++, j++, paramtypes++) {
-               switch (paramtypes->type) {
-               /* primitive types */
-               case TYPE_INT:
-               case TYPE_LONG:
-               case TYPE_FLOAT:
-               case TYPE_DOUBLE:
-                       param = params->data[j];
-                       if (!param)
-                               goto illegal_arg;
+/* _Jv_jni_CallObjectMethodA ***************************************************
 
-                       /* internally used data type */
-                       blk[i].itemtype = paramtypes->type;
+   Internal function to call Java Object methods.
 
-                       /* convert the value according to its declared type */
+*******************************************************************************/
 
-                       c = param->vftbl->class;
+static java_handle_t *_Jv_jni_CallObjectMethodA(java_handle_t *o,
+                                                                                               vftbl_t *vftbl,
+                                                                                               methodinfo *m,
+                                                                                               const jvalue *args)
+{
+       methodinfo    *resm;
+       java_handle_t *ro;
 
-                       switch (paramtypes->decltype) {
-                       case PRIMITIVETYPE_BOOLEAN:
-                               if (c == primitivetype_table[paramtypes->decltype].class_wrap)
-                                       blk[i].item = (s8) ((java_lang_Boolean *) param)->value;
-                               else
-                                       goto illegal_arg;
-                               break;
+       STATISTICS(jniinvokation());
 
-                       case PRIMITIVETYPE_BYTE:
-                               if (c == primitivetype_table[paramtypes->decltype].class_wrap)
-                                       blk[i].item = (s8) ((java_lang_Byte *) param)->value;
-                               else
-                                       goto illegal_arg;
-                               break;
+       if (m == NULL) {
+               exceptions_throw_nullpointerexception();
+               return NULL;
+       }
 
-                       case PRIMITIVETYPE_CHAR:
-                               if (c == primitivetype_table[paramtypes->decltype].class_wrap)
-                                       blk[i].item = (s8) ((java_lang_Character *) param)->value;
-                               else
-                                       goto illegal_arg;
-                               break;
-
-                       case PRIMITIVETYPE_SHORT:
-                               if (c == primitivetype_table[paramtypes->decltype].class_wrap)
-                                       blk[i].item = (s8) ((java_lang_Short *) param)->value;
-                               else if (c == primitivetype_table[PRIMITIVETYPE_BYTE].class_wrap)
-                                       blk[i].item = (s8) ((java_lang_Byte *) param)->value;
-                               else
-                                       goto illegal_arg;
-                               break;
-
-                       case PRIMITIVETYPE_INT:
-                               if (c == primitivetype_table[paramtypes->decltype].class_wrap)
-                                       blk[i].item = (s8) ((java_lang_Integer *) param)->value;
-                               else if (c == primitivetype_table[PRIMITIVETYPE_SHORT].class_wrap)
-                                       blk[i].item = (s8) ((java_lang_Short *) param)->value;
-                               else if (c == primitivetype_table[PRIMITIVETYPE_BYTE].class_wrap)
-                                       blk[i].item = (s8) ((java_lang_Byte *) param)->value;
-                               else
-                                       goto illegal_arg;
-                               break;
-
-                       case PRIMITIVETYPE_LONG:
-                               if (c == primitivetype_table[paramtypes->decltype].class_wrap)
-                                       blk[i].item = (s8) ((java_lang_Long *) param)->value;
-                               else if (c == primitivetype_table[PRIMITIVETYPE_INT].class_wrap)
-                                       blk[i].item = (s8) ((java_lang_Integer *) param)->value;
-                               else if (c == primitivetype_table[PRIMITIVETYPE_SHORT].class_wrap)
-                                       blk[i].item = (s8) ((java_lang_Short *) param)->value;
-                               else if (c == primitivetype_table[PRIMITIVETYPE_BYTE].class_wrap)
-                                       blk[i].item = (s8) ((java_lang_Byte *) param)->value;
-                               else
-                                       goto illegal_arg;
-                               break;
+       /* Class initialization is done by the JIT compiler.  This is ok
+          since a static method always belongs to the declaring class. */
 
-                       case PRIMITIVETYPE_FLOAT:
-                               if (c == primitivetype_table[paramtypes->decltype].class_wrap)
-                                       *((jfloat *) (&blk[i].item)) = (jfloat) ((java_lang_Float *) param)->value;
-                               else
-                                       goto illegal_arg;
-                               break;
-
-                       case PRIMITIVETYPE_DOUBLE:
-                               if (c == primitivetype_table[paramtypes->decltype].class_wrap)
-                                       *((jdouble *) (&blk[i].item)) = (jdouble) ((java_lang_Double *) param)->value;
-                               else if (c == primitivetype_table[PRIMITIVETYPE_FLOAT].class_wrap)
-                                       *((jfloat *) (&blk[i].item)) = (jfloat) ((java_lang_Float *) param)->value;
-                               else
-                                       goto illegal_arg;
-                               break;
+       if (m->flags & ACC_STATIC) {
+               /* For static methods we reset the object. */
 
-                       default:
-                               goto illegal_arg;
-                       } /* end declared type switch */
-                       break;
-               
-                       case TYPE_ADDRESS:
-                               if (!resolve_class_from_typedesc(paramtypes, true, true, &c))
-                                       return false;
+               if (o != NULL)
+                       o = NULL;
 
-                               if (params->data[j] != 0) {
-                                       if (paramtypes->arraydim > 0) {
-                                               if (!builtin_arrayinstanceof(params->data[j], c))
-                                                       goto illegal_arg;
+               /* for convenience */
 
-                                       } else {
-                                               if (!builtin_instanceof(params->data[j], c))
-                                                       goto illegal_arg;
-                                       }
-                               }
-                               blk[i].itemtype = TYPE_ADR;
-                               blk[i].item = PTR_TO_ITEM(params->data[j]);
-                               break;                  
+               resm = m;
 
-                       default:
-                               goto illegal_arg;
-               } /* end param type switch */
+       } else {
+               /* For instance methods we make a virtual function table lookup. */
 
-       } /* end param loop */
+               resm = method_vftbl_lookup(vftbl, m);
+       }
 
-/*     if (rettype) */
-/*             *rettype = descr->returntype.decltype; */
+       STATISTICS(jnicallXmethodnvokation());
 
-       return true;
+       ro = vm_call_method_jvalue(resm, o, args);
 
-illegal_arg:
-       exceptions_throw_illegalargumentexception();
-       return false;
+       return ro;
 }
 
 
-/* _Jv_jni_CallObjectMethod ****************************************************
+/* _Jv_jni_CallIntMethod *******************************************************
 
-   Internal function to call Java Object methods.
+   Internal function to call Java integer class methods (boolean,
+   byte, char, short, int).
 
 *******************************************************************************/
 
-static java_objectheader *_Jv_jni_CallObjectMethod(java_objectheader *o,
-                                                                                                  vftbl_t *vftbl,
-                                                                                                  methodinfo *m, va_list ap)
+static jint _Jv_jni_CallIntMethod(java_handle_t *o, vftbl_t *vftbl,
+                                                                 methodinfo *m, va_list ap)
 {
-       methodinfo        *resm;
-       s4                 paramcount;
-       jni_callblock     *blk;
-       java_objectheader *ret;
-       s4                 dumpsize;
+       methodinfo *resm;
+       jint        i;
 
        STATISTICS(jniinvokation());
 
        if (m == NULL) {
                exceptions_throw_nullpointerexception();
-               return NULL;
+               return 0;
        }
-
+        
        /* Class initialization is done by the JIT compiler.  This is ok
           since a static method always belongs to the declaring class. */
 
@@ -508,45 +368,26 @@ static java_objectheader *_Jv_jni_CallObjectMethod(java_objectheader *o,
                resm = method_vftbl_lookup(vftbl, m);
        }
 
-       /* mark start of dump memory area */
-
-       dumpsize = dump_size();
-
-       paramcount = resm->parseddesc->paramcount;
-
-       blk = DMNEW(jni_callblock, paramcount);
-
-       fill_callblock_from_vargs(o, resm->parseddesc, blk, ap, TYPE_ADR);
-
        STATISTICS(jnicallXmethodnvokation());
 
-       ASM_CALLJAVAFUNCTION2_ADR(ret, resm, paramcount,
-                                                         paramcount * sizeof(jni_callblock),
-                                                         blk);
+       i = vm_call_method_int_valist(resm, o, ap);
 
-       /* release dump area */
-
-       dump_release(dumpsize);
-
-       return ret;
+       return i;
 }
 
 
-/* _Jv_jni_CallIntMethod *******************************************************
+/* _Jv_jni_CallIntMethod******************************************************
 
    Internal function to call Java integer class methods (boolean,
    byte, char, short, int).
 
 *******************************************************************************/
 
-static jint _Jv_jni_CallIntMethod(java_objectheader *o, vftbl_t *vftbl,
-                                                                 methodinfo *m, va_list ap, s4 type)
+static jint _Jv_jni_CallIntMethodA(java_handle_t *o, vftbl_t *vftbl,
+                                                                  methodinfo *m, const jvalue *args)
 {
-       methodinfo    *resm;
-       s4             paramcount;
-       jni_callblock *blk;
-       jint           ret;
-       s4             dumpsize;
+       methodinfo *resm;
+       jint        i;
 
        STATISTICS(jniinvokation());
 
@@ -574,27 +415,11 @@ static jint _Jv_jni_CallIntMethod(java_objectheader *o, vftbl_t *vftbl,
                resm = method_vftbl_lookup(vftbl, m);
        }
 
-       /* mark start of dump memory area */
-
-       dumpsize = dump_size();
-
-       paramcount = resm->parseddesc->paramcount;
-
-       blk = DMNEW(jni_callblock, paramcount);
-
-       fill_callblock_from_vargs(o, resm->parseddesc, blk, ap, type);
-
        STATISTICS(jnicallXmethodnvokation());
 
-       ASM_CALLJAVAFUNCTION2_INT(ret, resm, paramcount,
-                                                         paramcount * sizeof(jni_callblock),
-                                                         blk);
+       i = vm_call_method_int_jvalue(resm, o, args);
 
-       /* release dump area */
-
-       dump_release(dumpsize);
-
-       return ret;
+       return i;
 }
 
 
@@ -604,14 +429,11 @@ static jint _Jv_jni_CallIntMethod(java_objectheader *o, vftbl_t *vftbl,
 
 *******************************************************************************/
 
-static jlong _Jv_jni_CallLongMethod(java_objectheader *o, vftbl_t *vftbl,
+static jlong _Jv_jni_CallLongMethod(java_handle_t *o, vftbl_t *vftbl,
                                                                        methodinfo *m, va_list ap)
 {
-       methodinfo    *resm;
-       s4             paramcount;
-       jni_callblock *blk;
-       jlong          ret;
-       s4             dumpsize;
+       methodinfo *resm;
+       jlong       l;
 
        STATISTICS(jniinvokation());
 
@@ -639,27 +461,57 @@ static jlong _Jv_jni_CallLongMethod(java_objectheader *o, vftbl_t *vftbl,
                resm = method_vftbl_lookup(vftbl, m);
        }
 
-       /* mark start of dump memory area */
+       STATISTICS(jnicallXmethodnvokation());
 
-       dumpsize = dump_size();
+       l = vm_call_method_long_valist(resm, o, ap);
+
+       return l;
+}
 
-       paramcount = resm->parseddesc->paramcount;
 
-       blk = DMNEW(jni_callblock, paramcount);
+/* _Jv_jni_CallLongMethodA *****************************************************
 
-       fill_callblock_from_vargs(o, resm->parseddesc, blk, ap, PRIMITIVETYPE_LONG);
+   Internal function to call Java long methods.
 
-       STATISTICS(jnicallXmethodnvokation());
+*******************************************************************************/
 
-       ASM_CALLJAVAFUNCTION2_LONG(ret, resm, paramcount,
-                                                          paramcount * sizeof(jni_callblock),
-                                                          blk);
+static jlong _Jv_jni_CallLongMethodA(java_handle_t *o, vftbl_t *vftbl,
+                                                                        methodinfo *m, const jvalue *args)
+{
+       methodinfo *resm;
+       jlong       l;
 
-       /* release dump area */
+       STATISTICS(jniinvokation());
 
-       dump_release(dumpsize);
+       if (m == NULL) {
+               exceptions_throw_nullpointerexception();
+               return 0;
+       }
+
+       /* Class initialization is done by the JIT compiler.  This is ok
+          since a static method always belongs to the declaring class. */
+
+       if (m->flags & ACC_STATIC) {
+               /* For static methods we reset the object. */
 
-       return ret;
+               if (o != NULL)
+                       o = NULL;
+
+               /* for convenience */
+
+               resm = m;
+       }
+       else {
+               /* For instance methods we make a virtual function table lookup. */
+
+               resm = method_vftbl_lookup(vftbl, m);
+       }
+
+       STATISTICS(jnicallXmethodnvokation());
+
+       l = vm_call_method_long_jvalue(resm, o, args);
+
+       return l;
 }
 
 
@@ -669,14 +521,11 @@ static jlong _Jv_jni_CallLongMethod(java_objectheader *o, vftbl_t *vftbl,
 
 *******************************************************************************/
 
-static jfloat _Jv_jni_CallFloatMethod(java_objectheader *o, vftbl_t *vftbl,
+static jfloat _Jv_jni_CallFloatMethod(java_handle_t *o, vftbl_t *vftbl,
                                                                          methodinfo *m, va_list ap)
 {
-       methodinfo    *resm;
-       s4             paramcount;
-       jni_callblock *blk;
-       jdouble        ret;
-       s4             dumpsize;
+       methodinfo *resm;
+       jfloat      f;
 
        /* Class initialization is done by the JIT compiler.  This is ok
           since a static method always belongs to the declaring class. */
@@ -697,45 +546,25 @@ static jfloat _Jv_jni_CallFloatMethod(java_objectheader *o, vftbl_t *vftbl,
                resm = method_vftbl_lookup(vftbl, m);
        }
 
-       /* mark start of dump memory area */
-
-       dumpsize = dump_size();
-
-       paramcount = resm->parseddesc->paramcount;
-
-       blk = DMNEW(jni_callblock, paramcount);
-
-       fill_callblock_from_vargs(o, resm->parseddesc, blk, ap,
-                                                         PRIMITIVETYPE_FLOAT);
-
        STATISTICS(jnicallXmethodnvokation());
 
-       ASM_CALLJAVAFUNCTION2_FLOAT(ret, resm, paramcount,
-                                                               paramcount * sizeof(jni_callblock),
-                                                               blk);
-
-       /* release dump area */
-
-       dump_release(dumpsize);
+       f = vm_call_method_float_valist(resm, o, ap);
 
-       return ret;
+       return f;
 }
 
 
-/* _Jv_jni_CallDoubleMethod ****************************************************
+/* _Jv_jni_CallFloatMethodA ****************************************************
 
-   Internal function to call Java double methods.
+   Internal function to call Java float methods.
 
 *******************************************************************************/
 
-static jdouble _Jv_jni_CallDoubleMethod(java_objectheader *o, vftbl_t *vftbl,
-                                                                               methodinfo *m, va_list ap)
+static jfloat _Jv_jni_CallFloatMethodA(java_handle_t *o, vftbl_t *vftbl,
+                                                                          methodinfo *m, const jvalue *args)
 {
-       methodinfo    *resm;
-       s4             paramcount;
-       jni_callblock *blk;
-       jfloat         ret;
-       s4             dumpsize;
+       methodinfo *resm;
+       jfloat      f;
 
        /* Class initialization is done by the JIT compiler.  This is ok
           since a static method always belongs to the declaring class. */
@@ -749,56 +578,32 @@ static jdouble _Jv_jni_CallDoubleMethod(java_objectheader *o, vftbl_t *vftbl,
                /* for convenience */
 
                resm = m;
-
-       else {
+       }
+       else {
                /* For instance methods we make a virtual function table lookup. */
 
                resm = method_vftbl_lookup(vftbl, m);
        }
 
-       /* mark start of dump memory area */
-
-       dumpsize = dump_size();
-
-       paramcount = resm->parseddesc->paramcount;
-
-       blk = DMNEW(jni_callblock, paramcount);
-
-       fill_callblock_from_vargs(o, resm->parseddesc, blk, ap,
-                                                         PRIMITIVETYPE_DOUBLE);
-
        STATISTICS(jnicallXmethodnvokation());
 
-       ASM_CALLJAVAFUNCTION2_DOUBLE(ret, resm, paramcount,
-                                                                paramcount * sizeof(jni_callblock),
-                                                                blk);
+       f = vm_call_method_float_jvalue(resm, o, args);
 
-       /* release dump area */
-
-       dump_release(dumpsize);
-
-       return ret;
+       return f;
 }
 
 
-/* _Jv_jni_CallVoidMethod ******************************************************
+/* _Jv_jni_CallDoubleMethod ****************************************************
 
-   Internal function to call Java void methods.
+   Internal function to call Java double methods.
 
 *******************************************************************************/
 
-static void _Jv_jni_CallVoidMethod(java_objectheader *o, vftbl_t *vftbl,
-                                                                  methodinfo *m, va_list ap)
-{      
-       methodinfo    *resm;
-       s4             paramcount;
-       jni_callblock *blk;
-       s4             dumpsize;
-
-       if (m == NULL) {
-               exceptions_throw_nullpointerexception();
-               return;
-       }
+static jdouble _Jv_jni_CallDoubleMethod(java_handle_t *o, vftbl_t *vftbl,
+                                                                               methodinfo *m, va_list ap)
+{
+       methodinfo *resm;
+       jdouble     d;
 
        /* Class initialization is done by the JIT compiler.  This is ok
           since a static method always belongs to the declaring class. */
@@ -819,287 +624,279 @@ static void _Jv_jni_CallVoidMethod(java_objectheader *o, vftbl_t *vftbl,
                resm = method_vftbl_lookup(vftbl, m);
        }
 
-       /* mark start of dump memory area */
-
-       dumpsize = dump_size();
+       d = vm_call_method_double_valist(resm, o, ap);
 
-       paramcount = resm->parseddesc->paramcount;
+       return d;
+}
 
-       blk = DMNEW(jni_callblock, paramcount);
 
-       fill_callblock_from_vargs(o, resm->parseddesc, blk, ap, TYPE_VOID);
+/* _Jv_jni_CallDoubleMethodA ***************************************************
 
-       STATISTICS(jnicallXmethodnvokation());
+   Internal function to call Java double methods.
 
-       ASM_CALLJAVAFUNCTION2(resm, paramcount,
-                                                 paramcount * sizeof(jni_callblock),
-                                                 blk);
+*******************************************************************************/
 
-       /* release dump area */
+static jdouble _Jv_jni_CallDoubleMethodA(java_handle_t *o, vftbl_t *vftbl,
+                                                                                methodinfo *m, const jvalue *args)
+{
+       methodinfo *resm;
+       jdouble     d;
 
-       dump_release(dumpsize);
-}
+       /* Class initialization is done by the JIT compiler.  This is ok
+          since a static method always belongs to the declaring class. */
 
+       if (m->flags & ACC_STATIC) {
+               /* For static methods we reset the object. */
 
-/* _Jv_jni_invokeNative ********************************************************
+               if (o != NULL)
+                       o = NULL;
 
-   Invoke a method on the given object with the given arguments.
+               /* for convenience */
 
-   For instance methods OBJ must be != NULL and the method is looked up
-   in the vftbl of the object.
+               resm = m;
+       }
+       else {
+               /* For instance methods we make a virtual function table lookup. */
+
+               resm = method_vftbl_lookup(vftbl, m);
+       }
+
+       d = vm_call_method_double_jvalue(resm, o, args);
+
+       return d;
+}
 
-   For static methods, OBJ is ignored.
+
+/* _Jv_jni_CallVoidMethod ******************************************************
+
+   Internal function to call Java void methods.
 
 *******************************************************************************/
 
-java_objectheader *_Jv_jni_invokeNative(methodinfo *m, java_objectheader *o,
-                                                                               java_objectarray *params)
-{
-       methodinfo        *resm;
-       jni_callblock     *blk;
-       java_objectheader *ro;
-       s4                 argcount;
-       s4                 paramcount;
+static void _Jv_jni_CallVoidMethod(java_handle_t *o, vftbl_t *vftbl,
+                                                                  methodinfo *m, va_list ap)
+{      
+       methodinfo *resm;
 
-       if (!m) {
+       if (m == NULL) {
                exceptions_throw_nullpointerexception();
-               return NULL;
+               return;
        }
 
-       argcount = m->parseddesc->paramcount;
-       paramcount = argcount;
+       /* Class initialization is done by the JIT compiler.  This is ok
+          since a static method always belongs to the declaring class. */
 
-       /* if method is non-static, remove the `this' pointer */
+       if (m->flags & ACC_STATIC) {
+               /* For static methods we reset the object. */
 
-       if (!(m->flags & ACC_STATIC))
-               paramcount--;
+               if (o != NULL)
+                       o = NULL;
 
-       /* For instance methods the object has to be an instance of the
-          class the method belongs to. For static methods the obj
-          parameter is ignored. */
+               /* for convenience */
 
-       if (!(m->flags & ACC_STATIC) && o &&
-               (!builtin_instanceof(o, m->class)))
-       {
-               *exceptionptr =
-                       new_exception_message(string_java_lang_IllegalArgumentException,
-                                                                 "Object parameter of wrong type in Java_java_lang_reflect_Method_invokeNative");
-               return NULL;
-       }
+               resm = m;
 
-       /* check if we got the right number of arguments */
+       } else {
+               /* For instance methods we make a virtual function table lookup. */
 
-       if (((params == NULL) && (paramcount != 0)) ||
-               (params && (params->header.size != paramcount))) 
-       {
-               *exceptionptr =
-                       new_exception(string_java_lang_IllegalArgumentException);
-               return NULL;
+               resm = method_vftbl_lookup(vftbl, m);
        }
 
-       /* for instance methods we need an object */
+       STATISTICS(jnicallXmethodnvokation());
 
-       if (!(m->flags & ACC_STATIC) && (o == NULL)) {
-               *exceptionptr =
-                       new_exception_message(string_java_lang_NullPointerException,
-                                                                 "Static mismatch in Java_java_lang_reflect_Method_invokeNative");
-               return NULL;
-       }
+       (void) vm_call_method_valist(resm, o, ap);
+}
 
-       /* for static methods, zero object to make subsequent code simpler */
-       if (m->flags & ACC_STATIC)
-               o = NULL;
 
-       if (o != NULL) {
-               /* for instance methods we must do a vftbl lookup */
-               resm = method_vftbl_lookup(o->vftbl, m);
+/* _Jv_jni_CallVoidMethodA *****************************************************
 
-       } else {
-               /* for static methods, just for convenience */
-               resm = m;
-       }
+   Internal function to call Java void methods.
 
-       blk = MNEW(jni_callblock, argcount);
+*******************************************************************************/
 
-       if (!fill_callblock_from_objectarray(o, resm->parseddesc, blk, params))
-               return NULL;
+static void _Jv_jni_CallVoidMethodA(java_handle_t *o, vftbl_t *vftbl,
+                                                                       methodinfo *m, const jvalue *args)
+{      
+       methodinfo *resm;
 
-       switch (resm->parseddesc->returntype.decltype) {
-       case TYPE_VOID:
-               ASM_CALLJAVAFUNCTION2(resm, argcount,
-                                                         argcount * sizeof(jni_callblock),
-                                                         blk);
+       if (m == NULL) {
+               exceptions_throw_nullpointerexception();
+               return;
+       }
 
-               ro = NULL;
-               break;
+       /* Class initialization is done by the JIT compiler.  This is ok
+          since a static method always belongs to the declaring class. */
+
+       if (m->flags & ACC_STATIC) {
+               /* For static methods we reset the object. */
 
-       case PRIMITIVETYPE_BOOLEAN: {
-               s4 i;
-               java_lang_Boolean *bo;
+               if (o != NULL)
+                       o = NULL;
 
-               ASM_CALLJAVAFUNCTION2_INT(i, resm, argcount,
-                                                                 argcount * sizeof(jni_callblock),
-                                                                 blk);
+               /* for convenience */
 
-               ro = builtin_new(class_java_lang_Boolean);
+               resm = m;
 
-               /* setting the value of the object direct */
+       } else {
+               /* For instance methods we make a virtual function table lookup. */
 
-               bo = (java_lang_Boolean *) ro;
-               bo->value = i;
+               resm = method_vftbl_lookup(vftbl, m);
        }
-       break;
 
-       case PRIMITIVETYPE_BYTE: {
-               s4 i;
-               java_lang_Byte *bo;
+       STATISTICS(jnicallXmethodnvokation());
 
-               ASM_CALLJAVAFUNCTION2_INT(i, resm, argcount,
-                                                                 argcount * sizeof(jni_callblock),
-                                                                 blk);
+       (void) vm_call_method_jvalue(resm, o, args);
+}
 
-               ro = builtin_new(class_java_lang_Byte);
 
-               /* setting the value of the object direct */
+/* _Jv_jni_invokeNative ********************************************************
 
-               bo = (java_lang_Byte *) ro;
-               bo->value = i;
-       }
-       break;
+   Invoke a method on the given object with the given arguments.
 
-       case PRIMITIVETYPE_CHAR: {
-               s4 i;
-               java_lang_Character *co;
+   For instance methods OBJ must be != NULL and the method is looked up
+   in the vftbl of the object.
 
-               ASM_CALLJAVAFUNCTION2_INT(i, resm, argcount,
-                                                                 argcount * sizeof(jni_callblock),
-                                                                 blk);
+   For static methods, OBJ is ignored.
 
-               ro = builtin_new(class_java_lang_Character);
+*******************************************************************************/
 
-               /* setting the value of the object direct */
+java_handle_t *_Jv_jni_invokeNative(methodinfo *m, java_handle_t *o,
+                                                                       java_handle_objectarray_t *params)
+{
+       methodinfo    *resm;
+       java_handle_t *ro;
+       s4             argcount;
+       s4             paramcount;
+       java_handle_t *xptr;
+       int32_t        dumpsize;
+       uint64_t      *array;
+       imm_union          value;
 
-               co = (java_lang_Character *) ro;
-               co->value = i;
+       if (m == NULL) {
+               exceptions_throw_nullpointerexception();
+               return NULL;
        }
-       break;
 
-       case PRIMITIVETYPE_SHORT: {
-               s4 i;
-               java_lang_Short *so;
+       argcount = m->parseddesc->paramcount;
+       paramcount = argcount;
 
-               ASM_CALLJAVAFUNCTION2_INT(i, resm, argcount,
-                                                                 argcount * sizeof(jni_callblock),
-                                                                 blk);
+       /* if method is non-static, remove the `this' pointer */
 
-               ro = builtin_new(class_java_lang_Short);
+       if (!(m->flags & ACC_STATIC))
+               paramcount--;
 
-               /* setting the value of the object direct */
+       /* For instance methods the object has to be an instance of the
+          class the method belongs to. For static methods the obj
+          parameter is ignored. */
 
-               so = (java_lang_Short *) ro;
-               so->value = i;
+       if (!(m->flags & ACC_STATIC) && o && (!builtin_instanceof(o, m->class))) {
+               exceptions_throw_illegalargumentexception();
+               return NULL;
        }
-       break;
 
-       case PRIMITIVETYPE_INT: {
-               s4 i;
-               java_lang_Integer *io;
-
-               ASM_CALLJAVAFUNCTION2_INT(i, resm, argcount,
-                                                                 argcount * sizeof(jni_callblock),
-                                                                 blk);
+       /* check if we got the right number of arguments */
 
-               ro = builtin_new(class_java_lang_Integer);
+       if (((params == NULL) && (paramcount != 0)) ||
+               (params && (LLNI_array_size(params) != paramcount))) 
+       {
+               exceptions_throw_illegalargumentexception();
+               return NULL;
+       }
 
-               /* setting the value of the object direct */
+       /* for instance methods we need an object */
 
-               io = (java_lang_Integer *) ro;
-               io->value = i;
+       if (!(m->flags & ACC_STATIC) && (o == NULL)) {
+               /* XXX not sure if that is the correct exception */
+               exceptions_throw_nullpointerexception();
+               return NULL;
        }
-       break;
 
-       case PRIMITIVETYPE_LONG: {
-               s8 l;
-               java_lang_Long *lo;
+       /* for static methods, zero object to make subsequent code simpler */
+       if (m->flags & ACC_STATIC)
+               o = NULL;
 
-               ASM_CALLJAVAFUNCTION2_LONG(l, resm, argcount,
-                                                                  argcount * sizeof(jni_callblock),
-                                                                  blk);
+       if (o != NULL) {
+               /* for instance methods we must do a vftbl lookup */
+               resm = method_vftbl_lookup(o->vftbl, m);
+       }
+       else {
+               /* for static methods, just for convenience */
+               resm = m;
+       }
 
-               ro = builtin_new(class_java_lang_Long);
+       /* mark start of dump memory area */
 
-               /* setting the value of the object direct */
+       dumpsize = dump_size();
 
-               lo = (java_lang_Long *) ro;
-               lo->value = l;
-       }
-       break;
+       /* Fill the argument array from a object-array. */
 
-       case PRIMITIVETYPE_FLOAT: {
-               float f;
-               java_lang_Float *fo;
+       array = vm_array_from_objectarray(resm, o, params);
 
-               ASM_CALLJAVAFUNCTION2_FLOAT(f, resm, argcount,
-                                                                       argcount * sizeof(jni_callblock),
-                                                                       blk);
+       /* The array can be NULL if we don't have any arguments to pass
+          and the architecture does not have any argument registers
+          (e.g. i386).  In that case we additionally check for an
+          exception thrown. */
 
-               ro = builtin_new(class_java_lang_Float);
+       if ((array == NULL) && (exceptions_get_exception() != NULL)) {
+               /* release dump area */
 
-               /* setting the value of the object direct */
+               dump_release(dumpsize);
 
-               fo = (java_lang_Float *) ro;
-               fo->value = f;
+               return NULL;
        }
-       break;
 
-       case PRIMITIVETYPE_DOUBLE: {
-               double d;
-               java_lang_Double *_do;
+       switch (resm->parseddesc->returntype.decltype) {
+       case TYPE_VOID:
+               (void) vm_call_array(resm, array);
+               ro = NULL;
+               break;
 
-               ASM_CALLJAVAFUNCTION2_DOUBLE(d, resm, argcount,
-                                                                        argcount * sizeof(jni_callblock),
-                                                                        blk);
+       case PRIMITIVETYPE_BOOLEAN:
+       case PRIMITIVETYPE_BYTE:
+       case PRIMITIVETYPE_CHAR:
+       case PRIMITIVETYPE_SHORT:
+       case PRIMITIVETYPE_INT:
+               value.i = vm_call_int_array(resm, array);
+               ro = primitive_box(resm->parseddesc->returntype.decltype, value);
+               break;
 
-               ro = builtin_new(class_java_lang_Double);
+       case PRIMITIVETYPE_LONG:
+               value.l = vm_call_long_array(resm, array);
+               ro = primitive_box(resm->parseddesc->returntype.decltype, value);
+               break;
 
-               /* setting the value of the object direct */
+       case PRIMITIVETYPE_FLOAT:
+               value.f = vm_call_float_array(resm, array);
+               ro = primitive_box(resm->parseddesc->returntype.decltype, value);
+               break;
 
-               _do = (java_lang_Double *) ro;
-               _do->value = d;
-       }
-       break;
+       case PRIMITIVETYPE_DOUBLE:
+               value.d = vm_call_double_array(resm, array);
+               ro = primitive_box(resm->parseddesc->returntype.decltype, value);
+               break;
 
        case TYPE_ADR:
-               ASM_CALLJAVAFUNCTION2_ADR(ro, resm, argcount,
-                                                                 argcount * sizeof(jni_callblock),
-                                                                 blk);
+               ro = vm_call_array(resm, array);
                break;
 
        default:
-               /* if this happens the exception has already been set by
-                  fill_callblock_from_objectarray */
-
-               MFREE(blk, jni_callblock, argcount);
-
-               return NULL;
+               vm_abort("_Jv_jni_invokeNative: invalid return type %d", resm->parseddesc->returntype.decltype);
        }
 
-       MFREE(blk, jni_callblock, argcount);
-
-       if (*exceptionptr) {
-               java_objectheader *cause;
-
-               cause = *exceptionptr;
+       xptr = exceptions_get_exception();
 
+       if (xptr != NULL) {
                /* clear exception pointer, we are calling JIT code again */
 
-               *exceptionptr = NULL;
+               exceptions_clear_exception();
 
-               *exceptionptr =
-                       new_exception_throwable(string_java_lang_reflect_InvocationTargetException,
-                                                                       (java_lang_Throwable *) cause);
+               exceptions_throw_invocationtargetexception(xptr);
        }
 
+       /* release dump area */
+
+       dump_release(dumpsize);
+
        return ro;
 }
 
@@ -1111,7 +908,7 @@ java_objectheader *_Jv_jni_invokeNative(methodinfo *m, java_objectheader *o,
 
 *******************************************************************************/
 
-jint GetVersion(JNIEnv *env)
+jint _Jv_JNI_GetVersion(JNIEnv *env)
 {
        STATISTICS(jniinvokation());
 
@@ -1131,24 +928,29 @@ jint GetVersion(JNIEnv *env)
 
 *******************************************************************************/
 
-jclass DefineClass(JNIEnv *env, const char *name, jobject loader,
-                                  const jbyte *buf, jsize bufLen)
+jclass _Jv_JNI_DefineClass(JNIEnv *env, const char *name, jobject loader,
+                                                  const jbyte *buf, jsize bufLen)
 {
-       java_lang_ClassLoader *cl;
-       java_lang_String      *s;
-       java_bytearray        *ba;
-       jclass                 c;
+#if defined(ENABLE_JAVASE)
+       utf         *u;
+       classloader *cl;
+       classinfo   *c;
 
-       STATISTICS(jniinvokation());
+       TRACEJNICALLS("_Jv_JNI_DefineClass(env=%p, name=%s, loader=%p, buf=%p, bufLen=%d)", env, name, loader, buf, bufLen);
+
+       u  = utf_new_char(name);
+       cl = (classloader *) loader;
 
-       cl = (java_lang_ClassLoader *) loader;
-       s = javastring_new_char(name);
-       ba = (java_bytearray *) buf;
+       c = class_define(u, cl, bufLen, (const uint8_t *) buf, NULL);
 
-       c = (jclass) Java_java_lang_VMClassLoader_defineClass(env, NULL, cl, s, ba,
-                                                                                                                 0, bufLen, NULL);
+       return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) c);
+#else
+       vm_abort("_Jv_JNI_DefineClass: not implemented in this configuration");
+
+       /* keep compiler happy */
 
-       return (jclass) NewLocalRef(env, (jobject) c);
+       return 0;
+#endif
 }
 
 
@@ -1160,8 +962,9 @@ jclass DefineClass(JNIEnv *env, const char *name, jobject loader,
 
 *******************************************************************************/
 
-jclass FindClass(JNIEnv *env, const char *name)
+jclass _Jv_JNI_FindClass(JNIEnv *env, const char *name)
 {
+#if defined(ENABLE_JAVASE)
        utf       *u;
        classinfo *cc;
        classinfo *c;
@@ -1184,22 +987,7 @@ jclass FindClass(JNIEnv *env, const char *name)
           its associated class loader. In that case, the result of
           ClassLoader.getBaseClassLoader is used." */
 
-#if defined(__ALPHA__) || defined(__ARM__) || defined(__I386__) || defined(__MIPS__) || defined(__POWERPC__) || defined(__X86_64__)
-       /* these JITs support stacktraces, and so does the interpreter */
-
        cc = stacktrace_getCurrentClass();
-#else
-# if defined(ENABLE_INTRP)
-       /* the interpreter supports stacktraces, even if the JIT does not */
-
-       if (opt_intrp)
-               cc = stacktrace_getCurrentClass();
-       else
-# endif
-               cc = NULL;
-#endif
-
-       /* if no Java method was found, use the system classloader */
 
        if (cc == NULL)
                c = load_class_from_sysloader(u);
@@ -1212,7 +1000,14 @@ jclass FindClass(JNIEnv *env, const char *name)
        if (!link_class(c))
                return NULL;
 
-       return (jclass) NewLocalRef(env, (jobject) c);
+       return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) c);
+#else
+       vm_abort("_Jv_JNI_FindClass: not implemented in this configuration");
+
+       /* keep compiler happy */
+
+       return NULL;
+#endif
 }
   
 
@@ -1224,18 +1019,21 @@ jclass FindClass(JNIEnv *env, const char *name)
 
 *******************************************************************************/
  
-jclass GetSuperclass(JNIEnv *env, jclass sub)
+jclass _Jv_JNI_GetSuperclass(JNIEnv *env, jclass sub)
 {
        classinfo *c;
+       classinfo *super;
 
-       STATISTICS(jniinvokation());
+       TRACEJNICALLS("_Jv_JNI_GetSuperclass(env=%p, sub=%p)", env, sub);
 
-       c = ((classinfo *) sub)->super.cls;
+       c = LLNI_classinfo_unwrap(sub);
 
-       if (!c)
+       if (c == NULL)
                return NULL;
 
-       return (jclass) NewLocalRef(env, (jobject) c);
+       super = class_get_superclass(c);
+
+       return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) super);
 }
   
  
@@ -1245,14 +1043,17 @@ jclass GetSuperclass(JNIEnv *env, jclass sub)
 
 *******************************************************************************/
 
-jboolean IsAssignableFrom(JNIEnv *env, jclass sub, jclass sup)
+jboolean _Jv_JNI_IsAssignableFrom(JNIEnv *env, jclass sub, jclass sup)
 {
+       java_lang_Class *csup;
+       java_lang_Class *csub;
+
+       csup = (java_lang_Class *) sup;
+       csub = (java_lang_Class *) sub;
+
        STATISTICS(jniinvokation());
 
-       return Java_java_lang_VMClass_isAssignableFrom(env,
-                                                                                                  NULL,
-                                                                                                  (java_lang_Class *) sup,
-                                                                                                  (java_lang_Class *) sub);
+       return _Jv_java_lang_Class_isAssignableFrom(csup, csub);
 }
 
 
@@ -1262,11 +1063,15 @@ jboolean IsAssignableFrom(JNIEnv *env, jclass sub, jclass sup)
 
 *******************************************************************************/
 
-jint Throw(JNIEnv *env, jthrowable obj)
+jint _Jv_JNI_Throw(JNIEnv *env, jthrowable obj)
 {
+       java_handle_t *o;
+
        STATISTICS(jniinvokation());
 
-       *exceptionptr = (java_objectheader *) obj;
+       o = (java_handle_t *) obj;
+
+       exceptions_set_exception(o);
 
        return JNI_OK;
 }
@@ -1280,24 +1085,27 @@ jint Throw(JNIEnv *env, jthrowable obj)
 
 *******************************************************************************/
 
-jint ThrowNew(JNIEnv* env, jclass clazz, const char *msg) 
+jint _Jv_JNI_ThrowNew(JNIEnv* env, jclass clazz, const char *msg) 
 {
-       java_lang_Throwable *o;
-       java_lang_String    *s;
+       classinfo     *c;
+       java_handle_t *o;
+       java_handle_t *s;
 
        STATISTICS(jniinvokation());
 
-       s = (java_lang_String *) javastring_new_char(msg);
+       c = LLNI_classinfo_unwrap(clazz);
+       if (msg == NULL)
+               msg = "";
+       s = javastring_new_from_utf_string(msg);
 
        /* instantiate exception object */
 
-       o = (java_lang_Throwable *) native_new_and_init_string((classinfo *) clazz,
-                                                                                                                  s);
+       o = native_new_and_init_string(c, s);
 
-       if (!o)
+       if (o == NULL)
                return -1;
 
-       *exceptionptr = (java_objectheader *) o;
+       exceptions_set_exception(o);
 
        return 0;
 }
@@ -1311,15 +1119,15 @@ jint ThrowNew(JNIEnv* env, jclass clazz, const char *msg)
 
 *******************************************************************************/
 
-jthrowable ExceptionOccurred(JNIEnv *env)
+jthrowable _Jv_JNI_ExceptionOccurred(JNIEnv *env)
 {
-       java_objectheader *e;
+       java_handle_t *o;
 
        STATISTICS(jniinvokation());
 
-       e = *exceptionptr;
+       o = exceptions_get_exception();
 
-       return NewLocalRef(env, (jthrowable) e);
+       return _Jv_JNI_NewLocalRef(env, (jthrowable) o);
 }
 
 
@@ -1331,35 +1139,35 @@ jthrowable ExceptionOccurred(JNIEnv *env)
 
 *******************************************************************************/
 
-void ExceptionDescribe(JNIEnv *env)
+void _Jv_JNI_ExceptionDescribe(JNIEnv *env)
 {
-       java_objectheader *e;
-       methodinfo        *m;
+       java_handle_t *o;
+       methodinfo    *m;
 
        STATISTICS(jniinvokation());
 
-       e = *exceptionptr;
+       o = exceptions_get_exception();
 
-       if (e) {
+       if (o == NULL) {
                /* clear exception, because we are calling jit code again */
 
-               *exceptionptr = NULL;
+               exceptions_clear_exception();
 
                /* get printStackTrace method from exception class */
 
-               m = class_resolveclassmethod(e->vftbl->class,
+               m = class_resolveclassmethod(o->vftbl->class,
                                                                         utf_printStackTrace,
                                                                         utf_void__void,
                                                                         NULL,
                                                                         true);
 
-               if (!m)
+               if (m == NULL)
                        /* XXX what should we do? */
                        return;
 
                /* print the stacktrace */
 
-               ASM_CALLJAVAFUNCTION(m, e, NULL, NULL, NULL);
+               (void) vm_call_method(m, o);
        }
 }
 
@@ -1371,11 +1179,11 @@ void ExceptionDescribe(JNIEnv *env)
 
 *******************************************************************************/
 
-void ExceptionClear(JNIEnv *env)
+void _Jv_JNI_ExceptionClear(JNIEnv *env)
 {
        STATISTICS(jniinvokation());
 
-       *exceptionptr = NULL;
+       exceptions_clear_exception();
 }
 
 
@@ -1386,11 +1194,13 @@ void ExceptionClear(JNIEnv *env)
 
 *******************************************************************************/
 
-void FatalError(JNIEnv *env, const char *msg)
+void _Jv_JNI_FatalError(JNIEnv *env, const char *msg)
 {
        STATISTICS(jniinvokation());
 
-       throw_cacao_exception_exit(string_java_lang_InternalError, msg);
+       /* this seems to be the best way */
+
+       vm_abort("JNI Fatal error: %s", msg);
 }
 
 
@@ -1401,17 +1211,22 @@ void FatalError(JNIEnv *env, const char *msg)
 
 *******************************************************************************/
 
-jint PushLocalFrame(JNIEnv* env, jint capacity)
+jint _Jv_JNI_PushLocalFrame(JNIEnv* env, jint capacity)
 {
        STATISTICS(jniinvokation());
 
-       log_text("JNI-Call: PushLocalFrame: IMPLEMENT ME!");
+       if (capacity <= 0)
+               return -1;
+
+       /* add new local reference frame to current table */
 
-       assert(0);
+       if (!localref_frame_push(capacity))
+               return -1;
 
        return 0;
 }
 
+
 /* PopLocalFrame ***************************************************************
 
    Pops off the current local reference frame, frees all the local
@@ -1420,17 +1235,17 @@ jint PushLocalFrame(JNIEnv* env, jint capacity)
 
 *******************************************************************************/
 
-jobject PopLocalFrame(JNIEnv* env, jobject result)
+jobject _Jv_JNI_PopLocalFrame(JNIEnv* env, jobject result)
 {
        STATISTICS(jniinvokation());
 
-       log_text("JNI-Call: PopLocalFrame: IMPLEMENT ME!");
+       /* release all current local frames */
 
-       assert(0);
+       localref_frame_pop_all();
 
        /* add local reference and return the value */
 
-       return NewLocalRef(env, NULL);
+       return _Jv_JNI_NewLocalRef(env, result);
 }
 
 
@@ -1440,28 +1255,33 @@ jobject PopLocalFrame(JNIEnv* env, jobject result)
 
 *******************************************************************************/
 
-void DeleteLocalRef(JNIEnv *env, jobject localRef)
+void _Jv_JNI_DeleteLocalRef(JNIEnv *env, jobject localRef)
 {
-       java_objectheader *o;
-       localref_table    *lrt;
-       s4                 i;
+       java_handle_t  *o;
+       localref_table *lrt;
+       s4              i;
 
        STATISTICS(jniinvokation());
 
-       o = (java_objectheader *) localRef;
+       o = (java_handle_t *) localRef;
 
        /* get local reference table (thread specific) */
 
        lrt = LOCALREFTABLE;
 
-       /* remove the reference */
+       /* go through all local frames */
 
-       for (i = 0; i < lrt->capacity; i++) {
-               if (lrt->refs[i] == o) {
-                       lrt->refs[i] = NULL;
-                       lrt->used--;
+       for (; lrt != NULL; lrt = lrt->prev) {
 
-                       return;
+               /* and try to remove the reference */
+
+               for (i = 0; i < lrt->capacity; i++) {
+                       if (lrt->refs[i] == o) {
+                               lrt->refs[i] = NULL;
+                               lrt->used--;
+
+                               return;
+                       }
                }
        }
 
@@ -1469,7 +1289,7 @@ void DeleteLocalRef(JNIEnv *env, jobject localRef)
 
 /*     if (opt_checkjni) */
 /*     FatalError(env, "Bad global or local ref passed to JNI"); */
-       log_text("JNI-DeleteLocalRef: Bad global or local ref passed to JNI");
+       log_text("JNI-DeleteLocalRef: Local ref passed to JNI not found");
 }
 
 
@@ -1479,7 +1299,7 @@ void DeleteLocalRef(JNIEnv *env, jobject localRef)
 
 *******************************************************************************/
 
-jboolean IsSameObject(JNIEnv *env, jobject ref1, jobject ref2)
+jboolean _Jv_JNI_IsSameObject(JNIEnv *env, jobject ref1, jobject ref2)
 {
        STATISTICS(jniinvokation());
 
@@ -1496,7 +1316,7 @@ jboolean IsSameObject(JNIEnv *env, jobject ref1, jobject ref2)
 
 *******************************************************************************/
 
-jobject NewLocalRef(JNIEnv *env, jobject ref)
+jobject _Jv_JNI_NewLocalRef(JNIEnv *env, jobject ref)
 {
        localref_table *lrt;
        s4              i;
@@ -1510,20 +1330,24 @@ jobject NewLocalRef(JNIEnv *env, jobject ref)
 
        lrt = LOCALREFTABLE;
 
-       /* check if we have space for the requested reference */
+       /* Check if we have space for the requested reference?  No,
+          allocate a new frame.  This is actually not what the spec says,
+          but for compatibility reasons... */
 
        if (lrt->used == lrt->capacity) {
-/*             throw_cacao_exception_exit(string_java_lang_InternalError, */
-/*                                                                "Too many local references"); */
-               fprintf(stderr, "Too many local references");
-               assert(0);
+               if (_Jv_JNI_EnsureLocalCapacity(env, 16) != 0)
+                       return NULL;
+
+               /* get the new local reference table */
+
+               lrt = LOCALREFTABLE;
        }
 
        /* insert the reference */
 
        for (i = 0; i < lrt->capacity; i++) {
                if (lrt->refs[i] == NULL) {
-                       lrt->refs[i] = (java_objectheader *) ref;
+                       lrt->refs[i] = (java_handle_t *) ref;
                        lrt->used++;
 
                        return ref;
@@ -1547,7 +1371,7 @@ jobject NewLocalRef(JNIEnv *env, jobject ref)
 
 *******************************************************************************/
 
-jint EnsureLocalCapacity(JNIEnv* env, jint capacity)
+jint _Jv_JNI_EnsureLocalCapacity(JNIEnv* env, jint capacity)
 {
        localref_table *lrt;
 
@@ -1559,10 +1383,8 @@ jint EnsureLocalCapacity(JNIEnv* env, jint capacity)
 
        /* check if capacity elements are available in the local references table */
 
-       if ((lrt->used + capacity) > lrt->capacity) {
-               *exceptionptr = new_exception(string_java_lang_OutOfMemoryError);
-               return -1;
-       }
+       if ((lrt->used + capacity) > lrt->capacity)
+               return _Jv_JNI_PushLocalFrame(env, capacity);
 
        return 0;
 }
@@ -1575,25 +1397,23 @@ jint EnsureLocalCapacity(JNIEnv* env, jint capacity)
 
 *******************************************************************************/
 
-jobject AllocObject(JNIEnv *env, jclass clazz)
+jobject _Jv_JNI_AllocObject(JNIEnv *env, jclass clazz)
 {
-       classinfo         *c;
-       java_objectheader *o;
+       classinfo     *c;
+       java_handle_t *o;
 
        STATISTICS(jniinvokation());
 
-       c = (classinfo *) clazz;
+       c = LLNI_classinfo_unwrap(clazz);
 
        if ((c->flags & ACC_INTERFACE) || (c->flags & ACC_ABSTRACT)) {
-               *exceptionptr =
-                       new_exception_utfmessage(string_java_lang_InstantiationException,
-                                                                        c->name);
+               exceptions_throw_instantiationexception(c);
                return NULL;
        }
                
        o = builtin_new(c);
 
-       return NewLocalRef(env, o);
+       return _Jv_JNI_NewLocalRef(env, (jobject) o);
 }
 
 
@@ -1606,21 +1426,23 @@ jobject AllocObject(JNIEnv *env, jclass clazz)
 
 *******************************************************************************/
 
-jobject NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
+jobject _Jv_JNI_NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
 {
-       java_objectheader *o;
-       methodinfo        *m;
-       va_list            ap;
+       java_handle_t *o;
+       classinfo     *c;
+       methodinfo    *m;
+       va_list        ap;
 
        STATISTICS(jniinvokation());
 
+       c = LLNI_classinfo_unwrap(clazz);
        m = (methodinfo *) methodID;
 
        /* create object */
 
-       o = builtin_new(clazz);
+       o = builtin_new(c);
        
-       if (!o)
+       if (o == NULL)
                return NULL;
 
        /* call constructor */
@@ -1629,7 +1451,7 @@ jobject NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
        _Jv_jni_CallVoidMethod(o, o->vftbl, m, ap);
        va_end(ap);
 
-       return NewLocalRef(env, o);
+       return _Jv_JNI_NewLocalRef(env, (jobject) o);
 }
 
 
@@ -1643,45 +1465,67 @@ jobject NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
 
 *******************************************************************************/
 
-jobject NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID, va_list args)
+jobject _Jv_JNI_NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID,
+                                                  va_list args)
 {
-       java_objectheader *o;
-       methodinfo        *m;
+       java_handle_t *o;
+       classinfo     *c;
+       methodinfo    *m;
 
        STATISTICS(jniinvokation());
 
+       c = LLNI_classinfo_unwrap(clazz);
        m = (methodinfo *) methodID;
 
        /* create object */
 
-       o = builtin_new(clazz);
+       o = builtin_new(c);
        
-       if (!o)
+       if (o == NULL)
                return NULL;
 
        /* call constructor */
 
        _Jv_jni_CallVoidMethod(o, o->vftbl, m, args);
 
-       return NewLocalRef(env, o);
+       return _Jv_JNI_NewLocalRef(env, (jobject) o);
 }
 
 
-/*********************************************************************************** 
+/* NewObjectA ***************************************************************** 
 
-       Constructs a new Java object
-       arguments that are to be passed to the constructor are placed in 
-       args array of jvalues 
+   Programmers place all arguments that are to be passed to the
+   constructor in an args array of jvalues that immediately follows
+   the methodID argument. NewObjectA() accepts the arguments in this
+   array, and, in turn, passes them to the Java method that the
+   programmer wishes to invoke.
 
-***********************************************************************************/
+*******************************************************************************/
 
-jobject NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID, jvalue *args)
+jobject _Jv_JNI_NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID,
+                                                  const jvalue *args)
 {
+       java_handle_t *o;
+       classinfo     *c;
+       methodinfo    *m;
+
        STATISTICS(jniinvokation());
 
-       log_text("JNI-Call: NewObjectA: IMPLEMENT ME!");
+       c = LLNI_classinfo_unwrap(clazz);
+       m = (methodinfo *) methodID;
+
+       /* create object */
+
+       o = builtin_new(c);
+       
+       if (o == NULL)
+               return NULL;
+
+       /* call constructor */
+
+       _Jv_jni_CallVoidMethodA(o, o->vftbl, m, args);
 
-       return NewLocalRef(env, NULL);
+       return _Jv_JNI_NewLocalRef(env, (jobject) o);
 }
 
 
@@ -1691,21 +1535,21 @@ jobject NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID, jvalue *args)
 
 *******************************************************************************/
 
-jclass GetObjectClass(JNIEnv *env, jobject obj)
+jclass _Jv_JNI_GetObjectClass(JNIEnv *env, jobject obj)
 {
-       java_objectheader *o;
-       classinfo         *c;
+       java_handle_t *o;
+       classinfo     *c;
 
        STATISTICS(jniinvokation());
 
-       o = (java_objectheader *) obj;
+       o = (java_handle_t *) obj;
 
        if ((o == NULL) || (o->vftbl == NULL))
                return NULL;
 
        c = o->vftbl->class;
 
-       return (jclass) NewLocalRef(env, (jobject) c);
+       return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) c);
 }
 
 
@@ -1715,14 +1559,17 @@ jclass GetObjectClass(JNIEnv *env, jobject obj)
 
 *******************************************************************************/
 
-jboolean IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz)
+jboolean _Jv_JNI_IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz)
 {
+       java_lang_Class  *c;
+       java_lang_Object *o;
+
        STATISTICS(jniinvokation());
 
-       return Java_java_lang_VMClass_isInstance(env,
-                                                                                        NULL,
-                                                                                        (java_lang_Class *) clazz,
-                                                                                        (java_lang_Object *) obj);
+       c = (java_lang_Class *) clazz;
+       o = (java_lang_Object *) obj;
+
+       return _Jv_java_lang_Class_isInstance(c, o);
 }
 
 
@@ -1735,37 +1582,48 @@ jboolean IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz)
   
 *******************************************************************************/
   
-jmethodID FromReflectedMethod(JNIEnv *env, jobject method)
+jmethodID _Jv_JNI_FromReflectedMethod(JNIEnv *env, jobject method)
 {
-       methodinfo *mi;
-       classinfo  *c;
-       s4          slot;
+#if defined(ENABLE_JAVASE)
+       java_handle_t *o;
+       classinfo     *c;
+       methodinfo    *m;
+       s4             slot;
 
        STATISTICS(jniinvokation());
 
-       if (method == NULL)
+       o = (java_handle_t *) method;
+
+       if (o == NULL)
                return NULL;
        
-       if (builtin_instanceof(method, class_java_lang_reflect_Method)) {
+       if (builtin_instanceof(o, class_java_lang_reflect_Method)) {
                java_lang_reflect_Method *rm;
 
-               rm = (java_lang_reflect_Method *) method;
-               c = (classinfo *) (rm->declaringClass);
-               slot = rm->slot;
-
-       } else if (builtin_instanceof(method, class_java_lang_reflect_Constructor)) {
+               rm   = (java_lang_reflect_Method *) method;
+               LLNI_field_get_cls(rm, clazz, c);
+               LLNI_field_get_val(rm, slot , slot);
+       }
+       else if (builtin_instanceof(o, class_java_lang_reflect_Constructor)) {
                java_lang_reflect_Constructor *rc;
 
-               rc = (java_lang_reflect_Constructor *) method;
-               c = (classinfo *) (rc->clazz);
-               slot = rc->slot;
-
-       else
+               rc   = (java_lang_reflect_Constructor *) method;
+               LLNI_field_get_cls(rc, clazz, c);
+               LLNI_field_get_val(rc, slot , slot);
+       }
+       else
                return NULL;
 
-       mi = &(c->methods[slot]);
+       m = &(c->methods[slot]);
+
+       return (jmethodID) m;
+#else
+       vm_abort("_Jv_JNI_FromReflectedMethod: not implemented in this configuration");
+
+       /* keep compiler happy */
 
-       return (jmethodID) mi;
+       return NULL;
+#endif
 }
 
 
@@ -1775,11 +1633,13 @@ jmethodID FromReflectedMethod(JNIEnv *env, jobject method)
 
 *******************************************************************************/
  
-jfieldID FromReflectedField(JNIEnv* env, jobject field)
+jfieldID _Jv_JNI_FromReflectedField(JNIEnv* env, jobject field)
 {
+#if defined(ENABLE_JAVASE)
        java_lang_reflect_Field *rf;
        classinfo               *c;
        fieldinfo               *f;
+       int32_t                  slot;
 
        STATISTICS(jniinvokation());
 
@@ -1788,11 +1648,18 @@ jfieldID FromReflectedField(JNIEnv* env, jobject field)
        if (rf == NULL)
                return NULL;
 
-       c = (classinfo *) rf->declaringClass;
-
-       f = &(c->fields[rf->slot]);
+       LLNI_field_get_cls(rf, clazz, c);
+       LLNI_field_get_val(rf, slot , slot);
+       f = &(c->fields[slot]);
 
        return (jfieldID) f;
+#else
+       vm_abort("_Jv_JNI_FromReflectedField: not implemented in this configuration");
+
+       /* keep compiler happy */
+
+       return NULL;
+#endif
 }
 
 
@@ -1804,25 +1671,51 @@ jfieldID FromReflectedField(JNIEnv* env, jobject field)
 
 *******************************************************************************/
 
-jobject ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID methodID, jboolean isStatic)
+jobject _Jv_JNI_ToReflectedMethod(JNIEnv* env, jclass cls, jmethodID methodID,
+                                                                 jboolean isStatic)
 {
+#if defined(ENABLE_JAVASE)
+       methodinfo                    *m;
+       java_lang_reflect_Constructor *rc;
+       java_lang_reflect_Method      *rm;
+
        STATISTICS(jniinvokation());
 
-       log_text("JNI-Call: ToReflectedMethod: IMPLEMENT ME!");
+       m = (methodinfo *) methodID;
 
-       return NULL;
-}
+       /* HotSpot does the same assert. */
 
+       assert(((m->flags & ACC_STATIC) != 0) == (isStatic != 0));
 
-/* ToReflectedField ************************************************************
+       if (m->name == utf_init) {
+               rc = reflect_constructor_new(m);
+
+               return (jobject) rc;
+       }
+       else {
+               rm = reflect_method_new(m);
+
+               return (jobject) rm;
+       }
+#else
+       vm_abort("_Jv_JNI_ToReflectedMethod: not implemented in this configuration");
+
+       /* keep compiler happy */
+
+       return NULL;
+#endif
+}
+
+
+/* ToReflectedField ************************************************************
 
    Converts a field ID derived from cls to an instance of the
    java.lang.reflect.Field class.
 
 *******************************************************************************/
 
-jobject ToReflectedField(JNIEnv* env, jclass cls, jfieldID fieldID,
-                                                jboolean isStatic)
+jobject _Jv_JNI_ToReflectedField(JNIEnv* env, jclass cls, jfieldID fieldID,
+                                                                jboolean isStatic)
 {
        STATISTICS(jniinvokation());
 
@@ -1845,8 +1738,8 @@ jobject ToReflectedField(JNIEnv* env, jclass cls, jfieldID fieldID,
 
 *******************************************************************************/
 
-jmethodID GetMethodID(JNIEnv* env, jclass clazz, const char *name,
-                                         const char *sig)
+jmethodID _Jv_JNI_GetMethodID(JNIEnv* env, jclass clazz, const char *name,
+                                                         const char *sig)
 {
        classinfo  *c;
        utf        *uname;
@@ -1855,9 +1748,9 @@ jmethodID GetMethodID(JNIEnv* env, jclass clazz, const char *name,
 
        STATISTICS(jniinvokation());
 
-       c = (classinfo *) clazz;
+       c = LLNI_classinfo_unwrap(clazz);
 
-       if (!c)
+       if (c == NULL)
                return NULL;
 
        if (!(c->state & CLASS_INITIALIZED))
@@ -1869,7 +1762,7 @@ jmethodID GetMethodID(JNIEnv* env, jclass clazz, const char *name,
        uname = utf_new_char((char *) name);
        udesc = utf_new_char((char *) sig);
 
-       m = class_resolvemethod(clazz, uname, udesc);
+       m = class_resolvemethod(c, uname, udesc);
 
        if ((m == NULL) || (m->flags & ACC_STATIC)) {
                exceptions_throw_nosuchmethoderror(c, uname, udesc);
@@ -1883,2947 +1776,1346 @@ jmethodID GetMethodID(JNIEnv* env, jclass clazz, const char *name,
 
 /* JNI-functions for calling instance methods *********************************/
 
-jobject CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
-{
-       java_objectheader *o;
-       methodinfo        *m;
-       java_objectheader *ret;
-       va_list            ap;
-
-       o = (java_objectheader *) obj;
+#define JNI_CALL_VIRTUAL_METHOD(name, type, intern)         \
+type _Jv_JNI_Call##name##Method(JNIEnv *env, jobject obj,   \
+                                                               jmethodID methodID, ...)    \
+{                                                           \
+       java_handle_t *o;                                       \
+       methodinfo    *m;                                       \
+       va_list        ap;                                      \
+       type           ret;                                     \
+                                                            \
+       o = (java_handle_t *) obj;                              \
+       m = (methodinfo *) methodID;                            \
+                                                            \
+       va_start(ap, methodID);                                 \
+       ret = _Jv_jni_Call##intern##Method(o, o->vftbl, m, ap); \
+       va_end(ap);                                             \
+                                                            \
+       return ret;                                             \
+}
+
+JNI_CALL_VIRTUAL_METHOD(Boolean, jboolean, Int)
+JNI_CALL_VIRTUAL_METHOD(Byte,    jbyte,    Int)
+JNI_CALL_VIRTUAL_METHOD(Char,    jchar,    Int)
+JNI_CALL_VIRTUAL_METHOD(Short,   jshort,   Int)
+JNI_CALL_VIRTUAL_METHOD(Int,     jint,     Int)
+JNI_CALL_VIRTUAL_METHOD(Long,    jlong,    Long)
+JNI_CALL_VIRTUAL_METHOD(Float,   jfloat,   Float)
+JNI_CALL_VIRTUAL_METHOD(Double,  jdouble,  Double)
+
+
+#define JNI_CALL_VIRTUAL_METHOD_V(name, type, intern)              \
+type _Jv_JNI_Call##name##MethodV(JNIEnv *env, jobject obj,         \
+                                                                jmethodID methodID, va_list args) \
+{                                                                  \
+       java_handle_t *o;                                              \
+       methodinfo    *m;                                              \
+       type           ret;                                            \
+                                                                   \
+       o = (java_handle_t *) obj;                                     \
+       m = (methodinfo *) methodID;                                   \
+                                                                   \
+       ret = _Jv_jni_Call##intern##Method(o, o->vftbl, m, args);      \
+                                                                   \
+       return ret;                                                    \
+}
+
+JNI_CALL_VIRTUAL_METHOD_V(Boolean, jboolean, Int)
+JNI_CALL_VIRTUAL_METHOD_V(Byte,    jbyte,    Int)
+JNI_CALL_VIRTUAL_METHOD_V(Char,    jchar,    Int)
+JNI_CALL_VIRTUAL_METHOD_V(Short,   jshort,   Int)
+JNI_CALL_VIRTUAL_METHOD_V(Int,     jint,     Int)
+JNI_CALL_VIRTUAL_METHOD_V(Long,    jlong,    Long)
+JNI_CALL_VIRTUAL_METHOD_V(Float,   jfloat,   Float)
+JNI_CALL_VIRTUAL_METHOD_V(Double,  jdouble,  Double)
+
+
+#define JNI_CALL_VIRTUAL_METHOD_A(name, type, intern)          \
+type _Jv_JNI_Call##name##MethodA(JNIEnv *env, jobject obj,     \
+                                                                jmethodID methodID,           \
+                                                                const jvalue *args)           \
+{                                                              \
+       java_handle_t *o;                                          \
+       methodinfo    *m;                                          \
+       type           ret;                                        \
+                                                               \
+       o = (java_handle_t *) obj;                                 \
+       m = (methodinfo *) methodID;                               \
+                                                               \
+       ret = _Jv_jni_Call##intern##MethodA(o, o->vftbl, m, args); \
+                                                               \
+       return ret;                                                \
+}
+
+JNI_CALL_VIRTUAL_METHOD_A(Boolean, jboolean, Int)
+JNI_CALL_VIRTUAL_METHOD_A(Byte,    jbyte,    Int)
+JNI_CALL_VIRTUAL_METHOD_A(Char,    jchar,    Int)
+JNI_CALL_VIRTUAL_METHOD_A(Short,   jshort,   Int)
+JNI_CALL_VIRTUAL_METHOD_A(Int,     jint,     Int)
+JNI_CALL_VIRTUAL_METHOD_A(Long,    jlong,    Long)
+JNI_CALL_VIRTUAL_METHOD_A(Float,   jfloat,   Float)
+JNI_CALL_VIRTUAL_METHOD_A(Double,  jdouble,  Double)
+
+
+jobject _Jv_JNI_CallObjectMethod(JNIEnv *env, jobject obj, jmethodID methodID,
+                                                                ...)
+{
+       java_handle_t *o;
+       methodinfo    *m;
+       java_handle_t *ret;
+       va_list        ap;
+
+       o = (java_handle_t *) obj;
        m = (methodinfo *) methodID;
 
        va_start(ap, methodID);
        ret = _Jv_jni_CallObjectMethod(o, o->vftbl, m, ap);
        va_end(ap);
 
-       return NewLocalRef(env, ret);
+       return _Jv_JNI_NewLocalRef(env, (jobject) ret);
 }
 
 
-jobject CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
+jobject _Jv_JNI_CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
+                                                                 va_list args)
 {
-       java_objectheader *o;
-       methodinfo        *m;
-       java_objectheader *ret;
+       java_handle_t *o;
+       methodinfo    *m;
+       java_handle_t *ret;
 
-       o = (java_objectheader *) obj;
+       o = (java_handle_t *) obj;
        m = (methodinfo *) methodID;
 
        ret = _Jv_jni_CallObjectMethod(o, o->vftbl, m, args);
 
-       return NewLocalRef(env, ret);
+       return _Jv_JNI_NewLocalRef(env, (jobject) ret);
 }
 
 
-jobject CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
+jobject _Jv_JNI_CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
+                                                                 const jvalue *args)
 {
-       log_text("JNI-Call: CallObjectMethodA: IMPLEMENT ME!");
+       java_handle_t *o;
+       methodinfo    *m;
+       java_handle_t *ret;
+
+       o = (java_handle_t *) obj;
+       m = (methodinfo *) methodID;
+
+       ret = _Jv_jni_CallObjectMethodA(o, o->vftbl, m, args);
 
-       return NewLocalRef(env, NULL);
+       return _Jv_JNI_NewLocalRef(env, (jobject) ret);
 }
 
 
-jboolean CallBooleanMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
+
+void _Jv_JNI_CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
 {
-       java_objectheader *o;
-       methodinfo        *m;
-       va_list            ap;
-       jboolean           b;
+       java_handle_t *o;
+       methodinfo    *m;
+       va_list        ap;
 
-       o = (java_objectheader *) obj;
+       o = (java_handle_t *) obj;
        m = (methodinfo *) methodID;
 
        va_start(ap, methodID);
-       b = _Jv_jni_CallIntMethod(o, o->vftbl, m, ap, PRIMITIVETYPE_BOOLEAN);
+       _Jv_jni_CallVoidMethod(o, o->vftbl, m, ap);
        va_end(ap);
-
-       return b;
 }
 
 
-jboolean CallBooleanMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
+void _Jv_JNI_CallVoidMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
+                                                        va_list args)
 {
-       java_objectheader *o;
-       methodinfo        *m;
-       jboolean           b;
+       java_handle_t *o;
+       methodinfo    *m;
 
-       o = (java_objectheader *) obj;
+       o = (java_handle_t *) obj;
        m = (methodinfo *) methodID;
 
-       b = _Jv_jni_CallIntMethod(o, o->vftbl, m, args, PRIMITIVETYPE_BOOLEAN);
-
-       return b;
+       _Jv_jni_CallVoidMethod(o, o->vftbl, m, args);
 }
 
 
-jboolean CallBooleanMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
+void _Jv_JNI_CallVoidMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
+                                                        const jvalue *args)
 {
-       log_text("JNI-Call: CallBooleanMethodA");
-
-       return 0;
-}
+       java_handle_t *o;
+       methodinfo    *m;
 
+       o = (java_handle_t *) obj;
+       m = (methodinfo *) methodID;
 
-jbyte CallByteMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
-{
-       java_objectheader *o;
-       methodinfo        *m;
-       va_list            ap;
-       jbyte              b;
-
-       o = (java_objectheader *) obj;
+       _Jv_jni_CallVoidMethodA(o, o->vftbl, m, args);
+}
+
+
+
+#define JNI_CALL_NONVIRTUAL_METHOD(name, type, intern)                      \
+type _Jv_JNI_CallNonvirtual##name##Method(JNIEnv *env, jobject obj,         \
+                                                                                 jclass clazz, jmethodID methodID, \
+                                                                                 ...)                              \
+{                                                                           \
+       java_handle_t *o;                                                       \
+       classinfo     *c;                                                       \
+       methodinfo    *m;                                                       \
+       va_list        ap;                                                      \
+       type           ret;                                                     \
+                                                                            \
+       o = (java_handle_t *) obj;                                              \
+       c = LLNI_classinfo_unwrap(clazz);                                       \
+       m = (methodinfo *) methodID;                                            \
+                                                                            \
+       va_start(ap, methodID);                                                 \
+       ret = _Jv_jni_Call##intern##Method(o, c->vftbl, m, ap);                 \
+       va_end(ap);                                                             \
+                                                                            \
+       return ret;                                                             \
+}
+
+JNI_CALL_NONVIRTUAL_METHOD(Boolean, jboolean, Int)
+JNI_CALL_NONVIRTUAL_METHOD(Byte,    jbyte,    Int)
+JNI_CALL_NONVIRTUAL_METHOD(Char,    jchar,    Int)
+JNI_CALL_NONVIRTUAL_METHOD(Short,   jshort,   Int)
+JNI_CALL_NONVIRTUAL_METHOD(Int,     jint,     Int)
+JNI_CALL_NONVIRTUAL_METHOD(Long,    jlong,    Long)
+JNI_CALL_NONVIRTUAL_METHOD(Float,   jfloat,   Float)
+JNI_CALL_NONVIRTUAL_METHOD(Double,  jdouble,  Double)
+
+
+#define JNI_CALL_NONVIRTUAL_METHOD_V(name, type, intern)                     \
+type _Jv_JNI_CallNonvirtual##name##MethodV(JNIEnv *env, jobject obj,         \
+                                                                                  jclass clazz, jmethodID methodID, \
+                                                                                  va_list args)                     \
+{                                                                            \
+       java_handle_t *o;                                                        \
+       classinfo     *c;                                                        \
+       methodinfo    *m;                                                        \
+       type           ret;                                                      \
+                                                                             \
+       o = (java_handle_t *) obj;                                               \
+       c = LLNI_classinfo_unwrap(clazz);                                        \
+       m = (methodinfo *) methodID;                                             \
+                                                                             \
+       ret = _Jv_jni_CallIntMethod(o, c->vftbl, m, args);                       \
+                                                                             \
+       return ret;                                                              \
+}
+
+JNI_CALL_NONVIRTUAL_METHOD_V(Boolean, jboolean, Int)
+JNI_CALL_NONVIRTUAL_METHOD_V(Byte,    jbyte,    Int)
+JNI_CALL_NONVIRTUAL_METHOD_V(Char,    jchar,    Int)
+JNI_CALL_NONVIRTUAL_METHOD_V(Short,   jshort,   Int)
+JNI_CALL_NONVIRTUAL_METHOD_V(Int,     jint,     Int)
+JNI_CALL_NONVIRTUAL_METHOD_V(Long,    jlong,    Long)
+JNI_CALL_NONVIRTUAL_METHOD_V(Float,   jfloat,   Float)
+JNI_CALL_NONVIRTUAL_METHOD_V(Double,  jdouble,  Double)
+
+
+#define JNI_CALL_NONVIRTUAL_METHOD_A(name, type, intern)                     \
+type _Jv_JNI_CallNonvirtual##name##MethodA(JNIEnv *env, jobject obj,         \
+                                                                                  jclass clazz, jmethodID methodID, \
+                                                                                  const jvalue *args)               \
+{                                                                            \
+       log_text("JNI-Call: CallNonvirtual##name##MethodA: IMPLEMENT ME!");      \
+                                                                             \
+       return 0;                                                                \
+}
+
+JNI_CALL_NONVIRTUAL_METHOD_A(Boolean, jboolean, Int)
+JNI_CALL_NONVIRTUAL_METHOD_A(Byte,    jbyte,    Int)
+JNI_CALL_NONVIRTUAL_METHOD_A(Char,    jchar,    Int)
+JNI_CALL_NONVIRTUAL_METHOD_A(Short,   jshort,   Int)
+JNI_CALL_NONVIRTUAL_METHOD_A(Int,     jint,     Int)
+JNI_CALL_NONVIRTUAL_METHOD_A(Long,    jlong,    Long)
+JNI_CALL_NONVIRTUAL_METHOD_A(Float,   jfloat,   Float)
+JNI_CALL_NONVIRTUAL_METHOD_A(Double,  jdouble,  Double)
+
+jobject _Jv_JNI_CallNonvirtualObjectMethod(JNIEnv *env, jobject obj,
+                                                                                  jclass clazz, jmethodID methodID,
+                                                                                  ...)
+{
+       java_handle_t *o;
+       classinfo     *c;
+       methodinfo    *m;
+       java_handle_t *r;
+       va_list        ap;
+
+       o = (java_handle_t *) obj;
+       c = LLNI_classinfo_unwrap(clazz);
        m = (methodinfo *) methodID;
 
        va_start(ap, methodID);
-       b = _Jv_jni_CallIntMethod(o, o->vftbl, m, ap, PRIMITIVETYPE_BYTE);
+       r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, ap);
        va_end(ap);
 
-       return b;
-
+       return _Jv_JNI_NewLocalRef(env, (jobject) r);
 }
 
-jbyte CallByteMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
+
+jobject _Jv_JNI_CallNonvirtualObjectMethodV(JNIEnv *env, jobject obj,
+                                                                                       jclass clazz, jmethodID methodID,
+                                                                                       va_list args)
 {
-       java_objectheader *o;
-       methodinfo        *m;
-       jbyte              b;
+       java_handle_t *o;
+       classinfo     *c;
+       methodinfo    *m;
+       java_handle_t *r;
 
-       o = (java_objectheader *) obj;
+       o = (java_handle_t *) obj;
+       c = LLNI_classinfo_unwrap(clazz);
        m = (methodinfo *) methodID;
 
-       b = _Jv_jni_CallIntMethod(o, o->vftbl, m, args, PRIMITIVETYPE_BYTE);
+       r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, args);
 
-       return b;
+       return _Jv_JNI_NewLocalRef(env, (jobject) r);
 }
 
 
-jbyte CallByteMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
+jobject _Jv_JNI_CallNonvirtualObjectMethodA(JNIEnv *env, jobject obj,
+                                                                                       jclass clazz, jmethodID methodID,
+                                                                                       const jvalue *args)
 {
-       log_text("JNI-Call: CallByteMethodA: IMPLEMENT ME!");
+       log_text("JNI-Call: CallNonvirtualObjectMethodA: IMPLEMENT ME!");
 
-       return 0;
+       return _Jv_JNI_NewLocalRef(env, NULL);
 }
 
 
-jchar CallCharMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
+void _Jv_JNI_CallNonvirtualVoidMethod(JNIEnv *env, jobject obj, jclass clazz,
+                                                                         jmethodID methodID, ...)
 {
-       java_objectheader *o;
-       methodinfo        *m;
-       va_list            ap;
-       jchar              c;
+       java_handle_t *o;
+       classinfo     *c;
+       methodinfo    *m;
+       va_list        ap;
 
-       o = (java_objectheader *) obj;
+       o = (java_handle_t *) obj;
+       c = LLNI_classinfo_unwrap(clazz);
        m = (methodinfo *) methodID;
 
        va_start(ap, methodID);
-       c = _Jv_jni_CallIntMethod(o, o->vftbl, m, ap, PRIMITIVETYPE_CHAR);
+       _Jv_jni_CallVoidMethod(o, c->vftbl, m, ap);
        va_end(ap);
-
-       return c;
 }
 
 
-jchar CallCharMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
+void _Jv_JNI_CallNonvirtualVoidMethodV(JNIEnv *env, jobject obj, jclass clazz,
+                                                                          jmethodID methodID, va_list args)
 {
-       java_objectheader *o;
-       methodinfo        *m;
-       jchar              c;
+       java_handle_t *o;
+       classinfo     *c;
+       methodinfo    *m;
 
-       o = (java_objectheader *) obj;
+       o = (java_handle_t *) obj;
+       c = LLNI_classinfo_unwrap(clazz);
        m = (methodinfo *) methodID;
 
-       c = _Jv_jni_CallIntMethod(o, o->vftbl, m, args, PRIMITIVETYPE_CHAR);
-
-       return c;
-}
-
-
-jchar CallCharMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
-{
-       log_text("JNI-Call: CallCharMethodA: IMPLEMENT ME!");
-
-       return 0;
+       _Jv_jni_CallVoidMethod(o, c->vftbl, m, args);
 }
 
 
-jshort CallShortMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
-{
-       java_objectheader *o;
-       methodinfo        *m;
-       va_list            ap;
-       jshort             s;
+void _Jv_JNI_CallNonvirtualVoidMethodA(JNIEnv *env, jobject obj, jclass clazz,
+                                                                          jmethodID methodID, const jvalue * args)
+{      
+       java_handle_t *o;
+       classinfo     *c;
+       methodinfo    *m;
 
-       o = (java_objectheader *) obj;
+       o = (java_handle_t *) obj;
+       c = LLNI_classinfo_unwrap(clazz);
        m = (methodinfo *) methodID;
 
-       va_start(ap, methodID);
-       s = _Jv_jni_CallIntMethod(o, o->vftbl, m, ap, PRIMITIVETYPE_SHORT);
-       va_end(ap);
-
-       return s;
+       _Jv_jni_CallVoidMethodA(o, c->vftbl, m, args);
 }
 
 
-jshort CallShortMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
-{
-       java_objectheader *o;
-       methodinfo        *m;
-       jshort             s;
-
-       o = (java_objectheader *) obj;
-       m = (methodinfo *) methodID;
+/* Accessing Fields of Objects ************************************************/
 
-       s = _Jv_jni_CallIntMethod(o, o->vftbl, m, args, PRIMITIVETYPE_SHORT);
+/* GetFieldID ******************************************************************
 
-       return s;
-}
+   Returns the field ID for an instance (nonstatic) field of a
+   class. The field is specified by its name and signature. The
+   Get<type>Field and Set<type>Field families of accessor functions
+   use field IDs to retrieve object fields.
 
+*******************************************************************************/
 
-jshort CallShortMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
+jfieldID _Jv_JNI_GetFieldID(JNIEnv *env, jclass clazz, const char *name,
+                                                       const char *sig)
 {
-       log_text("JNI-Call: CallShortMethodA: IMPLEMENT ME!");
-
-       return 0;
-}
+       classinfo *c;
+       fieldinfo *f;
+       utf       *uname;
+       utf       *udesc;
 
+       STATISTICS(jniinvokation());
 
+       c = LLNI_classinfo_unwrap(clazz);
 
-jint CallIntMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
-{
-       java_objectheader *o;
-       methodinfo        *m;
-       va_list            ap;
-       jint               i;
+       /* XXX NPE check? */
 
-       o = (java_objectheader *) obj;
-       m = (methodinfo *) methodID;
+       uname = utf_new_char((char *) name);
+       udesc = utf_new_char((char *) sig);
 
-       va_start(ap, methodID);
-       i = _Jv_jni_CallIntMethod(o, o->vftbl, m, ap, PRIMITIVETYPE_INT);
-       va_end(ap);
+       f = class_findfield(c, uname, udesc); 
+       
+       if (f == NULL)
+               exceptions_throw_nosuchfielderror(c, uname);  
 
-       return i;
+       return (jfieldID) f;
 }
 
 
-jint CallIntMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
-{
-       java_objectheader *o;
-       methodinfo        *m;
-       jint               i;
-
-       o = (java_objectheader *) obj;
-       m = (methodinfo *) methodID;
-
-       i = _Jv_jni_CallIntMethod(o, o->vftbl, m, args, PRIMITIVETYPE_INT);
-
-       return i;
-}
+/* Get<type>Field Routines *****************************************************
 
+   This family of accessor routines returns the value of an instance
+   (nonstatic) field of an object. The field to access is specified by
+   a field ID obtained by calling GetFieldID().
 
-jint CallIntMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
-{
-       log_text("JNI-Call: CallIntMethodA: IMPLEMENT ME!");
+*******************************************************************************/
 
-       return 0;
+#define JNI_GET_FIELD(name, type, intern)                                 \
+type _Jv_JNI_Get##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID) \
+{                                                                         \
+       intern ret;                                                           \
+                                                                          \
+       STATISTICS(jniinvokation());                                          \
+                                                                          \
+       ret = GET_FIELD(obj, intern, fieldID);                                \
+                                                                          \
+       return (type) ret;                                                    \
 }
 
+JNI_GET_FIELD(Boolean, jboolean, s4)
+JNI_GET_FIELD(Byte,    jbyte,    s4)
+JNI_GET_FIELD(Char,    jchar,    s4)
+JNI_GET_FIELD(Short,   jshort,   s4)
+JNI_GET_FIELD(Int,     jint,     s4)
+JNI_GET_FIELD(Long,    jlong,    s8)
+JNI_GET_FIELD(Float,   jfloat,   float)
+JNI_GET_FIELD(Double,  jdouble,  double)
 
 
-jlong CallLongMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
+jobject _Jv_JNI_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID)
 {
-       java_objectheader *o;
-       methodinfo        *m;
-       va_list            ap;
-       jlong              l;
+       java_handle_t *o;
 
-       o = (java_objectheader *) obj;
-       m = (methodinfo *) methodID;
+       STATISTICS(jniinvokation());
 
-       va_start(ap, methodID);
-       l = _Jv_jni_CallLongMethod(o, o->vftbl, m, ap);
-       va_end(ap);
+#warning this needs to be fixed
+       o = GET_FIELD(obj, java_handle_t*, fieldID);
 
-       return l;
+       return _Jv_JNI_NewLocalRef(env, (jobject) o);
 }
 
 
-jlong CallLongMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
-{
-       java_objectheader *o;
-       methodinfo        *m;
-       jlong              l;
+/* Set<type>Field Routines *****************************************************
 
-       o = (java_objectheader *) obj;
-       m = (methodinfo *) methodID;
+   This family of accessor routines sets the value of an instance
+   (nonstatic) field of an object. The field to access is specified by
+   a field ID obtained by calling GetFieldID().
 
-       l = _Jv_jni_CallLongMethod(o, o->vftbl, m, args);
+*******************************************************************************/
 
-       return l;
+#define JNI_SET_FIELD(name, type, intern)                                 \
+void _Jv_JNI_Set##name##Field(JNIEnv *env, jobject obj, jfieldID fieldID, \
+                                                         type value)                                 \
+{                                                                         \
+       STATISTICS(jniinvokation());                                          \
+                                                                          \
+       SET_FIELD(obj, intern, fieldID, value);                               \
 }
 
+JNI_SET_FIELD(Boolean, jboolean, s4)
+JNI_SET_FIELD(Byte,    jbyte,    s4)
+JNI_SET_FIELD(Char,    jchar,    s4)
+JNI_SET_FIELD(Short,   jshort,   s4)
+JNI_SET_FIELD(Int,     jint,     s4)
+JNI_SET_FIELD(Long,    jlong,    s8)
+JNI_SET_FIELD(Float,   jfloat,   float)
+JNI_SET_FIELD(Double,  jdouble,  double)
+
 
-jlong CallLongMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
+void _Jv_JNI_SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID,
+                                                       jobject value)
 {
-       log_text("JNI-Call: CallLongMethodA: IMPLEMENT ME!");
+       STATISTICS(jniinvokation());
 
-       return 0;
+#warning this needs to be fixed
+       SET_FIELD(obj, java_handle_t*, fieldID, value);
 }
 
 
+/* Calling Static Methods *****************************************************/
 
-jfloat CallFloatMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
-{
-       java_objectheader *o;
-       methodinfo        *m;
-       va_list            ap;
-       jfloat             f;
-
-       o = (java_objectheader *) obj;
-       m = (methodinfo *) methodID;
+/* GetStaticMethodID ***********************************************************
 
-       va_start(ap, methodID);
-       f = _Jv_jni_CallFloatMethod(o, o->vftbl, m, ap);
-       va_end(ap);
+   Returns the method ID for a static method of a class. The method is
+   specified by its name and signature.
 
-       return f;
-}
+   GetStaticMethodID() causes an uninitialized class to be
+   initialized.
 
+*******************************************************************************/
 
-jfloat CallFloatMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
+jmethodID _Jv_JNI_GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name,
+                                                                       const char *sig)
 {
-       java_objectheader *o;
-       methodinfo        *m;
-       jfloat             f;
+       classinfo  *c;
+       utf        *uname;
+       utf        *udesc;
+       methodinfo *m;
 
-       o = (java_objectheader *) obj;
-       m = (methodinfo *) methodID;
+       STATISTICS(jniinvokation());
 
-       f = _Jv_jni_CallFloatMethod(o, o->vftbl, m, args);
+       c = LLNI_classinfo_unwrap(clazz);
 
-       return f;
-}
+       if (!c)
+               return NULL;
 
+       if (!(c->state & CLASS_INITIALIZED))
+               if (!initialize_class(c))
+                       return NULL;
 
-jfloat CallFloatMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
-{
-       log_text("JNI-Call: CallFloatMethodA: IMPLEMENT ME!");
+       /* try to get the static method of the class */
 
-       return 0;
-}
+       uname = utf_new_char((char *) name);
+       udesc = utf_new_char((char *) sig);
 
+       m = class_resolvemethod(c, uname, udesc);
 
+       if ((m == NULL) || !(m->flags & ACC_STATIC)) {
+               exceptions_throw_nosuchmethoderror(c, uname, udesc);
 
-jdouble CallDoubleMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
-{
-       java_objectheader *o;
-       methodinfo        *m;
-       va_list            ap;
-       jdouble            d;
+               return NULL;
+       }
+
+       return (jmethodID) m;
+}
+
+
+#define JNI_CALL_STATIC_METHOD(name, type, intern)               \
+type _Jv_JNI_CallStatic##name##Method(JNIEnv *env, jclass clazz, \
+                                                                         jmethodID methodID, ...)   \
+{                                                                \
+       methodinfo *m;                                               \
+       va_list     ap;                                              \
+       type        res;                                             \
+                                                                 \
+       m = (methodinfo *) methodID;                                 \
+                                                                 \
+       va_start(ap, methodID);                                      \
+       res = _Jv_jni_Call##intern##Method(NULL, NULL, m, ap);       \
+       va_end(ap);                                                  \
+                                                                 \
+       return res;                                                  \
+}
+
+JNI_CALL_STATIC_METHOD(Boolean, jboolean, Int)
+JNI_CALL_STATIC_METHOD(Byte,    jbyte,    Int)
+JNI_CALL_STATIC_METHOD(Char,    jchar,    Int)
+JNI_CALL_STATIC_METHOD(Short,   jshort,   Int)
+JNI_CALL_STATIC_METHOD(Int,     jint,     Int)
+JNI_CALL_STATIC_METHOD(Long,    jlong,    Long)
+JNI_CALL_STATIC_METHOD(Float,   jfloat,   Float)
+JNI_CALL_STATIC_METHOD(Double,  jdouble,  Double)
+
+
+#define JNI_CALL_STATIC_METHOD_V(name, type, intern)                     \
+type _Jv_JNI_CallStatic##name##MethodV(JNIEnv *env, jclass clazz,        \
+                                                                          jmethodID methodID, va_list args) \
+{                                                                        \
+       methodinfo *m;                                                       \
+       type        res;                                                     \
+                                                                         \
+       m = (methodinfo *) methodID;                                         \
+                                                                         \
+       res = _Jv_jni_Call##intern##Method(NULL, NULL, m, args);             \
+                                                                         \
+       return res;                                                          \
+}
+
+JNI_CALL_STATIC_METHOD_V(Boolean, jboolean, Int)
+JNI_CALL_STATIC_METHOD_V(Byte,    jbyte,    Int)
+JNI_CALL_STATIC_METHOD_V(Char,    jchar,    Int)
+JNI_CALL_STATIC_METHOD_V(Short,   jshort,   Int)
+JNI_CALL_STATIC_METHOD_V(Int,     jint,     Int)
+JNI_CALL_STATIC_METHOD_V(Long,    jlong,    Long)
+JNI_CALL_STATIC_METHOD_V(Float,   jfloat,   Float)
+JNI_CALL_STATIC_METHOD_V(Double,  jdouble,  Double)
+
+
+#define JNI_CALL_STATIC_METHOD_A(name, type, intern)                           \
+type _Jv_JNI_CallStatic##name##MethodA(JNIEnv *env, jclass clazz,              \
+                                                                          jmethodID methodID, const jvalue *args) \
+{                                                                              \
+       methodinfo *m;                                                             \
+       type        res;                                                           \
+                                                                               \
+       m = (methodinfo *) methodID;                                               \
+                                                                               \
+       res = _Jv_jni_Call##intern##MethodA(NULL, NULL, m, args);                  \
+                                                                               \
+       return res;                                                                \
+}
+
+JNI_CALL_STATIC_METHOD_A(Boolean, jboolean, Int)
+JNI_CALL_STATIC_METHOD_A(Byte,    jbyte,    Int)
+JNI_CALL_STATIC_METHOD_A(Char,    jchar,    Int)
+JNI_CALL_STATIC_METHOD_A(Short,   jshort,   Int)
+JNI_CALL_STATIC_METHOD_A(Int,     jint,     Int)
+JNI_CALL_STATIC_METHOD_A(Long,    jlong,    Long)
+JNI_CALL_STATIC_METHOD_A(Float,   jfloat,   Float)
+JNI_CALL_STATIC_METHOD_A(Double,  jdouble,  Double)
+
+
+jobject _Jv_JNI_CallStaticObjectMethod(JNIEnv *env, jclass clazz,
+                                                                          jmethodID methodID, ...)
+{
+       methodinfo    *m;
+       java_handle_t *o;
+       va_list        ap;
 
-       o = (java_objectheader *) obj;
        m = (methodinfo *) methodID;
 
        va_start(ap, methodID);
-       d = _Jv_jni_CallDoubleMethod(o, o->vftbl, m, ap);
+       o = _Jv_jni_CallObjectMethod(NULL, NULL, m, ap);
        va_end(ap);
 
-       return d;
+       return _Jv_JNI_NewLocalRef(env, (jobject) o);
 }
 
 
-jdouble CallDoubleMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
+jobject _Jv_JNI_CallStaticObjectMethodV(JNIEnv *env, jclass clazz,
+                                                                               jmethodID methodID, va_list args)
 {
-       java_objectheader *o;
-       methodinfo        *m;
-       jdouble            d;
+       methodinfo    *m;
+       java_handle_t *o;
 
-       o = (java_objectheader *) obj;
        m = (methodinfo *) methodID;
 
-       d = _Jv_jni_CallDoubleMethod(o, o->vftbl, m, args);
+       o = _Jv_jni_CallObjectMethod(NULL, NULL, m, args);
 
-       return d;
+       return _Jv_JNI_NewLocalRef(env, (jobject) o);
 }
 
 
-jdouble CallDoubleMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
+jobject _Jv_JNI_CallStaticObjectMethodA(JNIEnv *env, jclass clazz,
+                                                                               jmethodID methodID, const jvalue *args)
 {
-       log_text("JNI-Call: CallDoubleMethodA: IMPLEMENT ME!");
+       methodinfo    *m;
+       java_handle_t *o;
 
-       return 0;
-}
+       m = (methodinfo *) methodID;
+
+       o = _Jv_jni_CallObjectMethodA(NULL, NULL, m, args);
 
+       return _Jv_JNI_NewLocalRef(env, (jobject) o);
+}
 
 
-void CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
+void _Jv_JNI_CallStaticVoidMethod(JNIEnv *env, jclass clazz,
+                                                                 jmethodID methodID, ...)
 {
-       java_objectheader *o;
-       methodinfo        *m;
-       va_list            ap;
+       methodinfo *m;
+       va_list     ap;
 
-       o = (java_objectheader *) obj;
        m = (methodinfo *) methodID;
 
        va_start(ap, methodID);
-       _Jv_jni_CallVoidMethod(o, o->vftbl, m, ap);
+       _Jv_jni_CallVoidMethod(NULL, NULL, m, ap);
        va_end(ap);
 }
 
 
-void CallVoidMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
+void _Jv_JNI_CallStaticVoidMethodV(JNIEnv *env, jclass clazz,
+                                                                  jmethodID methodID, va_list args)
 {
-       java_objectheader *o;
-       methodinfo        *m;
+       methodinfo *m;
 
-       o = (java_objectheader *) obj;
        m = (methodinfo *) methodID;
 
-       _Jv_jni_CallVoidMethod(o, o->vftbl, m, args);
+       _Jv_jni_CallVoidMethod(NULL, NULL, m, args);
 }
 
 
-void CallVoidMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
+void _Jv_JNI_CallStaticVoidMethodA(JNIEnv *env, jclass clazz,
+                                                                  jmethodID methodID, const jvalue * args)
 {
-       log_text("JNI-Call: CallVoidMethodA: IMPLEMENT ME!");
-}
-
-
+       methodinfo *m;
 
-jobject CallNonvirtualObjectMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
-{
-       java_objectheader *o;
-       classinfo         *c;
-       methodinfo        *m;
-       java_objectheader *r;
-       va_list            ap;
-
-       o = (java_objectheader *) obj;
-       c = (classinfo *) clazz;
        m = (methodinfo *) methodID;
 
-       va_start(ap, methodID);
-       r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, ap);
-       va_end(ap);
-
-       return NewLocalRef(env, r);
+       _Jv_jni_CallVoidMethodA(NULL, NULL, m, args);
 }
 
 
-jobject CallNonvirtualObjectMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
-{
-       java_objectheader *o;
-       classinfo         *c;
-       methodinfo        *m;
-       java_objectheader *r;
-
-       o = (java_objectheader *) obj;
-       c = (classinfo *) clazz;
-       m = (methodinfo *) methodID;
+/* Accessing Static Fields ****************************************************/
 
-       r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, args);
+/* GetStaticFieldID ************************************************************
 
-       return NewLocalRef(env, r);
-}
+   Returns the field ID for a static field of a class. The field is
+   specified by its name and signature. The GetStatic<type>Field and
+   SetStatic<type>Field families of accessor functions use field IDs
+   to retrieve static fields.
 
+*******************************************************************************/
 
-jobject CallNonvirtualObjectMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
+jfieldID _Jv_JNI_GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name,
+                                                                 const char *sig)
 {
-       log_text("JNI-Call: CallNonvirtualObjectMethodA: IMPLEMENT ME!");
-
-       return NewLocalRef(env, NULL);
-}
+       classinfo *c;
+       fieldinfo *f;
+       utf       *uname;
+       utf       *usig;
 
+       STATISTICS(jniinvokation());
 
+       c = LLNI_classinfo_unwrap(clazz);
 
-jboolean CallNonvirtualBooleanMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
-{
-       java_objectheader *o;
-       classinfo         *c;
-       methodinfo        *m;
-       va_list            ap;
-       jboolean           b;
-
-       o = (java_objectheader *) obj;
-       c = (classinfo *) clazz;
-       m = (methodinfo *) methodID;
+       uname = utf_new_char((char *) name);
+       usig  = utf_new_char((char *) sig);
 
-       va_start(ap, methodID);
-       b = _Jv_jni_CallIntMethod(o, c->vftbl, m, ap, PRIMITIVETYPE_BOOLEAN);
-       va_end(ap);
+       f = class_findfield(c, uname, usig);
+       
+       if (f == NULL)
+               exceptions_throw_nosuchfielderror(c, uname);
 
-       return b;
+       return (jfieldID) f;
 }
 
 
-jboolean CallNonvirtualBooleanMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
-{
-       java_objectheader *o;
-       classinfo         *c;
-       methodinfo        *m;
-       jboolean           b;
+/* GetStatic<type>Field ********************************************************
 
-       o = (java_objectheader *) obj;
-       c = (classinfo *) clazz;
-       m = (methodinfo *) methodID;
+   This family of accessor routines returns the value of a static
+   field of an object.
 
-       b = _Jv_jni_CallIntMethod(o, c->vftbl, m, args, PRIMITIVETYPE_BOOLEAN);
+*******************************************************************************/
 
-       return b;
-}
+#define JNI_GET_STATIC_FIELD(name, type, field)                \
+type _Jv_JNI_GetStatic##name##Field(JNIEnv *env, jclass clazz, \
+                                                                       jfieldID fieldID)          \
+{                                                              \
+       classinfo *c;                                              \
+       fieldinfo *f;                                              \
+                                                               \
+       STATISTICS(jniinvokation());                               \
+                                                               \
+       c = LLNI_classinfo_unwrap(clazz);                          \
+       f = (fieldinfo *) fieldID;                                 \
+                                                               \
+       if (!(c->state & CLASS_INITIALIZED))                       \
+               if (!initialize_class(c))                              \
+                       return 0;                                          \
+                                                               \
+       return f->value->field;                                    \
+}
+
+JNI_GET_STATIC_FIELD(Boolean, jboolean, i)
+JNI_GET_STATIC_FIELD(Byte,    jbyte,    i)
+JNI_GET_STATIC_FIELD(Char,    jchar,    i)
+JNI_GET_STATIC_FIELD(Short,   jshort,   i)
+JNI_GET_STATIC_FIELD(Int,     jint,     i)
+JNI_GET_STATIC_FIELD(Long,    jlong,    l)
+JNI_GET_STATIC_FIELD(Float,   jfloat,   f)
+JNI_GET_STATIC_FIELD(Double,  jdouble,  d)
+
+
+jobject _Jv_JNI_GetStaticObjectField(JNIEnv *env, jclass clazz,
+                                                                        jfieldID fieldID)
+{
+       classinfo *c;
+       fieldinfo *f;
 
+       STATISTICS(jniinvokation());
 
-jboolean CallNonvirtualBooleanMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
-{
-       log_text("JNI-Call: CallNonvirtualBooleanMethodA: IMPLEMENT ME!");
+       c = LLNI_classinfo_unwrap(clazz);
+       f = (fieldinfo *) fieldID;
 
-       return 0;
-}
+       if (!(c->state & CLASS_INITIALIZED))
+               if (!initialize_class(c))
+                       return NULL;
 
+       return _Jv_JNI_NewLocalRef(env, f->value->a);
+}
 
-jbyte CallNonvirtualByteMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
-{
-       java_objectheader *o;
-       classinfo         *c;
-       methodinfo        *m;
-       va_list            ap;
-       jbyte              b;
-
-       o = (java_objectheader *) obj;
-       c = (classinfo *) clazz;
-       m = (methodinfo *) methodID;
 
-       va_start(ap, methodID);
-       b = _Jv_jni_CallIntMethod(o, c->vftbl, m, ap, PRIMITIVETYPE_BYTE);
-       va_end(ap);
+/*  SetStatic<type>Field *******************************************************
 
-       return b;
-}
+       This family of accessor routines sets the value of a static field
+       of an object.
 
+*******************************************************************************/
 
-jbyte CallNonvirtualByteMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
+#define JNI_SET_STATIC_FIELD(name, type, field)                \
+void _Jv_JNI_SetStatic##name##Field(JNIEnv *env, jclass clazz, \
+                                                                       jfieldID fieldID,          \
+                                                                       type value)                \
+{                                                              \
+       classinfo *c;                                              \
+       fieldinfo *f;                                              \
+                                                               \
+       STATISTICS(jniinvokation());                               \
+                                                               \
+       c = LLNI_classinfo_unwrap(clazz);                          \
+       f = (fieldinfo *) fieldID;                                 \
+                                                               \
+       if (!(c->state & CLASS_INITIALIZED))                       \
+               if (!initialize_class(c))                              \
+                       return;                                            \
+                                                               \
+       f->value->field = value;                                   \
+}
+
+JNI_SET_STATIC_FIELD(Boolean, jboolean, i)
+JNI_SET_STATIC_FIELD(Byte,    jbyte,    i)
+JNI_SET_STATIC_FIELD(Char,    jchar,    i)
+JNI_SET_STATIC_FIELD(Short,   jshort,   i)
+JNI_SET_STATIC_FIELD(Int,     jint,     i)
+JNI_SET_STATIC_FIELD(Long,    jlong,    l)
+JNI_SET_STATIC_FIELD(Float,   jfloat,   f)
+JNI_SET_STATIC_FIELD(Double,  jdouble,  d)
+
+
+void _Jv_JNI_SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID,
+                                                                 jobject value)
 {
-       java_objectheader *o;
-       classinfo         *c;
-       methodinfo        *m;
-       jbyte              b;
+       classinfo *c;
+       fieldinfo *f;
 
-       o = (java_objectheader *) obj;
-       c = (classinfo *) clazz;
-       m = (methodinfo *) methodID;
+       STATISTICS(jniinvokation());
+
+       c = LLNI_classinfo_unwrap(clazz);
+       f = (fieldinfo *) fieldID;
 
-       b = _Jv_jni_CallIntMethod(o, c->vftbl, m, args, PRIMITIVETYPE_BYTE);
+       if (!(c->state & CLASS_INITIALIZED))
+               if (!initialize_class(c))
+                       return;
 
-       return b;
+       f->value->a = value;
 }
 
 
-jbyte CallNonvirtualByteMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
-{
-       log_text("JNI-Call: CallNonvirtualByteMethodA: IMPLEMENT ME!");
+/* String Operations **********************************************************/
 
-       return 0;
-}
+/* NewString *******************************************************************
 
+   Create new java.lang.String object from an array of Unicode
+   characters.
 
+*******************************************************************************/
 
-jchar CallNonvirtualCharMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
+jstring _Jv_JNI_NewString(JNIEnv *env, const jchar *buf, jsize len)
 {
-       java_objectheader *o;
-       classinfo         *c;
-       methodinfo        *m;
-       va_list            ap;
-       jchar              ch;
-
-       o = (java_objectheader *) obj;
-       c = (classinfo *) clazz;
-       m = (methodinfo *) methodID;
-
-       va_start(ap, methodID);
-       ch = _Jv_jni_CallIntMethod(o, c->vftbl, m, ap, PRIMITIVETYPE_CHAR);
-       va_end(ap);
-
-       return ch;
-}
-
-
-jchar CallNonvirtualCharMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
-{
-       java_objectheader *o;
-       classinfo         *c;
-       methodinfo        *m;
-       jchar              ch;
-
-       o = (java_objectheader *) obj;
-       c = (classinfo *) clazz;
-       m = (methodinfo *) methodID;
-
-       ch = _Jv_jni_CallIntMethod(o, c->vftbl, m, args, PRIMITIVETYPE_CHAR);
-
-       return ch;
-}
-
-
-jchar CallNonvirtualCharMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
-{
-       log_text("JNI-Call: CallNonvirtualCharMethodA: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-
-jshort CallNonvirtualShortMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
-{
-       java_objectheader *o;
-       classinfo         *c;
-       methodinfo        *m;
-       va_list            ap;
-       jshort             s;
-
-       o = (java_objectheader *) obj;
-       c = (classinfo *) clazz;
-       m = (methodinfo *) methodID;
-
-       va_start(ap, methodID);
-       s = _Jv_jni_CallIntMethod(o, c->vftbl, m, ap, PRIMITIVETYPE_SHORT);
-       va_end(ap);
-
-       return s;
-}
-
-
-jshort CallNonvirtualShortMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
-{
-       java_objectheader *o;
-       classinfo         *c;
-       methodinfo        *m;
-       jshort             s;
-
-       o = (java_objectheader *) obj;
-       c = (classinfo *) clazz;
-       m = (methodinfo *) methodID;
-
-       s = _Jv_jni_CallIntMethod(o, c->vftbl, m, args, PRIMITIVETYPE_SHORT);
-
-       return s;
-}
-
-
-jshort CallNonvirtualShortMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
-{
-       log_text("JNI-Call: CallNonvirtualShortMethodA: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-
-jint CallNonvirtualIntMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
-{
-       java_objectheader *o;
-       classinfo         *c;
-       methodinfo        *m;
-       va_list            ap;
-       jint               i;
-
-       o = (java_objectheader *) obj;
-       c = (classinfo *) clazz;
-       m = (methodinfo *) methodID;
-
-       va_start(ap, methodID);
-       i = _Jv_jni_CallIntMethod(o, c->vftbl, m, ap, PRIMITIVETYPE_INT);
-       va_end(ap);
-
-       return i;
-}
-
-
-jint CallNonvirtualIntMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
-{
-       java_objectheader *o;
-       classinfo         *c;
-       methodinfo        *m;
-       jint               i;
-
-       o = (java_objectheader *) obj;
-       c = (classinfo *) clazz;
-       m = (methodinfo *) methodID;
-
-       i = _Jv_jni_CallIntMethod(o, c->vftbl, m, args, PRIMITIVETYPE_INT);
-
-       return i;
-}
-
-
-jint CallNonvirtualIntMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
-{
-       log_text("JNI-Call: CallNonvirtualIntMethodA: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-
-jlong CallNonvirtualLongMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
-{
-       java_objectheader *o;
-       classinfo         *c;
-       methodinfo        *m;
-       va_list            ap;
-       jlong              l;
-
-       o = (java_objectheader *) obj;
-       c = (classinfo *) clazz;
-       m = (methodinfo *) methodID;
-
-       va_start(ap, methodID);
-       l = _Jv_jni_CallLongMethod(o, c->vftbl, m, ap);
-       va_end(ap);
-
-       return l;
-}
-
-
-jlong CallNonvirtualLongMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
-{
-       java_objectheader *o;
-       classinfo         *c;
-       methodinfo        *m;
-       jlong              l;
-
-       o = (java_objectheader *) obj;
-       c = (classinfo *) clazz;
-       m = (methodinfo *) methodID;
-
-       l = _Jv_jni_CallLongMethod(o, c->vftbl, m, args);
-
-       return l;
-}
-
-
-jlong CallNonvirtualLongMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
-{
-       log_text("JNI-Call: CallNonvirtualLongMethodA: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-
-jfloat CallNonvirtualFloatMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
-{
-       java_objectheader *o;
-       classinfo         *c;
-       methodinfo        *m;
-       va_list            ap;
-       jfloat             f;
-
-       o = (java_objectheader *) obj;
-       c = (classinfo *) clazz;
-       m = (methodinfo *) methodID;
-
-       va_start(ap, methodID);
-       f = _Jv_jni_CallFloatMethod(o, c->vftbl, m, ap);
-       va_end(ap);
-
-       return f;
-}
-
-
-jfloat CallNonvirtualFloatMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
-{
-       java_objectheader *o;
-       classinfo         *c;
-       methodinfo        *m;
-       jfloat             f;
-
-       o = (java_objectheader *) obj;
-       c = (classinfo *) clazz;
-       m = (methodinfo *) methodID;
-
-       f = _Jv_jni_CallFloatMethod(o, c->vftbl, m, args);
-
-       return f;
-}
-
-
-jfloat CallNonvirtualFloatMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
-{
-       log_text("JNI-Call: CallNonvirtualFloatMethodA: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-
-jdouble CallNonvirtualDoubleMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
-{
-       java_objectheader *o;
-       classinfo         *c;
-       methodinfo        *m;
-       va_list            ap;
-       jdouble            d;
-
-       o = (java_objectheader *) obj;
-       c = (classinfo *) clazz;
-       m = (methodinfo *) methodID;
-
-       va_start(ap, methodID);
-       d = _Jv_jni_CallDoubleMethod(o, c->vftbl, m, ap);
-       va_end(ap);
-
-       return d;
-}
-
-
-jdouble CallNonvirtualDoubleMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
-{
-       java_objectheader *o;
-       classinfo         *c;
-       methodinfo        *m;
-       jdouble            d;
-
-       o = (java_objectheader *) obj;
-       c = (classinfo *) clazz;
-       m = (methodinfo *) methodID;
-
-       d = _Jv_jni_CallDoubleMethod(o, c->vftbl, m, args);
-
-       return d;
-}
-
-
-jdouble CallNonvirtualDoubleMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue *args)
-{
-       log_text("JNI-Call: CallNonvirtualDoubleMethodA: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-
-void CallNonvirtualVoidMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
-{
-       java_objectheader *o;
-       classinfo         *c;
-       methodinfo        *m;
-       va_list            ap;
-
-       o = (java_objectheader *) obj;
-       c = (classinfo *) clazz;
-       m = (methodinfo *) methodID;
-
-       va_start(ap, methodID);
-       _Jv_jni_CallVoidMethod(o, c->vftbl, m, ap);
-       va_end(ap);
-}
-
-
-void CallNonvirtualVoidMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
-{
-       java_objectheader *o;
-       classinfo         *c;
-       methodinfo        *m;
-
-       o = (java_objectheader *) obj;
-       c = (classinfo *) clazz;
-       m = (methodinfo *) methodID;
-
-       _Jv_jni_CallVoidMethod(o, c->vftbl, m, args);
-}
-
-
-void CallNonvirtualVoidMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
-{
-       log_text("JNI-Call: CallNonvirtualVoidMethodA: IMPLEMENT ME!");
-}
-
-
-/* Accessing Fields of Objects ************************************************/
-
-/* GetFieldID ******************************************************************
-
-   Returns the field ID for an instance (nonstatic) field of a
-   class. The field is specified by its name and signature. The
-   Get<type>Field and Set<type>Field families of accessor functions
-   use field IDs to retrieve object fields.
-
-*******************************************************************************/
-
-jfieldID GetFieldID(JNIEnv *env, jclass clazz, const char *name,
-                                       const char *sig) 
-{
-       fieldinfo *f;
-       utf       *uname;
-       utf       *udesc;
-
-       STATISTICS(jniinvokation());
-
-       uname = utf_new_char((char *) name);
-       udesc = utf_new_char((char *) sig);
-
-       f = class_findfield(clazz, uname, udesc); 
-       
-       if (!f)
-               *exceptionptr = new_exception(string_java_lang_NoSuchFieldError);  
-
-       return (jfieldID) f;
-}
-
-
-/* Get<type>Field Routines *****************************************************
-
-   This family of accessor routines returns the value of an instance
-   (nonstatic) field of an object. The field to access is specified by
-   a field ID obtained by calling GetFieldID().
-
-*******************************************************************************/
-
-jobject GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID)
-{
-       java_objectheader *o;
-
-       STATISTICS(jniinvokation());
-
-       o = GET_FIELD(obj, java_objectheader*, fieldID);
-
-       return NewLocalRef(env, o);
-}
-
-
-jboolean GetBooleanField(JNIEnv *env, jobject obj, jfieldID fieldID)
-{
-       s4 i;
-
-       STATISTICS(jniinvokation());
-
-       i = GET_FIELD(obj, s4, fieldID);
-
-       return (jboolean) i;
-}
-
-
-jbyte GetByteField(JNIEnv *env, jobject obj, jfieldID fieldID)
-{
-       s4 i;
-
-       STATISTICS(jniinvokation());
-
-       i = GET_FIELD(obj, s4, fieldID);
-
-       return (jbyte) i;
-}
-
-
-jchar GetCharField(JNIEnv *env, jobject obj, jfieldID fieldID)
-{
-       s4 i;
-
-       STATISTICS(jniinvokation());
-
-       i = GET_FIELD(obj, s4, fieldID);
-
-       return (jchar) i;
-}
-
-
-jshort GetShortField(JNIEnv *env, jobject obj, jfieldID fieldID)
-{
-       s4 i;
-
-       STATISTICS(jniinvokation());
-
-       i = GET_FIELD(obj, s4, fieldID);
-
-       return (jshort) i;
-}
-
-
-jint GetIntField(JNIEnv *env, jobject obj, jfieldID fieldID)
-{
-       java_objectheader *o;
-       fieldinfo         *f;
-       s4                 i;
-
-       STATISTICS(jniinvokation());
-
-       o = (java_objectheader *) obj;
-       f = (fieldinfo *) fieldID;
-
-       i = GET_FIELD(o, s4, f);
-
-       return i;
-}
-
-
-jlong GetLongField(JNIEnv *env, jobject obj, jfieldID fieldID)
-{
-       s8 l;
-
-       STATISTICS(jniinvokation());
-
-       l = GET_FIELD(obj, s8, fieldID);
-
-       return l;
-}
-
-
-jfloat GetFloatField(JNIEnv *env, jobject obj, jfieldID fieldID)
-{
-       float f;
-
-       STATISTICS(jniinvokation());
-
-       f = GET_FIELD(obj, float, fieldID);
-
-       return f;
-}
-
-
-jdouble GetDoubleField(JNIEnv *env, jobject obj, jfieldID fieldID)
-{
-       double d;
-
-       STATISTICS(jniinvokation());
-
-       d = GET_FIELD(obj, double, fieldID);
-
-       return d;
-}
-
-
-/* Set<type>Field Routines *****************************************************
-
-   This family of accessor routines sets the value of an instance
-   (nonstatic) field of an object. The field to access is specified by
-   a field ID obtained by calling GetFieldID().
-
-*******************************************************************************/
-
-void SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID, jobject value)
-{
-       STATISTICS(jniinvokation());
-
-       SET_FIELD(obj, java_objectheader*, fieldID, value);
-}
-
-
-void SetBooleanField(JNIEnv *env, jobject obj, jfieldID fieldID, jboolean value)
-{
-       STATISTICS(jniinvokation());
-
-       SET_FIELD(obj, s4, fieldID, value);
-}
-
-
-void SetByteField(JNIEnv *env, jobject obj, jfieldID fieldID, jbyte value)
-{
-       STATISTICS(jniinvokation());
-
-       SET_FIELD(obj, s4, fieldID, value);
-}
-
-
-void SetCharField(JNIEnv *env, jobject obj, jfieldID fieldID, jchar value)
-{
-       STATISTICS(jniinvokation());
-
-       SET_FIELD(obj, s4, fieldID, value);
-}
-
-
-void SetShortField(JNIEnv *env, jobject obj, jfieldID fieldID, jshort value)
-{
-       STATISTICS(jniinvokation());
-
-       SET_FIELD(obj, s4, fieldID, value);
-}
-
-
-void SetIntField(JNIEnv *env, jobject obj, jfieldID fieldID, jint value)
-{
-       STATISTICS(jniinvokation());
-
-       SET_FIELD(obj, s4, fieldID, value);
-}
-
-
-void SetLongField(JNIEnv *env, jobject obj, jfieldID fieldID, jlong value)
-{
-       STATISTICS(jniinvokation());
-
-       SET_FIELD(obj, s8, fieldID, value);
-}
-
-
-void SetFloatField(JNIEnv *env, jobject obj, jfieldID fieldID, jfloat value)
-{
-       STATISTICS(jniinvokation());
-
-       SET_FIELD(obj, float, fieldID, value);
-}
-
-
-void SetDoubleField(JNIEnv *env, jobject obj, jfieldID fieldID, jdouble value)
-{
-       STATISTICS(jniinvokation());
-
-       SET_FIELD(obj, double, fieldID, value);
-}
-
-
-/* Calling Static Methods *****************************************************/
-
-/* GetStaticMethodID ***********************************************************
-
-   Returns the method ID for a static method of a class. The method is
-   specified by its name and signature.
-
-   GetStaticMethodID() causes an uninitialized class to be
-   initialized.
-
-*******************************************************************************/
-
-jmethodID GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name,
-                                                       const char *sig)
-{
-       classinfo  *c;
-       utf        *uname;
-       utf        *udesc;
-       methodinfo *m;
-
-       STATISTICS(jniinvokation());
-
-       c = (classinfo *) clazz;
-
-       if (!c)
-               return NULL;
-
-       if (!(c->state & CLASS_INITIALIZED))
-               if (!initialize_class(c))
-                       return NULL;
-
-       /* try to get the static method of the class */
-
-       uname = utf_new_char((char *) name);
-       udesc = utf_new_char((char *) sig);
-
-       m = class_resolvemethod(c, uname, udesc);
-
-       if ((m == NULL) || !(m->flags & ACC_STATIC)) {
-               exceptions_throw_nosuchmethoderror(c, uname, udesc);
-
-               return NULL;
-       }
-
-       return (jmethodID) m;
-}
-
-
-jobject CallStaticObjectMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
-{
-       methodinfo        *m;
-       java_objectheader *o;
-       va_list            ap;
-
-       m = (methodinfo *) methodID;
-
-       va_start(ap, methodID);
-       o = _Jv_jni_CallObjectMethod(NULL, NULL, m, ap);
-       va_end(ap);
-
-       return NewLocalRef(env, o);
-}
-
-
-jobject CallStaticObjectMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
-{
-       methodinfo        *m;
-       java_objectheader *o;
-
-       m = (methodinfo *) methodID;
-
-       o = _Jv_jni_CallObjectMethod(NULL, NULL, m, args);
-
-       return NewLocalRef(env, o);
-}
-
-
-jobject CallStaticObjectMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
-{
-       log_text("JNI-Call: CallStaticObjectMethodA: IMPLEMENT ME!");
-
-       return NewLocalRef(env, NULL);
-}
-
-
-jboolean CallStaticBooleanMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
-{
-       methodinfo *m;
-       va_list     ap;
-       jboolean    b;
-
-       m = (methodinfo *) methodID;
-
-       va_start(ap, methodID);
-       b = _Jv_jni_CallIntMethod(NULL, NULL, m, ap, PRIMITIVETYPE_BOOLEAN);
-       va_end(ap);
-
-       return b;
-}
-
-
-jboolean CallStaticBooleanMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
-{
-       methodinfo *m;
-       jboolean    b;
-
-       m = (methodinfo *) methodID;
-
-       b = _Jv_jni_CallIntMethod(NULL, NULL, m, args, PRIMITIVETYPE_BOOLEAN);
-
-       return b;
-}
-
-
-jboolean CallStaticBooleanMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
-{
-       log_text("JNI-Call: CallStaticBooleanMethodA: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-jbyte CallStaticByteMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
-{
-       methodinfo *m;
-       va_list     ap;
-       jbyte       b;
-
-       m = (methodinfo *) methodID;
-
-       va_start(ap, methodID);
-       b = _Jv_jni_CallIntMethod(NULL, NULL, m, ap, PRIMITIVETYPE_BYTE);
-       va_end(ap);
-
-       return b;
-}
-
-
-jbyte CallStaticByteMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
-{
-       methodinfo *m;
-       jbyte       b;
-
-       m = (methodinfo *) methodID;
-
-       b = _Jv_jni_CallIntMethod(NULL, NULL, m, args, PRIMITIVETYPE_BYTE);
-
-       return b;
-}
-
-
-jbyte CallStaticByteMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
-{
-       log_text("JNI-Call: CallStaticByteMethodA: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-jchar CallStaticCharMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
-{
-       methodinfo *m;
-       va_list     ap;
-       jchar       c;
-
-       m = (methodinfo *) methodID;
-
-       va_start(ap, methodID);
-       c = _Jv_jni_CallIntMethod(NULL, NULL, m, ap, PRIMITIVETYPE_CHAR);
-       va_end(ap);
-
-       return c;
-}
-
-
-jchar CallStaticCharMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
-{
-       methodinfo *m;
-       jchar       c;
-
-       m = (methodinfo *) methodID;
-
-       c = _Jv_jni_CallIntMethod(NULL, NULL, m, args, PRIMITIVETYPE_CHAR);
-
-       return c;
-}
-
-
-jchar CallStaticCharMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
-{
-       log_text("JNI-Call: CallStaticCharMethodA: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-jshort CallStaticShortMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
-{
-       methodinfo *m;
-       va_list     ap;
-       jshort      s;
-
-       m = (methodinfo *) methodID;
-
-       va_start(ap, methodID);
-       s = _Jv_jni_CallIntMethod(NULL, NULL, m, ap, PRIMITIVETYPE_SHORT);
-       va_end(ap);
-
-       return s;
-}
-
-
-jshort CallStaticShortMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
-{
-       methodinfo *m;
-       jshort      s;
-
-       m = (methodinfo *) methodID;
-
-       s = _Jv_jni_CallIntMethod(NULL, NULL, m, args, PRIMITIVETYPE_SHORT);
-
-       return s;
-}
-
-
-jshort CallStaticShortMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
-{
-       log_text("JNI-Call: CallStaticShortMethodA: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-jint CallStaticIntMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
-{
-       methodinfo *m;
-       va_list     ap;
-       jint        i;
-
-       m = (methodinfo *) methodID;
-
-       va_start(ap, methodID);
-       i = _Jv_jni_CallIntMethod(NULL, NULL, m, ap, PRIMITIVETYPE_INT);
-       va_end(ap);
-
-       return i;
-}
-
-
-jint CallStaticIntMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
-{
-       methodinfo *m;
-       jint        i;
-
-       m = (methodinfo *) methodID;
-
-       i = _Jv_jni_CallIntMethod(NULL, NULL, m, args, PRIMITIVETYPE_INT);
-
-       return i;
-}
-
-
-jint CallStaticIntMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
-{
-       log_text("JNI-Call: CallStaticIntMethodA: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-jlong CallStaticLongMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
-{
-       methodinfo *m;
-       va_list     ap;
-       jlong       l;
-
-       m = (methodinfo *) methodID;
-
-       va_start(ap, methodID);
-       l = _Jv_jni_CallLongMethod(NULL, NULL, m, ap);
-       va_end(ap);
-
-       return l;
-}
-
-
-jlong CallStaticLongMethodV(JNIEnv *env, jclass clazz, jmethodID methodID,
-                                                       va_list args)
-{
-       methodinfo *m;
-       jlong       l;
-       
-       m = (methodinfo *) methodID;
-
-       l = _Jv_jni_CallLongMethod(NULL, NULL, m, args);
-
-       return l;
-}
-
-
-jlong CallStaticLongMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
-{
-       log_text("JNI-Call: CallStaticLongMethodA: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-
-jfloat CallStaticFloatMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
-{
-       methodinfo *m;
-       va_list     ap;
-       jfloat      f;
-
-       m = (methodinfo *) methodID;
-
-       va_start(ap, methodID);
-       f = _Jv_jni_CallFloatMethod(NULL, NULL, m, ap);
-       va_end(ap);
-
-       return f;
-}
-
-
-jfloat CallStaticFloatMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
-{
-       methodinfo *m;
-       jfloat      f;
-
-       m = (methodinfo *) methodID;
-
-       f = _Jv_jni_CallFloatMethod(NULL, NULL, m, args);
-
-       return f;
-}
-
-
-jfloat CallStaticFloatMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
-{
-       log_text("JNI-Call: CallStaticFloatMethodA: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-jdouble CallStaticDoubleMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
-{
-       methodinfo *m;
-       va_list     ap;
-       jdouble     d;
-
-       m = (methodinfo *) methodID;
-
-       va_start(ap, methodID);
-       d = _Jv_jni_CallDoubleMethod(NULL, NULL, m, ap);
-       va_end(ap);
-
-       return d;
-}
-
-
-jdouble CallStaticDoubleMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
-{
-       methodinfo *m;
-       jdouble     d;
-
-       m = (methodinfo *) methodID;
-
-       d = _Jv_jni_CallDoubleMethod(NULL, NULL, m, args);
-
-       return d;
-}
-
-
-jdouble CallStaticDoubleMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
-{
-       log_text("JNI-Call: CallStaticDoubleMethodA: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-void CallStaticVoidMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
-{
-       methodinfo *m;
-       va_list     ap;
-
-       m = (methodinfo *) methodID;
-
-       va_start(ap, methodID);
-       _Jv_jni_CallVoidMethod(NULL, NULL, m, ap);
-       va_end(ap);
-}
-
-
-void CallStaticVoidMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
-{
-       methodinfo *m;
-
-       m = (methodinfo *) methodID;
-
-       _Jv_jni_CallVoidMethod(NULL, NULL, m, args);
-}
-
-
-void CallStaticVoidMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue * args)
-{
-       log_text("JNI-Call: CallStaticVoidMethodA: IMPLEMENT ME!");
-}
-
-
-/* Accessing Static Fields ****************************************************/
-
-/* GetStaticFieldID ************************************************************
-
-   Returns the field ID for a static field of a class. The field is
-   specified by its name and signature. The GetStatic<type>Field and
-   SetStatic<type>Field families of accessor functions use field IDs
-   to retrieve static fields.
-
-*******************************************************************************/
-
-jfieldID GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name, const char *sig)
-{
-       fieldinfo *f;
-
-       STATISTICS(jniinvokation());
-
-       f = class_findfield(clazz,
-                                               utf_new_char((char *) name),
-                                               utf_new_char((char *) sig));
-       
-       if (f == NULL)
-               *exceptionptr = new_exception(string_java_lang_NoSuchFieldError);
-
-       return (jfieldID) f;
-}
-
-
-/* GetStatic<type>Field ********************************************************
-
-   This family of accessor routines returns the value of a static
-   field of an object.
-
-*******************************************************************************/
-
-jobject GetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID)
-{
-       classinfo *c;
-       fieldinfo *f;
-
-       STATISTICS(jniinvokation());
-
-       c = (classinfo *) clazz;
-       f = (fieldinfo *) fieldID;
-
-       if (!(c->state & CLASS_INITIALIZED))
-               if (!initialize_class(c))
-                       return NULL;
-
-       return NewLocalRef(env, f->value.a);
-}
-
-
-jboolean GetStaticBooleanField(JNIEnv *env, jclass clazz, jfieldID fieldID)
-{
-       classinfo *c;
-       fieldinfo *f;
-
-       STATISTICS(jniinvokation());
-
-       c = (classinfo *) clazz;
-       f = (fieldinfo *) fieldID;
-
-       if (!(c->state & CLASS_INITIALIZED))
-               if (!initialize_class(c))
-                       return false;
-
-       return f->value.i;
-}
-
-
-jbyte GetStaticByteField(JNIEnv *env, jclass clazz, jfieldID fieldID)
-{
-       classinfo *c;
-       fieldinfo *f;
-
-       STATISTICS(jniinvokation());
-
-       c = (classinfo *) clazz;
-       f = (fieldinfo *) fieldID;
-
-       if (!(c->state & CLASS_INITIALIZED))
-               if (!initialize_class(c))
-                       return 0;
-
-       return f->value.i;
-}
-
-
-jchar GetStaticCharField(JNIEnv *env, jclass clazz, jfieldID fieldID)
-{
-       classinfo *c;
-       fieldinfo *f;
-
-       STATISTICS(jniinvokation());
-
-       c = (classinfo *) clazz;
-       f = (fieldinfo *) fieldID;
-
-       if (!(c->state & CLASS_INITIALIZED))
-               if (!initialize_class(c))
-                       return 0;
-
-       return f->value.i;
-}
-
-
-jshort GetStaticShortField(JNIEnv *env, jclass clazz, jfieldID fieldID)
-{
-       classinfo *c;
-       fieldinfo *f;
-
-       STATISTICS(jniinvokation());
-
-       c = (classinfo *) clazz;
-       f = (fieldinfo *) fieldID;
-
-       if (!(c->state & CLASS_INITIALIZED))
-               if (!initialize_class(c))
-                       return 0;
-
-       return f->value.i;
-}
-
-
-jint GetStaticIntField(JNIEnv *env, jclass clazz, jfieldID fieldID)
-{
-       classinfo *c;
-       fieldinfo *f;
-
-       STATISTICS(jniinvokation());
-
-       c = (classinfo *) clazz;
-       f = (fieldinfo *) fieldID;
-
-       if (!(c->state & CLASS_INITIALIZED))
-               if (!initialize_class(c))
-                       return 0;
-
-       return f->value.i;
-}
-
-
-jlong GetStaticLongField(JNIEnv *env, jclass clazz, jfieldID fieldID)
-{
-       classinfo *c;
-       fieldinfo *f;
-
-       STATISTICS(jniinvokation());
-
-       c = (classinfo *) clazz;
-       f = (fieldinfo *) fieldID;
-
-       if (!(c->state & CLASS_INITIALIZED))
-               if (!initialize_class(c))
-                       return 0;
-
-       return f->value.l;
-}
-
-
-jfloat GetStaticFloatField(JNIEnv *env, jclass clazz, jfieldID fieldID)
-{
-       classinfo *c;
-       fieldinfo *f;
-
-       STATISTICS(jniinvokation());
-
-       c = (classinfo *) clazz;
-       f = (fieldinfo *) fieldID;
-
-       if (!(c->state & CLASS_INITIALIZED))
-               if (!initialize_class(c))
-                       return 0.0;
-
-       return f->value.f;
-}
-
-
-jdouble GetStaticDoubleField(JNIEnv *env, jclass clazz, jfieldID fieldID)
-{
-       classinfo *c;
-       fieldinfo *f;
-
-       STATISTICS(jniinvokation());
-
-       c = (classinfo *) clazz;
-       f = (fieldinfo *) fieldID;
-
-       if (!(c->state & CLASS_INITIALIZED))
-               if (!initialize_class(c))
-                       return 0.0;
-
-       return f->value.d;
-}
-
-
-/*  SetStatic<type>Field *******************************************************
-
-       This family of accessor routines sets the value of a static field
-       of an object.
-
-*******************************************************************************/
-
-void SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID, jobject value)
-{
-       classinfo *c;
-       fieldinfo *f;
-
-       STATISTICS(jniinvokation());
-
-       c = (classinfo *) clazz;
-       f = (fieldinfo *) fieldID;
-
-       if (!(c->state & CLASS_INITIALIZED))
-               if (!initialize_class(c))
-                       return;
-
-       f->value.a = value;
-}
-
-
-void SetStaticBooleanField(JNIEnv *env, jclass clazz, jfieldID fieldID, jboolean value)
-{
-       classinfo *c;
-       fieldinfo *f;
-
-       STATISTICS(jniinvokation());
-
-       c = (classinfo *) clazz;
-       f = (fieldinfo *) fieldID;
-
-       if (!(c->state & CLASS_INITIALIZED))
-               if (!initialize_class(c))
-                       return;
-
-       f->value.i = value;
-}
-
-
-void SetStaticByteField(JNIEnv *env, jclass clazz, jfieldID fieldID, jbyte value)
-{
-       classinfo *c;
-       fieldinfo *f;
-
-       STATISTICS(jniinvokation());
-
-       c = (classinfo *) clazz;
-       f = (fieldinfo *) fieldID;
-
-       if (!(c->state & CLASS_INITIALIZED))
-               if (!initialize_class(c))
-                       return;
-
-       f->value.i = value;
-}
-
-
-void SetStaticCharField(JNIEnv *env, jclass clazz, jfieldID fieldID, jchar value)
-{
-       classinfo *c;
-       fieldinfo *f;
-
-       STATISTICS(jniinvokation());
-
-       c = (classinfo *) clazz;
-       f = (fieldinfo *) fieldID;
-
-       if (!(c->state & CLASS_INITIALIZED))
-               if (!initialize_class(c))
-                       return;
-
-       f->value.i = value;
-}
-
-
-void SetStaticShortField(JNIEnv *env, jclass clazz, jfieldID fieldID, jshort value)
-{
-       classinfo *c;
-       fieldinfo *f;
-
-       STATISTICS(jniinvokation());
-
-       c = (classinfo *) clazz;
-       f = (fieldinfo *) fieldID;
-
-       if (!(c->state & CLASS_INITIALIZED))
-               if (!initialize_class(c))
-                       return;
-
-       f->value.i = value;
-}
-
-
-void SetStaticIntField(JNIEnv *env, jclass clazz, jfieldID fieldID, jint value)
-{
-       classinfo *c;
-       fieldinfo *f;
-
-       STATISTICS(jniinvokation());
-
-       c = (classinfo *) clazz;
-       f = (fieldinfo *) fieldID;
-
-       if (!(c->state & CLASS_INITIALIZED))
-               if (!initialize_class(c))
-                       return;
-
-       f->value.i = value;
-}
-
-
-void SetStaticLongField(JNIEnv *env, jclass clazz, jfieldID fieldID, jlong value)
-{
-       classinfo *c;
-       fieldinfo *f;
-
-       STATISTICS(jniinvokation());
-
-       c = (classinfo *) clazz;
-       f = (fieldinfo *) fieldID;
-
-       if (!(c->state & CLASS_INITIALIZED))
-               if (!initialize_class(c))
-                       return;
-
-       f->value.l = value;
-}
-
-
-void SetStaticFloatField(JNIEnv *env, jclass clazz, jfieldID fieldID, jfloat value)
-{
-       classinfo *c;
-       fieldinfo *f;
-
-       STATISTICS(jniinvokation());
-
-       c = (classinfo *) clazz;
-       f = (fieldinfo *) fieldID;
-
-       if (!(c->state & CLASS_INITIALIZED))
-               if (!initialize_class(c))
-                       return;
-
-       f->value.f = value;
-}
-
-
-void SetStaticDoubleField(JNIEnv *env, jclass clazz, jfieldID fieldID, jdouble value)
-{
-       classinfo *c;
-       fieldinfo *f;
-
-       STATISTICS(jniinvokation());
-
-       c = (classinfo *) clazz;
-       f = (fieldinfo *) fieldID;
-
-       if (!(c->state & CLASS_INITIALIZED))
-               if (!initialize_class(c))
-                       return;
-
-       f->value.d = value;
-}
-
-
-/* String Operations **********************************************************/
-
-/* NewString *******************************************************************
-
-   Create new java.lang.String object from an array of Unicode
-   characters.
-
-*******************************************************************************/
-
-jstring NewString(JNIEnv *env, const jchar *buf, jsize len)
-{
-       java_lang_String *s;
-       java_chararray   *a;
-       u4                i;
-
-       STATISTICS(jniinvokation());
-       
-       s = (java_lang_String *) builtin_new(class_java_lang_String);
-       a = builtin_newarray_char(len);
-
-       /* javastring or characterarray could not be created */
-       if (!a || !s)
-               return NULL;
-
-       /* copy text */
-       for (i = 0; i < len; i++)
-               a->data[i] = buf[i];
-
-       s->value = a;
-       s->offset = 0;
-       s->count = len;
-
-       return (jstring) NewLocalRef(env, (jobject) s);
-}
-
-
-static jchar emptyStringJ[]={0,0};
-
-/* GetStringLength *************************************************************
-
-   Returns the length (the count of Unicode characters) of a Java
-   string.
-
-*******************************************************************************/
-
-jsize GetStringLength(JNIEnv *env, jstring str)
-{
-       return ((java_lang_String *) str)->count;
-}
-
-
-/********************  convertes javastring to u2-array ****************************/
-       
-u2 *javastring_tou2(jstring so) 
-{
-       java_lang_String *s;
-       java_chararray   *a;
-       u2               *stringbuffer;
-       u4                i;
-
-       STATISTICS(jniinvokation());
-       
-       s = (java_lang_String *) so;
-
-       if (!s)
-               return NULL;
-
-       a = s->value;
-
-       if (!a)
-               return NULL;
-
-       /* allocate memory */
-
-       stringbuffer = MNEW(u2, s->count + 1);
-
-       /* copy text */
-
-       for (i = 0; i < s->count; i++)
-               stringbuffer[i] = a->data[s->offset + i];
-       
-       /* terminate string */
-
-       stringbuffer[i] = '\0';
-
-       return stringbuffer;
-}
-
-
-/* GetStringChars **************************************************************
-
-   Returns a pointer to the array of Unicode characters of the
-   string. This pointer is valid until ReleaseStringchars() is called.
-
-*******************************************************************************/
-
-const jchar *GetStringChars(JNIEnv *env, jstring str, jboolean *isCopy)
-{      
-       jchar *jc;
-
-       STATISTICS(jniinvokation());
-
-       jc = javastring_tou2(str);
-
-       if (jc) {
-               if (isCopy)
-                       *isCopy = JNI_TRUE;
-
-               return jc;
-       }
-
-       if (isCopy)
-               *isCopy = JNI_TRUE;
-
-       return emptyStringJ;
-}
-
-
-/* ReleaseStringChars **********************************************************
-
-   Informs the VM that the native code no longer needs access to
-   chars. The chars argument is a pointer obtained from string using
-   GetStringChars().
-
-*******************************************************************************/
-
-void ReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars)
-{
-       STATISTICS(jniinvokation());
-
-       if (chars == emptyStringJ)
-               return;
-
-       MFREE(((jchar *) chars), jchar, ((java_lang_String *) str)->count + 1);
-}
-
-
-/* NewStringUTF ****************************************************************
-
-   Constructs a new java.lang.String object from an array of UTF-8 characters.
-
-*******************************************************************************/
-
-jstring NewStringUTF(JNIEnv *env, const char *bytes)
-{
-       java_lang_String *s;
-
-       STATISTICS(jniinvokation());
-
-       s = javastring_new(utf_new_char(bytes));
-
-    return (jstring) NewLocalRef(env, (jobject) s);
-}
-
-
-/****************** returns the utf8 length in bytes of a string *******************/
-
-jsize GetStringUTFLength (JNIEnv *env, jstring string)
-{   
-    java_lang_String *s = (java_lang_String*) string;
-
-       STATISTICS(jniinvokation());
-
-    return (jsize) u2_utflength(s->value->data, s->count); 
-}
-
-
-/* GetStringUTFChars ***********************************************************
-
-   Returns a pointer to an array of UTF-8 characters of the
-   string. This array is valid until it is released by
-   ReleaseStringUTFChars().
-
-*******************************************************************************/
-
-const char *GetStringUTFChars(JNIEnv *env, jstring string, jboolean *isCopy)
-{
-       utf *u;
-
-       STATISTICS(jniinvokation());
-
-       if (!string)
-               return "";
-
-       if (isCopy)
-               *isCopy = JNI_TRUE;
-       
-       u = javastring_toutf((java_lang_String *) string, false);
-
-       if (u)
-               return u->text;
-
-       return "";
-}
-
-
-/* ReleaseStringUTFChars *******************************************************
-
-   Informs the VM that the native code no longer needs access to
-   utf. The utf argument is a pointer derived from string using
-   GetStringUTFChars().
-
-*******************************************************************************/
-
-void ReleaseStringUTFChars(JNIEnv *env, jstring string, const char *utf)
-{
-       STATISTICS(jniinvokation());
-
-    /* XXX we don't release utf chars right now, perhaps that should be done 
-          later. Since there is always one reference the garbage collector will
-          never get them */
-}
-
-
-/* Array Operations ***********************************************************/
-
-/* GetArrayLength **************************************************************
-
-   Returns the number of elements in the array.
-
-*******************************************************************************/
-
-jsize GetArrayLength(JNIEnv *env, jarray array)
-{
-       java_arrayheader *a;
-
-       STATISTICS(jniinvokation());
-
-       a = (java_arrayheader *) array;
-
-       return a->size;
-}
-
-
-/* NewObjectArray **************************************************************
-
-   Constructs a new array holding objects in class elementClass. All
-   elements are initially set to initialElement.
-
-*******************************************************************************/
-
-jobjectArray NewObjectArray(JNIEnv *env, jsize length, jclass elementClass, jobject initialElement)
-{
-       java_objectarray *oa;
-       s4                i;
-
-       STATISTICS(jniinvokation());
-
-       if (length < 0) {
-               exceptions_throw_negativearraysizeexception();
-               return NULL;
-       }
-
-    oa = builtin_anewarray(length, elementClass);
-
-       if (!oa)
-               return NULL;
-
-       /* set all elements to initialElement */
-
-       for (i = 0; i < length; i++)
-               oa->data[i] = initialElement;
-
-       return (jobjectArray) NewLocalRef(env, (jobject) oa);
-}
-
-
-jobject GetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index)
-{
-       java_objectarray *oa;
-       jobject           o;
-
-       STATISTICS(jniinvokation());
-
-       oa = (java_objectarray *) array;
-
-       if (index >= oa->header.size) {
-               exceptions_throw_arrayindexoutofboundsexception();
-               return NULL;
-       }
-
-       o = oa->data[index];
-
-       return NewLocalRef(env, o);
-}
-
-
-void SetObjectArrayElement(JNIEnv *env, jobjectArray array, jsize index, jobject val)
-{
-       java_objectarray  *oa;
-       java_objectheader *o;
-
-       STATISTICS(jniinvokation());
-
-       oa = (java_objectarray *) array;
-       o  = (java_objectheader *) val;
-
-       if (index >= oa->header.size) {
-               exceptions_throw_arrayindexoutofboundsexception();
-               return;
-       }
-
-       /* check if the class of value is a subclass of the element class
-          of the array */
-
-       if (!builtin_canstore(oa, o)) {
-               *exceptionptr = new_exception(string_java_lang_ArrayStoreException);
-
-               return;
-       }
-
-       oa->data[index] = val;
-}
-
-
-jbooleanArray NewBooleanArray(JNIEnv *env, jsize len)
-{
-       java_booleanarray *ba;
-
-       STATISTICS(jniinvokation());
-
-       if (len < 0) {
-               exceptions_throw_negativearraysizeexception();
-               return NULL;
-       }
-
-       ba = builtin_newarray_boolean(len);
-
-       return (jbooleanArray) NewLocalRef(env, (jobject) ba);
-}
-
-
-jbyteArray NewByteArray(JNIEnv *env, jsize len)
-{
-       java_bytearray *ba;
-
-       STATISTICS(jniinvokation());
-
-       if (len < 0) {
-               exceptions_throw_negativearraysizeexception();
-               return NULL;
-       }
-
-       ba = builtin_newarray_byte(len);
-
-       return (jbyteArray) NewLocalRef(env, (jobject) ba);
-}
-
-
-jcharArray NewCharArray(JNIEnv *env, jsize len)
-{
-       java_chararray *ca;
-
-       STATISTICS(jniinvokation());
-
-       if (len < 0) {
-               exceptions_throw_negativearraysizeexception();
-               return NULL;
-       }
-
-       ca = builtin_newarray_char(len);
-
-       return (jcharArray) NewLocalRef(env, (jobject) ca);
-}
-
-
-jshortArray NewShortArray(JNIEnv *env, jsize len)
-{
-       java_shortarray *sa;
-
-       STATISTICS(jniinvokation());
-
-       if (len < 0) {
-               exceptions_throw_negativearraysizeexception();
-               return NULL;
-       }
-
-       sa = builtin_newarray_short(len);
-
-       return (jshortArray) NewLocalRef(env, (jobject) sa);
-}
-
-
-jintArray NewIntArray(JNIEnv *env, jsize len)
-{
-       java_intarray *ia;
-
-       STATISTICS(jniinvokation());
-
-       if (len < 0) {
-               exceptions_throw_negativearraysizeexception();
-               return NULL;
-       }
-
-       ia = builtin_newarray_int(len);
-
-       return (jintArray) NewLocalRef(env, (jobject) ia);
-}
-
-
-jlongArray NewLongArray(JNIEnv *env, jsize len)
-{
-       java_longarray *la;
+       java_lang_String        *s;
+       java_handle_chararray_t *a;
+       u4                       i;
 
        STATISTICS(jniinvokation());
+       
+       s = (java_lang_String *) builtin_new(class_java_lang_String);
+       a = builtin_newarray_char(len);
 
-       if (len < 0) {
-               exceptions_throw_negativearraysizeexception();
+       /* javastring or characterarray could not be created */
+       if ((a == NULL) || (s == NULL))
                return NULL;
-       }
-
-       la = builtin_newarray_long(len);
-
-       return (jlongArray) NewLocalRef(env, (jobject) la);
-}
-
-
-jfloatArray NewFloatArray(JNIEnv *env, jsize len)
-{
-       java_floatarray *fa;
 
-       STATISTICS(jniinvokation());
-
-       if (len < 0) {
-               exceptions_throw_negativearraysizeexception();
-               return NULL;
-       }
+       /* copy text */
+       for (i = 0; i < len; i++)
+               LLNI_array_direct(a, i) = buf[i];
 
-       fa = builtin_newarray_float(len);
+       LLNI_field_set_ref(s, value , a);
+       LLNI_field_set_val(s, offset, 0);
+       LLNI_field_set_val(s, count , len);
 
-       return (jfloatArray) NewLocalRef(env, (jobject) fa);
+       return (jstring) _Jv_JNI_NewLocalRef(env, (jobject) s);
 }
 
 
-jdoubleArray NewDoubleArray(JNIEnv *env, jsize len)
-{
-       java_doublearray *da;
-
-       STATISTICS(jniinvokation());
-
-       if (len < 0) {
-               exceptions_throw_negativearraysizeexception();
-               return NULL;
-       }
-
-       da = builtin_newarray_double(len);
-
-       return (jdoubleArray) NewLocalRef(env, (jobject) da);
-}
-
+static jchar emptyStringJ[]={0,0};
 
-/* Get<PrimitiveType>ArrayElements *********************************************
+/* GetStringLength *************************************************************
 
-   A family of functions that returns the body of the primitive array.
+   Returns the length (the count of Unicode characters) of a Java
+   string.
 
 *******************************************************************************/
 
-jboolean *GetBooleanArrayElements(JNIEnv *env, jbooleanArray array,
-                                                                 jboolean *isCopy)
-{
-       java_booleanarray *ba;
-
-       STATISTICS(jniinvokation());
-
-       ba = (java_booleanarray *) array;
-
-       if (isCopy)
-               *isCopy = JNI_FALSE;
-
-       return ba->data;
-}
-
-
-jbyte *GetByteArrayElements(JNIEnv *env, jbyteArray array, jboolean *isCopy)
+jsize _Jv_JNI_GetStringLength(JNIEnv *env, jstring str)
 {
-       java_bytearray *ba;
+       java_lang_String *s;
+       jsize             len;
 
-       STATISTICS(jniinvokation());
+       TRACEJNICALLS("_Jv_JNI_GetStringLength(env=%p, str=%p)", env, str);
 
-       ba = (java_bytearray *) array;
+       s = (java_lang_String *) str;
 
-       if (isCopy)
-               *isCopy = JNI_FALSE;
+       LLNI_field_get_val(s, count, len);
 
-       return ba->data;
+       return len;
 }
 
 
-jchar *GetCharArrayElements(JNIEnv *env, jcharArray array, jboolean *isCopy)
+/********************  convertes javastring to u2-array ****************************/
+       
+u2 *javastring_tou2(jstring so) 
 {
-       java_chararray *ca;
+       java_lang_String        *s;
+       java_handle_chararray_t *a;
+       u2                      *stringbuffer;
+       u4                       i;
+       int32_t                  count;
+       int32_t                  offset;
 
        STATISTICS(jniinvokation());
+       
+       s = (java_lang_String *) so;
 
-       ca = (java_chararray *) array;
-
-       if (isCopy)
-               *isCopy = JNI_FALSE;
-
-       return ca->data;
-}
-
-
-jshort *GetShortArrayElements(JNIEnv *env, jshortArray array, jboolean *isCopy)
-{
-       java_shortarray *sa;
-
-       STATISTICS(jniinvokation());
+       if (!s)
+               return NULL;
 
-       sa = (java_shortarray *) array;
+       LLNI_field_get_ref(s, value, a);
 
-       if (isCopy)
-               *isCopy = JNI_FALSE;
+       if (!a)
+               return NULL;
 
-       return sa->data;
-}
+       LLNI_field_get_val(s, count, count);
+       LLNI_field_get_val(s, offset, offset);
 
+       /* allocate memory */
 
-jint *GetIntArrayElements(JNIEnv *env, jintArray array, jboolean *isCopy)
-{
-       java_intarray *ia;
+       stringbuffer = MNEW(u2, count + 1);
 
-       STATISTICS(jniinvokation());
+       /* copy text */
 
-       ia = (java_intarray *) array;
+       for (i = 0; i < count; i++)
+               stringbuffer[i] = LLNI_array_direct(a, offset + i);
+       
+       /* terminate string */
 
-       if (isCopy)
-               *isCopy = JNI_FALSE;
+       stringbuffer[i] = '\0';
 
-       return ia->data;
+       return stringbuffer;
 }
 
 
-jlong *GetLongArrayElements(JNIEnv *env, jlongArray array, jboolean *isCopy)
-{
-       java_longarray *la;
-
-       STATISTICS(jniinvokation());
-
-       la = (java_longarray *) array;
-
-       if (isCopy)
-               *isCopy = JNI_FALSE;
-
-       /* We cast this one to prevent a compiler warning on 64-bit
-          systems since GNU Classpath typedef jlong to long long. */
+/* GetStringChars **************************************************************
 
-       return (jlong *) la->data;
-}
+   Returns a pointer to the array of Unicode characters of the
+   string. This pointer is valid until ReleaseStringChars() is called.
 
+*******************************************************************************/
 
-jfloat *GetFloatArrayElements(JNIEnv *env, jfloatArray array, jboolean *isCopy)
-{
-       java_floatarray *fa;
+const jchar *_Jv_JNI_GetStringChars(JNIEnv *env, jstring str, jboolean *isCopy)
+{      
+       jchar *jc;
 
        STATISTICS(jniinvokation());
 
-       fa = (java_floatarray *) array;
-
-       if (isCopy)
-               *isCopy = JNI_FALSE;
-
-       return fa->data;
-}
-
-
-jdouble *GetDoubleArrayElements(JNIEnv *env, jdoubleArray array,
-                                                               jboolean *isCopy)
-{
-       java_doublearray *da;
+       jc = javastring_tou2(str);
 
-       STATISTICS(jniinvokation());
+       if (jc) {
+               if (isCopy)
+                       *isCopy = JNI_TRUE;
 
-       da = (java_doublearray *) array;
+               return jc;
+       }
 
        if (isCopy)
-               *isCopy = JNI_FALSE;
+               *isCopy = JNI_TRUE;
 
-       return da->data;
+       return emptyStringJ;
 }
 
 
-/* Release<PrimitiveType>ArrayElements *****************************************
+/* ReleaseStringChars **********************************************************
 
-   A family of functions that informs the VM that the native code no
-   longer needs access to elems. The elems argument is a pointer
-   derived from array using the corresponding
-   Get<PrimitiveType>ArrayElements() function. If necessary, this
-   function copies back all changes made to elems to the original
-   array.
+   Informs the VM that the native code no longer needs access to
+   chars. The chars argument is a pointer obtained from string using
+   GetStringChars().
 
 *******************************************************************************/
 
-void ReleaseBooleanArrayElements(JNIEnv *env, jbooleanArray array,
-                                                                jboolean *elems, jint mode)
-{
-       java_booleanarray *ba;
-
-       STATISTICS(jniinvokation());
-
-       ba = (java_booleanarray *) array;
-
-       if (elems != ba->data) {
-               switch (mode) {
-               case JNI_COMMIT:
-                       MCOPY(ba->data, elems, u1, ba->header.size);
-                       break;
-               case 0:
-                       MCOPY(ba->data, elems, u1, ba->header.size);
-                       /* XXX TWISTI how should it be freed? */
-                       break;
-               case JNI_ABORT:
-                       /* XXX TWISTI how should it be freed? */
-                       break;
-               }
-       }
-}
-
-
-void ReleaseByteArrayElements(JNIEnv *env, jbyteArray array, jbyte *elems,
-                                                         jint mode)
+void _Jv_JNI_ReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars)
 {
-       java_bytearray *ba;
+       java_lang_String *s;
 
        STATISTICS(jniinvokation());
 
-       ba = (java_bytearray *) array;
-
-       if (elems != ba->data) {
-               switch (mode) {
-               case JNI_COMMIT:
-                       MCOPY(ba->data, elems, s1, ba->header.size);
-                       break;
-               case 0:
-                       MCOPY(ba->data, elems, s1, ba->header.size);
-                       /* XXX TWISTI how should it be freed? */
-                       break;
-               case JNI_ABORT:
-                       /* XXX TWISTI how should it be freed? */
-                       break;
-               }
-       }
-}
-
-
-void ReleaseCharArrayElements(JNIEnv *env, jcharArray array, jchar *elems,
-                                                         jint mode)
-{
-       java_chararray *ca;
+       if (chars == emptyStringJ)
+               return;
 
-       STATISTICS(jniinvokation());
+       s = (java_lang_String *) str;
 
-       ca = (java_chararray *) array;
-
-       if (elems != ca->data) {
-               switch (mode) {
-               case JNI_COMMIT:
-                       MCOPY(ca->data, elems, u2, ca->header.size);
-                       break;
-               case 0:
-                       MCOPY(ca->data, elems, u2, ca->header.size);
-                       /* XXX TWISTI how should it be freed? */
-                       break;
-               case JNI_ABORT:
-                       /* XXX TWISTI how should it be freed? */
-                       break;
-               }
-       }
+       MFREE(((jchar *) chars), jchar, LLNI_field_direct(s, count) + 1);
 }
 
 
-void ReleaseShortArrayElements(JNIEnv *env, jshortArray array, jshort *elems,
-                                                          jint mode)
-{
-       java_shortarray *sa;
-
-       STATISTICS(jniinvokation());
+/* NewStringUTF ****************************************************************
 
-       sa = (java_shortarray *) array;
-
-       if (elems != sa->data) {
-               switch (mode) {
-               case JNI_COMMIT:
-                       MCOPY(sa->data, elems, s2, sa->header.size);
-                       break;
-               case 0:
-                       MCOPY(sa->data, elems, s2, sa->header.size);
-                       /* XXX TWISTI how should it be freed? */
-                       break;
-               case JNI_ABORT:
-                       /* XXX TWISTI how should it be freed? */
-                       break;
-               }
-       }
-}
+   Constructs a new java.lang.String object from an array of UTF-8
+   characters.
 
+*******************************************************************************/
 
-void ReleaseIntArrayElements(JNIEnv *env, jintArray array, jint *elems,
-                                                        jint mode)
+jstring _Jv_JNI_NewStringUTF(JNIEnv *env, const char *bytes)
 {
-       java_intarray *ia;
-
-       STATISTICS(jniinvokation());
-
-       ia = (java_intarray *) array;
-
-       if (elems != ia->data) {
-               switch (mode) {
-               case JNI_COMMIT:
-                       MCOPY(ia->data, elems, s4, ia->header.size);
-                       break;
-               case 0:
-                       MCOPY(ia->data, elems, s4, ia->header.size);
-                       /* XXX TWISTI how should it be freed? */
-                       break;
-               case JNI_ABORT:
-                       /* XXX TWISTI how should it be freed? */
-                       break;
-               }
-       }
-}
-
+       java_lang_String *s;
 
-void ReleaseLongArrayElements(JNIEnv *env, jlongArray array, jlong *elems,
-                                                         jint mode)
-{
-       java_longarray *la;
+       TRACEJNICALLS("_Jv_JNI_NewStringUTF(env=%p, bytes=%s)", env, bytes);
 
-       STATISTICS(jniinvokation());
+       s = (java_lang_String *) javastring_safe_new_from_utf8(bytes);
 
-       la = (java_longarray *) array;
-
-       /* We cast this one to prevent a compiler warning on 64-bit
-          systems since GNU Classpath typedef jlong to long long. */
-
-       if ((s8 *) elems != la->data) {
-               switch (mode) {
-               case JNI_COMMIT:
-                       MCOPY(la->data, elems, s8, la->header.size);
-                       break;
-               case 0:
-                       MCOPY(la->data, elems, s8, la->header.size);
-                       /* XXX TWISTI how should it be freed? */
-                       break;
-               case JNI_ABORT:
-                       /* XXX TWISTI how should it be freed? */
-                       break;
-               }
-       }
+    return (jstring) _Jv_JNI_NewLocalRef(env, (jobject) s);
 }
 
 
-void ReleaseFloatArrayElements(JNIEnv *env, jfloatArray array, jfloat *elems,
-                                                          jint mode)
-{
-       java_floatarray *fa;
-
-       STATISTICS(jniinvokation());
+/****************** returns the utf8 length in bytes of a string *******************/
 
-       fa = (java_floatarray *) array;
-
-       if (elems != fa->data) {
-               switch (mode) {
-               case JNI_COMMIT:
-                       MCOPY(fa->data, elems, float, fa->header.size);
-                       break;
-               case 0:
-                       MCOPY(fa->data, elems, float, fa->header.size);
-                       /* XXX TWISTI how should it be freed? */
-                       break;
-               case JNI_ABORT:
-                       /* XXX TWISTI how should it be freed? */
-                       break;
-               }
-       }
-}
+jsize _Jv_JNI_GetStringUTFLength(JNIEnv *env, jstring string)
+{   
+       java_lang_String *s;
+       s4                length;
 
+       TRACEJNICALLS("_Jv_JNI_GetStringUTFLength(env=%p, string=%p)", env, string);
 
-void ReleaseDoubleArrayElements(JNIEnv *env, jdoubleArray array,
-                                                               jdouble *elems, jint mode)
-{
-       java_doublearray *da;
+       s = (java_lang_String *) string;
 
-       STATISTICS(jniinvokation());
+       length = u2_utflength(LLNI_field_direct(s, value)->data, LLNI_field_direct(s, count));
 
-       da = (java_doublearray *) array;
-
-       if (elems != da->data) {
-               switch (mode) {
-               case JNI_COMMIT:
-                       MCOPY(da->data, elems, double, da->header.size);
-                       break;
-               case 0:
-                       MCOPY(da->data, elems, double, da->header.size);
-                       /* XXX TWISTI how should it be freed? */
-                       break;
-               case JNI_ABORT:
-                       /* XXX TWISTI how should it be freed? */
-                       break;
-               }
-       }
+       return length;
 }
 
 
-/*  Get<PrimitiveType>ArrayRegion **********************************************
+/* GetStringUTFChars ***********************************************************
 
-       A family of functions that copies a region of a primitive array
-       into a buffer.
+   Returns a pointer to an array of UTF-8 characters of the
+   string. This array is valid until it is released by
+   ReleaseStringUTFChars().
 
 *******************************************************************************/
 
-void GetBooleanArrayRegion(JNIEnv *env, jbooleanArray array, jsize start,
-                                                  jsize len, jboolean *buf)
-{
-       java_booleanarray *ba;
-
-       STATISTICS(jniinvokation());
-
-       ba = (java_booleanarray *) array;
-
-    if ((start < 0) || (len < 0) || (start + len > ba->header.size))
-               exceptions_throw_arrayindexoutofboundsexception();
-    else
-               MCOPY(buf, &ba->data[start], u1, len);
-}
-
-
-void GetByteArrayRegion(JNIEnv *env, jbyteArray array, jsize start, jsize len,
-                                               jbyte *buf)
-{
-       java_bytearray *ba;
-
-       STATISTICS(jniinvokation());
-
-       ba = (java_bytearray *) array;
-
-       if ((start < 0) || (len < 0) || (start + len > ba->header.size))
-               exceptions_throw_arrayindexoutofboundsexception();
-       else
-               MCOPY(buf, &ba->data[start], s1, len);
-}
-
-
-void GetCharArrayRegion(JNIEnv *env, jcharArray array, jsize start, jsize len,
-                                               jchar *buf)
+const char *_Jv_JNI_GetStringUTFChars(JNIEnv *env, jstring string,
+                                                                         jboolean *isCopy)
 {
-       java_chararray *ca;
+       utf *u;
 
        STATISTICS(jniinvokation());
 
-       ca = (java_chararray *) array;
-
-       if ((start < 0) || (len < 0) || (start + len > ca->header.size))
-               exceptions_throw_arrayindexoutofboundsexception();
-       else
-               MCOPY(buf, &ca->data[start], u2, len);
-}
-
-
-void GetShortArrayRegion(JNIEnv *env, jshortArray array, jsize start,
-                                                jsize len, jshort *buf)
-{
-       java_shortarray *sa;
+       if (string == NULL)
+               return "";
 
-       STATISTICS(jniinvokation());
+       if (isCopy)
+               *isCopy = JNI_TRUE;
+       
+       u = javastring_toutf((java_handle_t *) string, false);
 
-       sa = (java_shortarray *) array;
+       if (u != NULL)
+               return u->text;
 
-       if ((start < 0) || (len < 0) || (start + len > sa->header.size))
-               exceptions_throw_arrayindexoutofboundsexception();
-       else    
-               MCOPY(buf, &sa->data[start], s2, len);
+       return "";
 }
 
 
-void GetIntArrayRegion(JNIEnv *env, jintArray array, jsize start, jsize len,
-                                          jint *buf)
-{
-       java_intarray *ia;
-
-       STATISTICS(jniinvokation());
-
-       ia = (java_intarray *) array;
+/* ReleaseStringUTFChars *******************************************************
 
-       if ((start < 0) || (len < 0) || (start + len > ia->header.size))
-               exceptions_throw_arrayindexoutofboundsexception();
-       else
-               MCOPY(buf, &ia->data[start], s4, len);
-}
+   Informs the VM that the native code no longer needs access to
+   utf. The utf argument is a pointer derived from string using
+   GetStringUTFChars().
 
+*******************************************************************************/
 
-void GetLongArrayRegion(JNIEnv *env, jlongArray array, jsize start, jsize len,
-                                               jlong *buf)
+void _Jv_JNI_ReleaseStringUTFChars(JNIEnv *env, jstring string, const char *utf)
 {
-       java_longarray *la;
-
        STATISTICS(jniinvokation());
 
-       la = (java_longarray *) array;
-
-       if ((start < 0) || (len < 0) || (start + len > la->header.size))
-               exceptions_throw_arrayindexoutofboundsexception();
-       else
-               MCOPY(buf, &la->data[start], s8, len);
+    /* XXX we don't release utf chars right now, perhaps that should be done 
+          later. Since there is always one reference the garbage collector will
+          never get them */
 }
 
 
-void GetFloatArrayRegion(JNIEnv *env, jfloatArray array, jsize start,
-                                                jsize len, jfloat *buf)
-{
-       java_floatarray *fa;
-
-       STATISTICS(jniinvokation());
+/* Array Operations ***********************************************************/
 
-       fa = (java_floatarray *) array;
+/* GetArrayLength **************************************************************
 
-       if ((start < 0) || (len < 0) || (start + len > fa->header.size))
-               exceptions_throw_arrayindexoutofboundsexception();
-       else
-               MCOPY(buf, &fa->data[start], float, len);
-}
+   Returns the number of elements in the array.
 
+*******************************************************************************/
 
-void GetDoubleArrayRegion(JNIEnv *env, jdoubleArray array, jsize start,
-                                                 jsize len, jdouble *buf)
+jsize _Jv_JNI_GetArrayLength(JNIEnv *env, jarray array)
 {
-       java_doublearray *da;
+       java_handle_t *a;
+       jsize          size;
 
        STATISTICS(jniinvokation());
 
-       da = (java_doublearray *) array;
+       a = (java_handle_t *) array;
 
-       if ((start < 0) || (len < 0) || (start + len > da->header.size))
-               exceptions_throw_arrayindexoutofboundsexception();
-       else
-               MCOPY(buf, &da->data[start], double, len);
+       size = LLNI_array_size(a);
+
+       return size;
 }
 
 
-/*  Set<PrimitiveType>ArrayRegion **********************************************
+/* NewObjectArray **************************************************************
 
-       A family of functions that copies back a region of a primitive
-       array from a buffer.
+   Constructs a new array holding objects in class elementClass. All
+   elements are initially set to initialElement.
 
 *******************************************************************************/
 
-void SetBooleanArrayRegion(JNIEnv *env, jbooleanArray array, jsize start,
-                                                  jsize len, jboolean *buf)
+jobjectArray _Jv_JNI_NewObjectArray(JNIEnv *env, jsize length,
+                                                                       jclass elementClass, jobject initialElement)
 {
-       java_booleanarray *ba;
+       classinfo                 *c;
+       java_handle_t             *o;
+       java_handle_objectarray_t *oa;
+       s4                         i;
 
        STATISTICS(jniinvokation());
 
-       ba = (java_booleanarray *) array;
+       c = LLNI_classinfo_unwrap(elementClass);
+       o = (java_handle_t *) initialElement;
 
-       if ((start < 0) || (len < 0) || (start + len > ba->header.size))
-               exceptions_throw_arrayindexoutofboundsexception();
-       else
-               MCOPY(&ba->data[start], buf, u1, len);
-}
+       if (length < 0) {
+               exceptions_throw_negativearraysizeexception();
+               return NULL;
+       }
 
+    oa = builtin_anewarray(length, c);
 
-void SetByteArrayRegion(JNIEnv *env, jbyteArray array, jsize start, jsize len,
-                                               jbyte *buf)
-{
-       java_bytearray *ba;
+       if (oa == NULL)
+               return NULL;
 
-       STATISTICS(jniinvokation());
+       /* set all elements to initialElement */
 
-       ba = (java_bytearray *) array;
+       for (i = 0; i < length; i++)
+               LLNI_objectarray_element_set(oa, i, o);
 
-       if ((start < 0) || (len < 0) || (start + len > ba->header.size))
-               exceptions_throw_arrayindexoutofboundsexception();
-       else
-               MCOPY(&ba->data[start], buf, s1, len);
+       return (jobjectArray) _Jv_JNI_NewLocalRef(env, (jobject) oa);
 }
 
 
-void SetCharArrayRegion(JNIEnv *env, jcharArray array, jsize start, jsize len,
-                                               jchar *buf)
+jobject _Jv_JNI_GetObjectArrayElement(JNIEnv *env, jobjectArray array,
+                                                                         jsize index)
 {
-       java_chararray *ca;
+       java_handle_objectarray_t *oa;
+       java_handle_t             *o;
 
        STATISTICS(jniinvokation());
 
-       ca = (java_chararray *) array;
+       oa = (java_handle_objectarray_t *) array;
 
-       if ((start < 0) || (len < 0) || (start + len > ca->header.size))
+       if (index >= LLNI_array_size(oa)) {
                exceptions_throw_arrayindexoutofboundsexception();
-       else
-               MCOPY(&ca->data[start], buf, u2, len);
+               return NULL;
+       }
+
+       LLNI_objectarray_element_get(oa, index, o);
+
+       return _Jv_JNI_NewLocalRef(env, (jobject) o);
 }
 
 
-void SetShortArrayRegion(JNIEnv *env, jshortArray array, jsize start,
-                                                jsize len, jshort *buf)
+void _Jv_JNI_SetObjectArrayElement(JNIEnv *env, jobjectArray array,
+                                                                  jsize index, jobject val)
 {
-       java_shortarray *sa;
+       java_handle_objectarray_t *oa;
+       java_handle_t             *o;
 
        STATISTICS(jniinvokation());
 
-       sa = (java_shortarray *) array;
+       oa = (java_handle_objectarray_t *) array;
+       o  = (java_handle_t *) val;
 
-       if ((start < 0) || (len < 0) || (start + len > sa->header.size))
+       if (index >= LLNI_array_size(oa)) {
                exceptions_throw_arrayindexoutofboundsexception();
-       else
-               MCOPY(&sa->data[start], buf, s2, len);
-}
+               return;
+       }
 
+       /* check if the class of value is a subclass of the element class
+          of the array */
 
-void SetIntArrayRegion(JNIEnv *env, jintArray array, jsize start, jsize len,
-                                          jint *buf)
-{
-       java_intarray *ia;
+       if (!builtin_canstore(oa, o))
+               return;
 
-       STATISTICS(jniinvokation());
+       LLNI_objectarray_element_set(oa, index, o);
+}
 
-       ia = (java_intarray *) array;
 
-       if ((start < 0) || (len < 0) || (start + len > ia->header.size))
-               exceptions_throw_arrayindexoutofboundsexception();
-       else
-               MCOPY(&ia->data[start], buf, s4, len);
+#define JNI_NEW_ARRAY(name, type, intern)                \
+type _Jv_JNI_New##name##Array(JNIEnv *env, jsize len)    \
+{                                                        \
+       java_handle_##intern##array_t *a;                    \
+                                                         \
+       STATISTICS(jniinvokation());                         \
+                                                         \
+       if (len < 0) {                                       \
+               exceptions_throw_negativearraysizeexception();   \
+               return NULL;                                     \
+       }                                                    \
+                                                         \
+       a = builtin_newarray_##intern(len);                  \
+                                                         \
+       return (type) _Jv_JNI_NewLocalRef(env, (jobject) a); \
 }
 
+JNI_NEW_ARRAY(Boolean, jbooleanArray, boolean)
+JNI_NEW_ARRAY(Byte,    jbyteArray,    byte)
+JNI_NEW_ARRAY(Char,    jcharArray,    char)
+JNI_NEW_ARRAY(Short,   jshortArray,   byte)
+JNI_NEW_ARRAY(Int,     jintArray,     int)
+JNI_NEW_ARRAY(Long,    jlongArray,    long)
+JNI_NEW_ARRAY(Float,   jfloatArray,   float)
+JNI_NEW_ARRAY(Double,  jdoubleArray,  double)
 
-void SetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start, jsize len,
-                                               jlong *buf)
-{
-       java_longarray *la;
 
-       STATISTICS(jniinvokation());
+/* Get<PrimitiveType>ArrayElements *********************************************
 
-       la = (java_longarray *) array;
+   A family of functions that returns the body of the primitive array.
 
-       if ((start < 0) || (len < 0) || (start + len > la->header.size))
-               exceptions_throw_arrayindexoutofboundsexception();
-       else
-               MCOPY(&la->data[start], buf, s8, len);
-}
+*******************************************************************************/
 
+#define JNI_GET_ARRAY_ELEMENTS(name, type, intern)                     \
+type *_Jv_JNI_Get##name##ArrayElements(JNIEnv *env, type##Array array, \
+                                                                                jboolean *isCopy)             \
+{                                                                      \
+       java_handle_##intern##array_t *a;                                  \
+                                                                       \
+       STATISTICS(jniinvokation());                                       \
+                                                                       \
+       a = (java_handle_##intern##array_t *) array;                       \
+                                                                       \
+       if (isCopy)                                                        \
+               *isCopy = JNI_FALSE;                                           \
+                                                                       \
+       return LLNI_array_data(a);                                         \
+}
+
+JNI_GET_ARRAY_ELEMENTS(Boolean, jboolean, boolean)
+JNI_GET_ARRAY_ELEMENTS(Byte,    jbyte,    byte)
+JNI_GET_ARRAY_ELEMENTS(Char,    jchar,    char)
+JNI_GET_ARRAY_ELEMENTS(Short,   jshort,   short)
+JNI_GET_ARRAY_ELEMENTS(Int,     jint,     int)
+JNI_GET_ARRAY_ELEMENTS(Long,    jlong,    long)
+JNI_GET_ARRAY_ELEMENTS(Float,   jfloat,   float)
+JNI_GET_ARRAY_ELEMENTS(Double,  jdouble,  double)
 
-void SetFloatArrayRegion(JNIEnv *env, jfloatArray array, jsize start,
-                                                jsize len, jfloat *buf)
-{
-       java_floatarray *fa;
 
-       STATISTICS(jniinvokation());
+/* Release<PrimitiveType>ArrayElements *****************************************
+
+   A family of functions that informs the VM that the native code no
+   longer needs access to elems. The elems argument is a pointer
+   derived from array using the corresponding
+   Get<PrimitiveType>ArrayElements() function. If necessary, this
+   function copies back all changes made to elems to the original
+   array.
 
-       fa = (java_floatarray *) array;
+*******************************************************************************/
 
-       if ((start < 0) || (len < 0) || (start + len > fa->header.size))
-               exceptions_throw_arrayindexoutofboundsexception();
-       else
-               MCOPY(&fa->data[start], buf, float, len);
-}
+#define JNI_RELEASE_ARRAY_ELEMENTS(name, type, intern, intern2)            \
+void _Jv_JNI_Release##name##ArrayElements(JNIEnv *env, type##Array array,  \
+                                                                                 type *elems, jint mode)          \
+{                                                                          \
+       java_handle_##intern##array_t *a;                                      \
+                                                                           \
+       STATISTICS(jniinvokation());                                           \
+                                                                           \
+       a = (java_handle_##intern##array_t *) array;                           \
+                                                                           \
+       if (elems != LLNI_array_data(a)) {                                     \
+               switch (mode) {                                                    \
+               case JNI_COMMIT:                                                   \
+                       MCOPY(LLNI_array_data(a), elems, intern2, LLNI_array_size(a)); \
+                       break;                                                         \
+               case 0:                                                            \
+                       MCOPY(LLNI_array_data(a), elems, intern2, LLNI_array_size(a)); \
+                       /* XXX TWISTI how should it be freed? */                       \
+                       break;                                                         \
+               case JNI_ABORT:                                                    \
+                       /* XXX TWISTI how should it be freed? */                       \
+                       break;                                                         \
+               }                                                                  \
+       }                                                                      \
+}
+
+JNI_RELEASE_ARRAY_ELEMENTS(Boolean, jboolean, boolean, u1)
+JNI_RELEASE_ARRAY_ELEMENTS(Byte,    jbyte,    byte,    s1)
+JNI_RELEASE_ARRAY_ELEMENTS(Char,    jchar,    char,    u2)
+JNI_RELEASE_ARRAY_ELEMENTS(Short,   jshort,   short,   s2)
+JNI_RELEASE_ARRAY_ELEMENTS(Int,     jint,     int,     s4)
+JNI_RELEASE_ARRAY_ELEMENTS(Long,    jlong,    long,    s8)
+JNI_RELEASE_ARRAY_ELEMENTS(Float,   jfloat,   float,   float)
+JNI_RELEASE_ARRAY_ELEMENTS(Double,  jdouble,  double,  double)
 
 
-void SetDoubleArrayRegion(JNIEnv *env, jdoubleArray array, jsize start,
-                                                 jsize len, jdouble *buf)
-{
-       java_doublearray *da;
+/*  Get<PrimitiveType>ArrayRegion **********************************************
 
-       STATISTICS(jniinvokation());
+       A family of functions that copies a region of a primitive array
+       into a buffer.
 
-       da = (java_doublearray *) array;
+*******************************************************************************/
 
-       if ((start < 0) || (len < 0) || (start + len > da->header.size))
-               exceptions_throw_arrayindexoutofboundsexception();
-       else
-               MCOPY(&da->data[start], buf, double, len);
-}
+#define JNI_GET_ARRAY_REGION(name, type, intern, intern2)               \
+void _Jv_JNI_Get##name##ArrayRegion(JNIEnv *env, type##Array array,     \
+                                                                       jsize start, jsize len, type *buf)  \
+{                                                                       \
+       java_handle_##intern##array_t *a;                                   \
+                                                                        \
+       STATISTICS(jniinvokation());                                        \
+                                                                        \
+       a = (java_handle_##intern##array_t *) array;                        \
+                                                                        \
+       if ((start < 0) || (len < 0) || (start + len > LLNI_array_size(a))) \
+               exceptions_throw_arrayindexoutofboundsexception();              \
+       else                                                                \
+               MCOPY(buf, &LLNI_array_direct(a, start), intern2, len);         \
+}
+
+JNI_GET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
+JNI_GET_ARRAY_REGION(Byte,    jbyte,    byte,    s1)
+JNI_GET_ARRAY_REGION(Char,    jchar,    char,    u2)
+JNI_GET_ARRAY_REGION(Short,   jshort,   short,   s2)
+JNI_GET_ARRAY_REGION(Int,     jint,     int,     s4)
+JNI_GET_ARRAY_REGION(Long,    jlong,    long,    s8)
+JNI_GET_ARRAY_REGION(Float,   jfloat,   float,   float)
+JNI_GET_ARRAY_REGION(Double,  jdouble,  double,  double)
+
+
+/*  Set<PrimitiveType>ArrayRegion **********************************************
+
+       A family of functions that copies back a region of a primitive
+       array from a buffer.
+
+*******************************************************************************/
+
+#define JNI_SET_ARRAY_REGION(name, type, intern, intern2)                    \
+void _Jv_JNI_Set##name##ArrayRegion(JNIEnv *env, type##Array array,          \
+                                                                       jsize start, jsize len, const type *buf) \
+{                                                                            \
+       java_handle_##intern##array_t *a;                                        \
+                                                                             \
+       STATISTICS(jniinvokation());                                             \
+                                                                             \
+       a = (java_handle_##intern##array_t *) array;                             \
+                                                                             \
+       if ((start < 0) || (len < 0) || (start + len > LLNI_array_size(a)))      \
+               exceptions_throw_arrayindexoutofboundsexception();                   \
+       else                                                                     \
+               MCOPY(&LLNI_array_direct(a, start), buf, intern2, len);              \
+}
+
+JNI_SET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
+JNI_SET_ARRAY_REGION(Byte,    jbyte,    byte,    s1)
+JNI_SET_ARRAY_REGION(Char,    jchar,    char,    u2)
+JNI_SET_ARRAY_REGION(Short,   jshort,   short,   s2)
+JNI_SET_ARRAY_REGION(Int,     jint,     int,     s4)
+JNI_SET_ARRAY_REGION(Long,    jlong,    long,    s8)
+JNI_SET_ARRAY_REGION(Float,   jfloat,   float,   float)
+JNI_SET_ARRAY_REGION(Double,  jdouble,  double,  double)
 
 
 /* Registering Native Methods *************************************************/
@@ -4838,12 +3130,20 @@ void SetDoubleArrayRegion(JNIEnv *env, jdoubleArray array, jsize start,
 
 *******************************************************************************/
 
-jint RegisterNatives(JNIEnv *env, jclass clazz, const JNINativeMethod *methods,
-                                        jint nMethods)
+jint _Jv_JNI_RegisterNatives(JNIEnv *env, jclass clazz,
+                                                        const JNINativeMethod *methods, jint nMethods)
 {
+       classinfo *c;
+
        STATISTICS(jniinvokation());
 
-    log_text("JNI-Call: RegisterNatives: IMPLEMENT ME!!!");
+       c = LLNI_classinfo_unwrap(clazz);
+
+       /* XXX: if implemented this needs a call to jvmti_NativeMethodBind
+       if (jvmti) jvmti_NativeMethodBind(method, address,  new_address_ptr);
+       */
+
+       native_method_register(c->name, methods, nMethods);
 
     return 0;
 }
@@ -4861,7 +3161,7 @@ jint RegisterNatives(JNIEnv *env, jclass clazz, const JNINativeMethod *methods,
 
 *******************************************************************************/
 
-jint UnregisterNatives(JNIEnv *env, jclass clazz)
+jint _Jv_JNI_UnregisterNatives(JNIEnv *env, jclass clazz)
 {
        STATISTICS(jniinvokation());
 
@@ -4882,18 +3182,16 @@ jint UnregisterNatives(JNIEnv *env, jclass clazz)
 
 *******************************************************************************/
 
-jint MonitorEnter(JNIEnv *env, jobject obj)
+jint _Jv_JNI_MonitorEnter(JNIEnv *env, jobject obj)
 {
        STATISTICS(jniinvokation());
 
-       if (!obj) {
+       if (obj == NULL) {
                exceptions_throw_nullpointerexception();
                return JNI_ERR;
        }
 
-#if defined(USE_THREADS)
-       builtin_monitorenter(obj);
-#endif
+       LOCK_MONITOR_ENTER(obj);
 
        return JNI_OK;
 }
@@ -4909,18 +3207,16 @@ jint MonitorEnter(JNIEnv *env, jobject obj)
 
 *******************************************************************************/
 
-jint MonitorExit(JNIEnv *env, jobject obj)
+jint _Jv_JNI_MonitorExit(JNIEnv *env, jobject obj)
 {
        STATISTICS(jniinvokation());
 
-       if (!obj) {
+       if (obj == NULL) {
                exceptions_throw_nullpointerexception();
                return JNI_ERR;
        }
 
-#if defined(USE_THREADS)
-       builtin_monitorexit(obj);
-#endif
+       LOCK_MONITOR_EXIT(obj);
 
        return JNI_OK;
 }
@@ -4936,29 +3232,81 @@ jint MonitorExit(JNIEnv *env, jobject obj)
 
 *******************************************************************************/
 
-jint GetJavaVM(JNIEnv *env, JavaVM **vm)
+jint _Jv_JNI_GetJavaVM(JNIEnv *env, JavaVM **vm)
 {
        STATISTICS(jniinvokation());
 
-    *vm = &ptr_jvm;
+    *vm = (JavaVM *) _Jv_jvm;
 
        return 0;
 }
 
 
-void GetStringRegion(JNIEnv* env, jstring str, jsize start, jsize len, jchar *buf)
+/* GetStringRegion *************************************************************
+
+   Copies len number of Unicode characters beginning at offset start
+   to the given buffer buf.
+
+   Throws StringIndexOutOfBoundsException on index overflow.
+
+*******************************************************************************/
+
+void _Jv_JNI_GetStringRegion(JNIEnv* env, jstring str, jsize start, jsize len,
+                                                        jchar *buf)
 {
+       java_lang_String        *s;
+       java_handle_chararray_t *ca;
+
        STATISTICS(jniinvokation());
 
-       log_text("JNI-Call: GetStringRegion: IMPLEMENT ME!");
+       s  = (java_lang_String *) str;
+       LLNI_field_get_ref(s, value, ca);
+
+       if ((start < 0) || (len < 0) || (start > LLNI_field_direct(s, count)) ||
+               (start + len > LLNI_field_direct(s, count))) {
+               exceptions_throw_stringindexoutofboundsexception();
+               return;
+       }
+
+       MCOPY(buf, &LLNI_array_direct(ca, start), u2, len);
 }
 
 
-void GetStringUTFRegion (JNIEnv* env, jstring str, jsize start, jsize len, char *buf)
+/* GetStringUTFRegion **********************************************************
+
+    Translates len number of Unicode characters beginning at offset
+    start into UTF-8 format and place the result in the given buffer
+    buf.
+
+    Throws StringIndexOutOfBoundsException on index overflow. 
+
+*******************************************************************************/
+
+void _Jv_JNI_GetStringUTFRegion(JNIEnv* env, jstring str, jsize start,
+                                                               jsize len, char *buf)
 {
-       STATISTICS(jniinvokation());
+       java_lang_String        *s;
+       java_handle_chararray_t *ca;
+       s4                       i;
+       int32_t                  count;
+       int32_t                  offset;
+
+       TRACEJNICALLS("_Jv_JNI_GetStringUTFRegion(env=%p, str=%p, start=%d, len=%d, buf=%p)", env, str, start, len, buf);
 
-       log_text("JNI-Call: GetStringUTFRegion: IMPLEMENT ME!");
+       s  = (java_lang_String *) str;
+       LLNI_field_get_ref(s, value, ca);
+       LLNI_field_get_val(s, count, count);
+       LLNI_field_get_val(s, offset, offset);
+
+       if ((start < 0) || (len < 0) || (start > count) || (start + len > count)) {
+               exceptions_throw_stringindexoutofboundsexception();
+               return;
+       }
+
+       for (i = 0; i < len; i++)
+               buf[i] = LLNI_array_direct(ca, offset + start + i);
+
+       buf[i] = '\0';
 }
 
 
@@ -4968,16 +3316,17 @@ void GetStringUTFRegion (JNIEnv* env, jstring str, jsize start, jsize len, char
 
 *******************************************************************************/
 
-void *GetPrimitiveArrayCritical(JNIEnv *env, jarray array, jboolean *isCopy)
+void *_Jv_JNI_GetPrimitiveArrayCritical(JNIEnv *env, jarray array,
+                                                                               jboolean *isCopy)
 {
-       java_bytearray *ba;
-       jbyte          *bp;
+       java_handle_bytearray_t *ba;
+       jbyte                   *bp;
 
-       ba = (java_bytearray *) array;
+       ba = (java_handle_bytearray_t *) array;
 
        /* do the same as Kaffe does */
 
-       bp = GetByteArrayElements(env, ba, isCopy);
+       bp = _Jv_JNI_GetByteArrayElements(env, (jbyteArray) ba, isCopy);
 
        return (void *) bp;
 }
@@ -4989,14 +3338,15 @@ void *GetPrimitiveArrayCritical(JNIEnv *env, jarray array, jboolean *isCopy)
 
 *******************************************************************************/
 
-void ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array, void *carray,
-                                                                  jint mode)
+void _Jv_JNI_ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array,
+                                                                                  void *carray, jint mode)
 {
        STATISTICS(jniinvokation());
 
        /* do the same as Kaffe does */
 
-       ReleaseByteArrayElements(env, (jbyteArray) array, (jbyte *) carray, mode);
+       _Jv_JNI_ReleaseByteArrayElements(env, (jbyteArray) array, (jbyte *) carray,
+                                                                        mode);
 }
 
 
@@ -5007,23 +3357,25 @@ void ReleasePrimitiveArrayCritical(JNIEnv *env, jarray array, void *carray,
 
 *******************************************************************************/
 
-const jchar *GetStringCritical(JNIEnv *env, jstring string, jboolean *isCopy)
+const jchar *_Jv_JNI_GetStringCritical(JNIEnv *env, jstring string,
+                                                                          jboolean *isCopy)
 {
        STATISTICS(jniinvokation());
 
-       return GetStringChars(env, string, isCopy);
+       return _Jv_JNI_GetStringChars(env, string, isCopy);
 }
 
 
-void ReleaseStringCritical(JNIEnv *env, jstring string, const jchar *cstring)
+void _Jv_JNI_ReleaseStringCritical(JNIEnv *env, jstring string,
+                                                                  const jchar *cstring)
 {
        STATISTICS(jniinvokation());
 
-       ReleaseStringChars(env, string, cstring);
+       _Jv_JNI_ReleaseStringChars(env, string, cstring);
 }
 
 
-jweak NewWeakGlobalRef(JNIEnv* env, jobject obj)
+jweak _Jv_JNI_NewWeakGlobalRef(JNIEnv* env, jobject obj)
 {
        STATISTICS(jniinvokation());
 
@@ -5033,7 +3385,7 @@ jweak NewWeakGlobalRef(JNIEnv* env, jobject obj)
 }
 
 
-void DeleteWeakGlobalRef(JNIEnv* env, jweak ref)
+void _Jv_JNI_DeleteWeakGlobalRef(JNIEnv* env, jweak ref)
 {
        STATISTICS(jniinvokation());
 
@@ -5048,46 +3400,61 @@ void DeleteWeakGlobalRef(JNIEnv* env, jweak ref)
 
 *******************************************************************************/
     
-jobject NewGlobalRef(JNIEnv* env, jobject lobj)
+jobject _Jv_JNI_NewGlobalRef(JNIEnv* env, jobject obj)
 {
-       java_objectheader *o;
-       java_lang_Integer *refcount;
-       java_objectheader *newval;
+       hashtable_global_ref_entry *gre;
+       u4   key;                           /* hashkey                            */
+       u4   slot;                          /* slot in hashtable                  */
+       java_handle_t *o;
 
        STATISTICS(jniinvokation());
 
-#if defined(USE_THREADS)
-       builtin_monitorenter(*global_ref_table);
-#endif
+       o = (java_handle_t *) obj;
+
+       LOCK_MONITOR_ENTER(hashtable_global_ref->header);
+
+       /* normally addresses are aligned to 4, 8 or 16 bytes */
+
+       key  = ((u4) (ptrint) obj) >> 4;           /* align to 16-byte boundaries */
+       slot = key & (hashtable_global_ref->size - 1);
+       gre  = hashtable_global_ref->ptr[slot];
        
-       ASM_CALLJAVAFUNCTION_ADR(o, getmid, *global_ref_table, lobj, NULL, NULL);
+       /* search external hash chain for the entry */
 
-       refcount = (java_lang_Integer *) o;
+       while (gre) {
+               if (gre->o == o) {
+                       /* global object found, increment the reference */
 
-       if (refcount == NULL) {
-               newval = native_new_and_init_int(class_java_lang_Integer, 1);
+                       gre->refs++;
 
-               if (newval == NULL) {
-#if defined(USE_THREADS)
-                       builtin_monitorexit(*global_ref_table);
-#endif
-                       return NULL;
+                       LOCK_MONITOR_EXIT(hashtable_global_ref->header);
+
+                       return obj;
                }
 
-               ASM_CALLJAVAFUNCTION(putmid, *global_ref_table, lobj, newval, NULL);
+               gre = gre->hashlink;                /* next element in external chain */
+       }
 
-       } else {
-               /* we can access the object itself, as we are in a
-           synchronized section */
+       /* global ref not found, create a new one */
 
-               refcount->value++;
-       }
+       gre = NEW(hashtable_global_ref_entry);
 
-#if defined(USE_THREADS)
-       builtin_monitorexit(*global_ref_table);
-#endif
+       gre->o    = o;
+       gre->refs = 1;
+
+       /* insert entry into hashtable */
+
+       gre->hashlink = hashtable_global_ref->ptr[slot];
+
+       hashtable_global_ref->ptr[slot] = gre;
 
-       return lobj;
+       /* update number of hashtable-entries */
+
+       hashtable_global_ref->entries++;
+
+       LOCK_MONITOR_EXIT(hashtable_global_ref->header);
+
+       return obj;
 }
 
 
@@ -5097,47 +3464,63 @@ jobject NewGlobalRef(JNIEnv* env, jobject lobj)
 
 *******************************************************************************/
 
-void DeleteGlobalRef(JNIEnv* env, jobject globalRef)
+void _Jv_JNI_DeleteGlobalRef(JNIEnv* env, jobject globalRef)
 {
-       java_objectheader *o;
-       java_lang_Integer *refcount;
-       s4                 val;
+       hashtable_global_ref_entry *gre;
+       hashtable_global_ref_entry *prevgre;
+       u4   key;                           /* hashkey                            */
+       u4   slot;                          /* slot in hashtable                  */
+       java_handle_t              *o;
 
        STATISTICS(jniinvokation());
 
-#if defined(USE_THREADS)
-       builtin_monitorenter(*global_ref_table);
-#endif
+       o = (java_handle_t *) globalRef;
 
-       ASM_CALLJAVAFUNCTION_ADR(o, getmid, *global_ref_table, globalRef, NULL,
-                                                        NULL);
+       LOCK_MONITOR_ENTER(hashtable_global_ref->header);
 
-       refcount = (java_lang_Integer *) o;
+       /* normally addresses are aligned to 4, 8 or 16 bytes */
 
-       if (refcount == NULL) {
-               log_text("JNI-DeleteGlobalRef: unable to find global reference");
-               return;
-       }
+       key  = ((u4) (ptrint) globalRef) >> 4;     /* align to 16-byte boundaries */
+       slot = key & (hashtable_global_ref->size - 1);
+       gre  = hashtable_global_ref->ptr[slot];
 
-       /* we can access the object itself, as we are in a synchronized
-          section */
+       /* initialize prevgre */
 
-       val = refcount->value - 1;
+       prevgre = NULL;
 
-       if (val == 0) {
-               ASM_CALLJAVAFUNCTION(removemid, *global_ref_table, refcount, NULL,
-                                                        NULL);
+       /* search external hash chain for the entry */
 
-       } else {
-               /* we do not create a new object, but set the new value into
-           the old one */
+       while (gre) {
+               if (gre->o == o) {
+                       /* global object found, decrement the reference count */
+
+                       gre->refs--;
+
+                       /* if reference count is 0, remove the entry */
+
+                       if (gre->refs == 0) {
+                               /* special handling if it's the first in the chain */
+
+                               if (prevgre == NULL)
+                                       hashtable_global_ref->ptr[slot] = gre->hashlink;
+                               else
+                                       prevgre->hashlink = gre->hashlink;
+
+                               FREE(gre, hashtable_global_ref_entry);
+                       }
+
+                       LOCK_MONITOR_EXIT(hashtable_global_ref->header);
+
+                       return;
+               }
 
-               refcount->value = val;
+               prevgre = gre;                    /* save current pointer for removal */
+               gre     = gre->hashlink;            /* next element in external chain */
        }
 
-#if defined(USE_THREADS)
-       builtin_monitorexit(*global_ref_table);
-#endif
+       log_println("JNI-DeleteGlobalRef: global reference not found");
+
+       LOCK_MONITOR_EXIT(hashtable_global_ref->header);
 }
 
 
@@ -5148,11 +3531,15 @@ void DeleteGlobalRef(JNIEnv* env, jobject globalRef)
 
 *******************************************************************************/
 
-jboolean ExceptionCheck(JNIEnv *env)
+jboolean _Jv_JNI_ExceptionCheck(JNIEnv *env)
 {
+       java_handle_t *o;
+
        STATISTICS(jniinvokation());
 
-       return *exceptionptr ? JNI_TRUE : JNI_FALSE;
+       o = exceptions_get_exception();
+
+       return (o != NULL) ? JNI_TRUE : JNI_FALSE;
 }
 
 
@@ -5166,31 +3553,33 @@ jboolean ExceptionCheck(JNIEnv *env)
 
 *******************************************************************************/
 
-jobject NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
+jobject _Jv_JNI_NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
 {
-       java_objectheader       *nbuf;
-#if SIZEOF_VOID_P == 8
+#if defined(ENABLE_JAVASE) && defined(WITH_CLASSPATH_GNU)
+       java_handle_t           *nbuf;
+
+# if SIZEOF_VOID_P == 8
        gnu_classpath_Pointer64 *paddress;
-#else
+# else
        gnu_classpath_Pointer32 *paddress;
-#endif
+# endif
 
        STATISTICS(jniinvokation());
 
        /* alocate a gnu.classpath.Pointer{32,64} object */
 
-#if SIZEOF_VOID_P == 8
+# if SIZEOF_VOID_P == 8
        if (!(paddress = (gnu_classpath_Pointer64 *)
                  builtin_new(class_gnu_classpath_Pointer64)))
-#else
+# else
        if (!(paddress = (gnu_classpath_Pointer32 *)
                  builtin_new(class_gnu_classpath_Pointer32)))
-#endif
+# endif
                return NULL;
 
        /* fill gnu.classpath.Pointer{32,64} with address */
 
-       paddress->data = (ptrint) address;
+       LLNI_field_set_val(paddress, data, (ptrint) address);
 
        /* create a java.nio.DirectByteBufferImpl$ReadWrite object */
 
@@ -5200,7 +3589,14 @@ jobject NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
 
        /* add local reference and return the value */
 
-       return NewLocalRef(env, nbuf);
+       return _Jv_JNI_NewLocalRef(env, nbuf);
+#else
+       vm_abort("_Jv_JNI_NewDirectByteBuffer: not implemented in this configuration");
+
+       /* keep compiler happy */
+
+       return NULL;
+#endif
 }
 
 
@@ -5211,14 +3607,16 @@ jobject NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
 
 *******************************************************************************/
 
-void *GetDirectBufferAddress(JNIEnv *env, jobject buf)
+void *_Jv_JNI_GetDirectBufferAddress(JNIEnv *env, jobject buf)
 {
+#if defined(ENABLE_JAVASE) && defined(WITH_CLASSPATH_GNU)
        java_nio_DirectByteBufferImpl *nbuf;
-#if SIZEOF_VOID_P == 8
-       gnu_classpath_Pointer64       *address;
-#else
-       gnu_classpath_Pointer32       *address;
-#endif
+# if SIZEOF_VOID_P == 8
+       gnu_classpath_Pointer64       *paddress;
+# else
+       gnu_classpath_Pointer32       *paddress;
+# endif
+       void                          *address;
 
        STATISTICS(jniinvokation());
 
@@ -5227,13 +3625,28 @@ void *GetDirectBufferAddress(JNIEnv *env, jobject buf)
 
        nbuf = (java_nio_DirectByteBufferImpl *) buf;
 
-#if SIZEOF_VOID_P == 8
-       address = (gnu_classpath_Pointer64 *) nbuf->address;
+# if SIZEOF_VOID_P == 8
+       LLNI_field_get_ref(nbuf, address, paddress);
+       /* this was the cast to avaoid warning: (gnu_classpath_Pointer64 *) nbuf->address; */
+# else
+       LLNI_field_get_ref(nbuf, address, paddress); 
+       /* this was the cast to avaoid warning: (gnu_classpath_Pointer32 *) nbuf->address; */
+# endif
+
+       if (paddress == NULL)
+               return NULL;
+
+       LLNI_field_get_val(paddress, data, address);
+       /* this was the cast to avaoid warning: (void *) paddress->data */
+
+       return address;
 #else
-       address = (gnu_classpath_Pointer32 *) nbuf->address;
-#endif
+       vm_abort("_Jv_JNI_GetDirectBufferAddress: not implemented in this configuration");
 
-       return (void *) address->data;
+       /* keep compiler happy */
+
+       return NULL;
+#endif
 }
 
 
@@ -5244,18 +3657,32 @@ void *GetDirectBufferAddress(JNIEnv *env, jobject buf)
 
 *******************************************************************************/
 
-jlong GetDirectBufferCapacity(JNIEnv* env, jobject buf)
+jlong _Jv_JNI_GetDirectBufferCapacity(JNIEnv* env, jobject buf)
 {
+#if defined(ENABLE_JAVASE) && defined(WITH_CLASSPATH_GNU)
+       java_handle_t   *o;
        java_nio_Buffer *nbuf;
+       jlong            capacity;
 
        STATISTICS(jniinvokation());
 
-       if (!builtin_instanceof(buf, class_java_nio_DirectByteBufferImpl))
+       o = (java_handle_t *) buf;
+
+       if (!builtin_instanceof(o, class_java_nio_DirectByteBufferImpl))
                return -1;
 
-       nbuf = (java_nio_Buffer *) buf;
+       nbuf = (java_nio_Buffer *) o;
+
+       LLNI_field_get_val(nbuf, cap, capacity);
+
+       return capacity;
+#else
+       vm_abort("_Jv_JNI_GetDirectBufferCapacity: not implemented in this configuration");
+
+       /* keep compiler happy */
 
-       return (jlong) nbuf->cap;
+       return 0;
+#endif
 }
 
 
@@ -5267,7 +3694,7 @@ jlong GetDirectBufferCapacity(JNIEnv* env, jobject buf)
 
 *******************************************************************************/
 
-jint DestroyJavaVM(JavaVM *vm)
+jint _Jv_JNI_DestroyJavaVM(JavaVM *vm)
 {
        s4 status;
 
@@ -5293,31 +3720,76 @@ jint DestroyJavaVM(JavaVM *vm)
 
 *******************************************************************************/
 
-jint AttachCurrentThread(JavaVM *vm, void **env, void *thr_args)
+static s4 jni_attach_current_thread(void **p_env, void *thr_args, bool isdaemon)
 {
-       STATISTICS(jniinvokation());
+       JavaVMAttachArgs *vm_aargs;
 
-       log_text("JNI-Call: AttachCurrentThread: IMPLEMENT ME!");
+#if defined(ENABLE_THREADS)
+       if (threads_get_current_threadobject() == NULL) {
+               vm_aargs = (JavaVMAttachArgs *) thr_args;
 
-#if !defined(HAVE___THREAD)
-/*     cacao_thread_attach();*/
-#else
-       #error "No idea how to implement that. Perhaps Stefan knows"
+               if (vm_aargs != NULL) {
+                       if ((vm_aargs->version != JNI_VERSION_1_2) &&
+                               (vm_aargs->version != JNI_VERSION_1_4))
+                               return JNI_EVERSION;
+               }
+
+               if (!threads_attach_current_thread(vm_aargs, false))
+                       return JNI_ERR;
+
+               if (!localref_table_init())
+                       return JNI_ERR;
+       }
 #endif
 
-       *env = &ptr_env;
+       *p_env = _Jv_env;
 
-       return 0;
+       return JNI_OK;
 }
 
 
-jint DetachCurrentThread(JavaVM *vm)
+jint _Jv_JNI_AttachCurrentThread(JavaVM *vm, void **p_env, void *thr_args)
 {
        STATISTICS(jniinvokation());
 
-       log_text("JNI-Call: DetachCurrentThread: IMPLEMENT ME!");
+       return jni_attach_current_thread(p_env, thr_args, false);
+}
 
-       return 0;
+
+/* DetachCurrentThread *********************************************************
+
+   Detaches the current thread from a Java VM. All Java monitors held
+   by this thread are released. All Java threads waiting for this
+   thread to die are notified.
+
+   In JDK 1.1, the main thread cannot be detached from the VM. It must
+   call DestroyJavaVM to unload the entire VM.
+
+   In the JDK, the main thread can be detached from the VM.
+
+   The main thread, which is the thread that created the Java VM,
+   cannot be detached from the VM. Instead, the main thread must call
+   JNI_DestroyJavaVM() to unload the entire VM.
+
+*******************************************************************************/
+
+jint _Jv_JNI_DetachCurrentThread(JavaVM *vm)
+{
+#if defined(ENABLE_THREADS)
+       threadobject *thread;
+
+       STATISTICS(jniinvokation());
+
+       thread = threads_get_current_threadobject();
+
+       if (thread == NULL)
+               return JNI_ERR;
+
+       if (!threads_detach_thread(thread))
+               return JNI_ERR;
+#endif
+
+       return JNI_OK;
 }
 
 
@@ -5330,28 +3802,36 @@ jint DetachCurrentThread(JavaVM *vm)
 
 *******************************************************************************/
 
-jint GetEnv(JavaVM *vm, void **env, jint version)
+jint _Jv_JNI_GetEnv(JavaVM *vm, void **env, jint version)
 {
        STATISTICS(jniinvokation());
 
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
-       if (thread_getself() == NULL) {
+#if defined(ENABLE_THREADS)
+       if (threads_get_current_threadobject() == NULL) {
                *env = NULL;
 
                return JNI_EDETACHED;
        }
 #endif
 
-       if ((version == JNI_VERSION_1_1) || (version == JNI_VERSION_1_2) ||
-               (version == JNI_VERSION_1_4)) {
-               *env = &ptr_env;
+       /* check the JNI version */
 
+       switch (version) {
+       case JNI_VERSION_1_1:
+       case JNI_VERSION_1_2:
+       case JNI_VERSION_1_4:
+               *env = _Jv_env;
                return JNI_OK;
+
+       default:
+               ;
        }
 
 #if defined(ENABLE_JVMTI)
-       if (version == JVMTI_VERSION_1_0) {
-               *env = (void *) new_jvmtienv();
+       if ((version & JVMTI_VERSION_MASK_INTERFACE_TYPE) 
+               == JVMTI_VERSION_INTERFACE_JVMTI) {
+
+               *env = (void *) jvmti_new_environment();
 
                if (env != NULL)
                        return JNI_OK;
@@ -5364,302 +3844,312 @@ jint GetEnv(JavaVM *vm, void **env, jint version)
 }
 
 
+/* AttachCurrentThreadAsDaemon *************************************************
 
-jint AttachCurrentThreadAsDaemon(JavaVM *vm, void **par1, void *par2)
+   Same semantics as AttachCurrentThread, but the newly-created
+   java.lang.Thread instance is a daemon.
+
+   If the thread has already been attached via either
+   AttachCurrentThread or AttachCurrentThreadAsDaemon, this routine
+   simply sets the value pointed to by penv to the JNIEnv of the
+   current thread. In this case neither AttachCurrentThread nor this
+   routine have any effect on the daemon status of the thread.
+
+*******************************************************************************/
+
+jint _Jv_JNI_AttachCurrentThreadAsDaemon(JavaVM *vm, void **penv, void *args)
 {
        STATISTICS(jniinvokation());
 
-       log_text("JNI-Call: AttachCurrentThreadAsDaemon: IMPLEMENT ME!");
-
-       return 0;
+       return jni_attach_current_thread(penv, args, true);
 }
 
 
 /* JNI invocation table *******************************************************/
 
-const struct JNIInvokeInterface JNI_JavaVMTable = {
+const struct JNIInvokeInterface_ _Jv_JNIInvokeInterface = {
        NULL,
        NULL,
        NULL,
 
-       DestroyJavaVM,
-       AttachCurrentThread,
-       DetachCurrentThread,
-       GetEnv,
-       AttachCurrentThreadAsDaemon
+       _Jv_JNI_DestroyJavaVM,
+       _Jv_JNI_AttachCurrentThread,
+       _Jv_JNI_DetachCurrentThread,
+       _Jv_JNI_GetEnv,
+       _Jv_JNI_AttachCurrentThreadAsDaemon
 };
 
 
 /* JNI function table *********************************************************/
 
-struct JNINativeInterface JNI_JNIEnvTable = {
+struct JNINativeInterface_ _Jv_JNINativeInterface = {
        NULL,
        NULL,
        NULL,
        NULL,    
-       GetVersion,
-
-       DefineClass,
-       FindClass,
-       FromReflectedMethod,
-       FromReflectedField,
-       ToReflectedMethod,
-       GetSuperclass,
-       IsAssignableFrom,
-       ToReflectedField,
-
-       Throw,
-       ThrowNew,
-       ExceptionOccurred,
-       ExceptionDescribe,
-       ExceptionClear,
-       FatalError,
-       PushLocalFrame,
-       PopLocalFrame,
-
-       NewGlobalRef,
-       DeleteGlobalRef,
-       DeleteLocalRef,
-       IsSameObject,
-       NewLocalRef,
-       EnsureLocalCapacity,
-
-       AllocObject,
-       NewObject,
-       NewObjectV,
-       NewObjectA,
-
-       GetObjectClass,
-       IsInstanceOf,
-
-       GetMethodID,
-
-       CallObjectMethod,
-       CallObjectMethodV,
-       CallObjectMethodA,
-       CallBooleanMethod,
-       CallBooleanMethodV,
-       CallBooleanMethodA,
-       CallByteMethod,
-       CallByteMethodV,
-       CallByteMethodA,
-       CallCharMethod,
-       CallCharMethodV,
-       CallCharMethodA,
-       CallShortMethod,
-       CallShortMethodV,
-       CallShortMethodA,
-       CallIntMethod,
-       CallIntMethodV,
-       CallIntMethodA,
-       CallLongMethod,
-       CallLongMethodV,
-       CallLongMethodA,
-       CallFloatMethod,
-       CallFloatMethodV,
-       CallFloatMethodA,
-       CallDoubleMethod,
-       CallDoubleMethodV,
-       CallDoubleMethodA,
-       CallVoidMethod,
-       CallVoidMethodV,
-       CallVoidMethodA,
-
-       CallNonvirtualObjectMethod,
-       CallNonvirtualObjectMethodV,
-       CallNonvirtualObjectMethodA,
-       CallNonvirtualBooleanMethod,
-       CallNonvirtualBooleanMethodV,
-       CallNonvirtualBooleanMethodA,
-       CallNonvirtualByteMethod,
-       CallNonvirtualByteMethodV,
-       CallNonvirtualByteMethodA,
-       CallNonvirtualCharMethod,
-       CallNonvirtualCharMethodV,
-       CallNonvirtualCharMethodA,
-       CallNonvirtualShortMethod,
-       CallNonvirtualShortMethodV,
-       CallNonvirtualShortMethodA,
-       CallNonvirtualIntMethod,
-       CallNonvirtualIntMethodV,
-       CallNonvirtualIntMethodA,
-       CallNonvirtualLongMethod,
-       CallNonvirtualLongMethodV,
-       CallNonvirtualLongMethodA,
-       CallNonvirtualFloatMethod,
-       CallNonvirtualFloatMethodV,
-       CallNonvirtualFloatMethodA,
-       CallNonvirtualDoubleMethod,
-       CallNonvirtualDoubleMethodV,
-       CallNonvirtualDoubleMethodA,
-       CallNonvirtualVoidMethod,
-       CallNonvirtualVoidMethodV,
-       CallNonvirtualVoidMethodA,
-
-       GetFieldID,
-
-       GetObjectField,
-       GetBooleanField,
-       GetByteField,
-       GetCharField,
-       GetShortField,
-       GetIntField,
-       GetLongField,
-       GetFloatField,
-       GetDoubleField,
-       SetObjectField,
-       SetBooleanField,
-       SetByteField,
-       SetCharField,
-       SetShortField,
-       SetIntField,
-       SetLongField,
-       SetFloatField,
-       SetDoubleField,
-
-       GetStaticMethodID,
-
-       CallStaticObjectMethod,
-       CallStaticObjectMethodV,
-       CallStaticObjectMethodA,
-       CallStaticBooleanMethod,
-       CallStaticBooleanMethodV,
-       CallStaticBooleanMethodA,
-       CallStaticByteMethod,
-       CallStaticByteMethodV,
-       CallStaticByteMethodA,
-       CallStaticCharMethod,
-       CallStaticCharMethodV,
-       CallStaticCharMethodA,
-       CallStaticShortMethod,
-       CallStaticShortMethodV,
-       CallStaticShortMethodA,
-       CallStaticIntMethod,
-       CallStaticIntMethodV,
-       CallStaticIntMethodA,
-       CallStaticLongMethod,
-       CallStaticLongMethodV,
-       CallStaticLongMethodA,
-       CallStaticFloatMethod,
-       CallStaticFloatMethodV,
-       CallStaticFloatMethodA,
-       CallStaticDoubleMethod,
-       CallStaticDoubleMethodV,
-       CallStaticDoubleMethodA,
-       CallStaticVoidMethod,
-       CallStaticVoidMethodV,
-       CallStaticVoidMethodA,
-
-       GetStaticFieldID,
-
-       GetStaticObjectField,
-       GetStaticBooleanField,
-       GetStaticByteField,
-       GetStaticCharField,
-       GetStaticShortField,
-       GetStaticIntField,
-       GetStaticLongField,
-       GetStaticFloatField,
-       GetStaticDoubleField,
-       SetStaticObjectField,
-       SetStaticBooleanField,
-       SetStaticByteField,
-       SetStaticCharField,
-       SetStaticShortField,
-       SetStaticIntField,
-       SetStaticLongField,
-       SetStaticFloatField,
-       SetStaticDoubleField,
-
-       NewString,
-       GetStringLength,
-       GetStringChars,
-       ReleaseStringChars,
-
-       NewStringUTF,
-       GetStringUTFLength,
-       GetStringUTFChars,
-       ReleaseStringUTFChars,
-
-       GetArrayLength,
-
-       NewObjectArray,
-       GetObjectArrayElement,
-       SetObjectArrayElement,
-
-       NewBooleanArray,
-       NewByteArray,
-       NewCharArray,
-       NewShortArray,
-       NewIntArray,
-       NewLongArray,
-       NewFloatArray,
-       NewDoubleArray,
-
-       GetBooleanArrayElements,
-       GetByteArrayElements,
-       GetCharArrayElements,
-       GetShortArrayElements,
-       GetIntArrayElements,
-       GetLongArrayElements,
-       GetFloatArrayElements,
-       GetDoubleArrayElements,
-
-       ReleaseBooleanArrayElements,
-       ReleaseByteArrayElements,
-       ReleaseCharArrayElements,
-       ReleaseShortArrayElements,
-       ReleaseIntArrayElements,
-       ReleaseLongArrayElements,
-       ReleaseFloatArrayElements,
-       ReleaseDoubleArrayElements,
-
-       GetBooleanArrayRegion,
-       GetByteArrayRegion,
-       GetCharArrayRegion,
-       GetShortArrayRegion,
-       GetIntArrayRegion,
-       GetLongArrayRegion,
-       GetFloatArrayRegion,
-       GetDoubleArrayRegion,
-       SetBooleanArrayRegion,
-       SetByteArrayRegion,
-       SetCharArrayRegion,
-       SetShortArrayRegion,
-       SetIntArrayRegion,
-       SetLongArrayRegion,
-       SetFloatArrayRegion,
-       SetDoubleArrayRegion,
-
-       RegisterNatives,
-       UnregisterNatives,
-
-       MonitorEnter,
-       MonitorExit,
-
-       GetJavaVM,
+       _Jv_JNI_GetVersion,
+
+       _Jv_JNI_DefineClass,
+       _Jv_JNI_FindClass,
+       _Jv_JNI_FromReflectedMethod,
+       _Jv_JNI_FromReflectedField,
+       _Jv_JNI_ToReflectedMethod,
+       _Jv_JNI_GetSuperclass,
+       _Jv_JNI_IsAssignableFrom,
+       _Jv_JNI_ToReflectedField,
+
+       _Jv_JNI_Throw,
+       _Jv_JNI_ThrowNew,
+       _Jv_JNI_ExceptionOccurred,
+       _Jv_JNI_ExceptionDescribe,
+       _Jv_JNI_ExceptionClear,
+       _Jv_JNI_FatalError,
+       _Jv_JNI_PushLocalFrame,
+       _Jv_JNI_PopLocalFrame,
+
+       _Jv_JNI_NewGlobalRef,
+       _Jv_JNI_DeleteGlobalRef,
+       _Jv_JNI_DeleteLocalRef,
+       _Jv_JNI_IsSameObject,
+       _Jv_JNI_NewLocalRef,
+       _Jv_JNI_EnsureLocalCapacity,
+
+       _Jv_JNI_AllocObject,
+       _Jv_JNI_NewObject,
+       _Jv_JNI_NewObjectV,
+       _Jv_JNI_NewObjectA,
+
+       _Jv_JNI_GetObjectClass,
+       _Jv_JNI_IsInstanceOf,
+
+       _Jv_JNI_GetMethodID,
+
+       _Jv_JNI_CallObjectMethod,
+       _Jv_JNI_CallObjectMethodV,
+       _Jv_JNI_CallObjectMethodA,
+       _Jv_JNI_CallBooleanMethod,
+       _Jv_JNI_CallBooleanMethodV,
+       _Jv_JNI_CallBooleanMethodA,
+       _Jv_JNI_CallByteMethod,
+       _Jv_JNI_CallByteMethodV,
+       _Jv_JNI_CallByteMethodA,
+       _Jv_JNI_CallCharMethod,
+       _Jv_JNI_CallCharMethodV,
+       _Jv_JNI_CallCharMethodA,
+       _Jv_JNI_CallShortMethod,
+       _Jv_JNI_CallShortMethodV,
+       _Jv_JNI_CallShortMethodA,
+       _Jv_JNI_CallIntMethod,
+       _Jv_JNI_CallIntMethodV,
+       _Jv_JNI_CallIntMethodA,
+       _Jv_JNI_CallLongMethod,
+       _Jv_JNI_CallLongMethodV,
+       _Jv_JNI_CallLongMethodA,
+       _Jv_JNI_CallFloatMethod,
+       _Jv_JNI_CallFloatMethodV,
+       _Jv_JNI_CallFloatMethodA,
+       _Jv_JNI_CallDoubleMethod,
+       _Jv_JNI_CallDoubleMethodV,
+       _Jv_JNI_CallDoubleMethodA,
+       _Jv_JNI_CallVoidMethod,
+       _Jv_JNI_CallVoidMethodV,
+       _Jv_JNI_CallVoidMethodA,
+
+       _Jv_JNI_CallNonvirtualObjectMethod,
+       _Jv_JNI_CallNonvirtualObjectMethodV,
+       _Jv_JNI_CallNonvirtualObjectMethodA,
+       _Jv_JNI_CallNonvirtualBooleanMethod,
+       _Jv_JNI_CallNonvirtualBooleanMethodV,
+       _Jv_JNI_CallNonvirtualBooleanMethodA,
+       _Jv_JNI_CallNonvirtualByteMethod,
+       _Jv_JNI_CallNonvirtualByteMethodV,
+       _Jv_JNI_CallNonvirtualByteMethodA,
+       _Jv_JNI_CallNonvirtualCharMethod,
+       _Jv_JNI_CallNonvirtualCharMethodV,
+       _Jv_JNI_CallNonvirtualCharMethodA,
+       _Jv_JNI_CallNonvirtualShortMethod,
+       _Jv_JNI_CallNonvirtualShortMethodV,
+       _Jv_JNI_CallNonvirtualShortMethodA,
+       _Jv_JNI_CallNonvirtualIntMethod,
+       _Jv_JNI_CallNonvirtualIntMethodV,
+       _Jv_JNI_CallNonvirtualIntMethodA,
+       _Jv_JNI_CallNonvirtualLongMethod,
+       _Jv_JNI_CallNonvirtualLongMethodV,
+       _Jv_JNI_CallNonvirtualLongMethodA,
+       _Jv_JNI_CallNonvirtualFloatMethod,
+       _Jv_JNI_CallNonvirtualFloatMethodV,
+       _Jv_JNI_CallNonvirtualFloatMethodA,
+       _Jv_JNI_CallNonvirtualDoubleMethod,
+       _Jv_JNI_CallNonvirtualDoubleMethodV,
+       _Jv_JNI_CallNonvirtualDoubleMethodA,
+       _Jv_JNI_CallNonvirtualVoidMethod,
+       _Jv_JNI_CallNonvirtualVoidMethodV,
+       _Jv_JNI_CallNonvirtualVoidMethodA,
+
+       _Jv_JNI_GetFieldID,
+
+       _Jv_JNI_GetObjectField,
+       _Jv_JNI_GetBooleanField,
+       _Jv_JNI_GetByteField,
+       _Jv_JNI_GetCharField,
+       _Jv_JNI_GetShortField,
+       _Jv_JNI_GetIntField,
+       _Jv_JNI_GetLongField,
+       _Jv_JNI_GetFloatField,
+       _Jv_JNI_GetDoubleField,
+       _Jv_JNI_SetObjectField,
+       _Jv_JNI_SetBooleanField,
+       _Jv_JNI_SetByteField,
+       _Jv_JNI_SetCharField,
+       _Jv_JNI_SetShortField,
+       _Jv_JNI_SetIntField,
+       _Jv_JNI_SetLongField,
+       _Jv_JNI_SetFloatField,
+       _Jv_JNI_SetDoubleField,
+
+       _Jv_JNI_GetStaticMethodID,
+
+       _Jv_JNI_CallStaticObjectMethod,
+       _Jv_JNI_CallStaticObjectMethodV,
+       _Jv_JNI_CallStaticObjectMethodA,
+       _Jv_JNI_CallStaticBooleanMethod,
+       _Jv_JNI_CallStaticBooleanMethodV,
+       _Jv_JNI_CallStaticBooleanMethodA,
+       _Jv_JNI_CallStaticByteMethod,
+       _Jv_JNI_CallStaticByteMethodV,
+       _Jv_JNI_CallStaticByteMethodA,
+       _Jv_JNI_CallStaticCharMethod,
+       _Jv_JNI_CallStaticCharMethodV,
+       _Jv_JNI_CallStaticCharMethodA,
+       _Jv_JNI_CallStaticShortMethod,
+       _Jv_JNI_CallStaticShortMethodV,
+       _Jv_JNI_CallStaticShortMethodA,
+       _Jv_JNI_CallStaticIntMethod,
+       _Jv_JNI_CallStaticIntMethodV,
+       _Jv_JNI_CallStaticIntMethodA,
+       _Jv_JNI_CallStaticLongMethod,
+       _Jv_JNI_CallStaticLongMethodV,
+       _Jv_JNI_CallStaticLongMethodA,
+       _Jv_JNI_CallStaticFloatMethod,
+       _Jv_JNI_CallStaticFloatMethodV,
+       _Jv_JNI_CallStaticFloatMethodA,
+       _Jv_JNI_CallStaticDoubleMethod,
+       _Jv_JNI_CallStaticDoubleMethodV,
+       _Jv_JNI_CallStaticDoubleMethodA,
+       _Jv_JNI_CallStaticVoidMethod,
+       _Jv_JNI_CallStaticVoidMethodV,
+       _Jv_JNI_CallStaticVoidMethodA,
+
+       _Jv_JNI_GetStaticFieldID,
+
+       _Jv_JNI_GetStaticObjectField,
+       _Jv_JNI_GetStaticBooleanField,
+       _Jv_JNI_GetStaticByteField,
+       _Jv_JNI_GetStaticCharField,
+       _Jv_JNI_GetStaticShortField,
+       _Jv_JNI_GetStaticIntField,
+       _Jv_JNI_GetStaticLongField,
+       _Jv_JNI_GetStaticFloatField,
+       _Jv_JNI_GetStaticDoubleField,
+       _Jv_JNI_SetStaticObjectField,
+       _Jv_JNI_SetStaticBooleanField,
+       _Jv_JNI_SetStaticByteField,
+       _Jv_JNI_SetStaticCharField,
+       _Jv_JNI_SetStaticShortField,
+       _Jv_JNI_SetStaticIntField,
+       _Jv_JNI_SetStaticLongField,
+       _Jv_JNI_SetStaticFloatField,
+       _Jv_JNI_SetStaticDoubleField,
+
+       _Jv_JNI_NewString,
+       _Jv_JNI_GetStringLength,
+       _Jv_JNI_GetStringChars,
+       _Jv_JNI_ReleaseStringChars,
+
+       _Jv_JNI_NewStringUTF,
+       _Jv_JNI_GetStringUTFLength,
+       _Jv_JNI_GetStringUTFChars,
+       _Jv_JNI_ReleaseStringUTFChars,
+
+       _Jv_JNI_GetArrayLength,
+
+       _Jv_JNI_NewObjectArray,
+       _Jv_JNI_GetObjectArrayElement,
+       _Jv_JNI_SetObjectArrayElement,
+
+       _Jv_JNI_NewBooleanArray,
+       _Jv_JNI_NewByteArray,
+       _Jv_JNI_NewCharArray,
+       _Jv_JNI_NewShortArray,
+       _Jv_JNI_NewIntArray,
+       _Jv_JNI_NewLongArray,
+       _Jv_JNI_NewFloatArray,
+       _Jv_JNI_NewDoubleArray,
+
+       _Jv_JNI_GetBooleanArrayElements,
+       _Jv_JNI_GetByteArrayElements,
+       _Jv_JNI_GetCharArrayElements,
+       _Jv_JNI_GetShortArrayElements,
+       _Jv_JNI_GetIntArrayElements,
+       _Jv_JNI_GetLongArrayElements,
+       _Jv_JNI_GetFloatArrayElements,
+       _Jv_JNI_GetDoubleArrayElements,
+
+       _Jv_JNI_ReleaseBooleanArrayElements,
+       _Jv_JNI_ReleaseByteArrayElements,
+       _Jv_JNI_ReleaseCharArrayElements,
+       _Jv_JNI_ReleaseShortArrayElements,
+       _Jv_JNI_ReleaseIntArrayElements,
+       _Jv_JNI_ReleaseLongArrayElements,
+       _Jv_JNI_ReleaseFloatArrayElements,
+       _Jv_JNI_ReleaseDoubleArrayElements,
+
+       _Jv_JNI_GetBooleanArrayRegion,
+       _Jv_JNI_GetByteArrayRegion,
+       _Jv_JNI_GetCharArrayRegion,
+       _Jv_JNI_GetShortArrayRegion,
+       _Jv_JNI_GetIntArrayRegion,
+       _Jv_JNI_GetLongArrayRegion,
+       _Jv_JNI_GetFloatArrayRegion,
+       _Jv_JNI_GetDoubleArrayRegion,
+       _Jv_JNI_SetBooleanArrayRegion,
+       _Jv_JNI_SetByteArrayRegion,
+       _Jv_JNI_SetCharArrayRegion,
+       _Jv_JNI_SetShortArrayRegion,
+       _Jv_JNI_SetIntArrayRegion,
+       _Jv_JNI_SetLongArrayRegion,
+       _Jv_JNI_SetFloatArrayRegion,
+       _Jv_JNI_SetDoubleArrayRegion,
+
+       _Jv_JNI_RegisterNatives,
+       _Jv_JNI_UnregisterNatives,
+
+       _Jv_JNI_MonitorEnter,
+       _Jv_JNI_MonitorExit,
+
+       _Jv_JNI_GetJavaVM,
 
        /* new JNI 1.2 functions */
 
-       GetStringRegion,
-       GetStringUTFRegion,
+       _Jv_JNI_GetStringRegion,
+       _Jv_JNI_GetStringUTFRegion,
 
-       GetPrimitiveArrayCritical,
-       ReleasePrimitiveArrayCritical,
+       _Jv_JNI_GetPrimitiveArrayCritical,
+       _Jv_JNI_ReleasePrimitiveArrayCritical,
 
-       GetStringCritical,
-       ReleaseStringCritical,
+       _Jv_JNI_GetStringCritical,
+       _Jv_JNI_ReleaseStringCritical,
 
-       NewWeakGlobalRef,
-       DeleteWeakGlobalRef,
+       _Jv_JNI_NewWeakGlobalRef,
+       _Jv_JNI_DeleteWeakGlobalRef,
 
-       ExceptionCheck,
+       _Jv_JNI_ExceptionCheck,
 
        /* new JNI 1.4 functions */
 
-       NewDirectByteBuffer,
-       GetDirectBufferAddress,
-       GetDirectBufferCapacity
+       _Jv_JNI_NewDirectByteBuffer,
+       _Jv_JNI_GetDirectBufferAddress,
+       _Jv_JNI_GetDirectBufferCapacity
 };
 
 
@@ -5710,9 +4200,17 @@ jint JNI_GetDefaultJavaVMInitArgs(void *vm_args)
 
 jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
 {
-       log_text("JNI_GetCreatedJavaVMs: IMPLEMENT ME!!!");
+       TRACEJNICALLS("JNI_GetCreatedJavaVMs(vmBuf=%p, jsize=%d, jsize=%p)", vmBuf, bufLen, nVMs);
 
-       return 0;
+       if (bufLen <= 0)
+               return JNI_ERR;
+
+       /* We currently only support 1 VM running. */
+
+       vmBuf[0] = (JavaVM *) _Jv_jvm;
+       *nVMs    = 1;
+
+    return JNI_OK;
 }
 
 
@@ -5725,48 +4223,14 @@ jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
 
 jint JNI_CreateJavaVM(JavaVM **p_vm, void **p_env, void *vm_args)
 {
-       JavaVMInitArgs *_vm_args;
-       _Jv_JNIEnv     *env;
-       localref_table *lrt;
-
-       /* get the arguments for the new JVM */
-
-       _vm_args = (JavaVMInitArgs *) vm_args;
-
-       /* get the VM and Env tables (must be set before vm_create) */
-
-       env = NEW(_Jv_JNIEnv);
-
-       env->env = &JNI_JNIEnvTable;
-
-       *p_vm  = (JavaVM *) &JNI_JavaVMTable;
-       *p_env = (void *) env;
-
-       /* XXX Set the global env variable.  Maybe we should do that differently. */
-
-       _Jv_env = env;
+       TRACEJNICALLS("JNI_CreateJavaVM(p_vm=%p, p_env=%p, vm_args=%p)", p_vm, p_env, vm_args);
 
        /* actually create the JVM */
 
-       if (!vm_create(_vm_args))
-               return -1;
-
-       /* setup the local ref table (must be created after vm_create) */
-
-       lrt = GCNEW(localref_table);
-
-       lrt->capacity    = LOCALREFTABLE_CAPACITY;
-       lrt->used        = 0;
-       lrt->localframes = 1;
-       lrt->prev        = LOCALREFTABLE;
-
-       /* clear the references array (memset is faster then a for-loop) */
-
-       MSET(lrt->refs, 0, java_objectheader*, LOCALREFTABLE_CAPACITY);
-
-       LOCALREFTABLE = lrt;
+       if (!vm_createjvm(p_vm, p_env, vm_args))
+               return JNI_ERR;
 
-       return 0;
+       return JNI_OK;
 }