* Removed all Id tags.
[cacao.git] / src / native / jni.c
index 7d7864e50e42a43b8cb1bd0fd4a8c4f6f2d57d0b..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
-            Joseph Wenninger
-            Martin Platter
-            Christian Thalinger
-            Edwin Steiner
-
-   $Id: jni.c 6252 2006-12-27 23:42:37Z twisti $
-
 */
 
 
 #include "config.h"
 
 #include <assert.h>
+#include <stdint.h>
 #include <string.h>
 
 #include "vm/types.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_ClassLoader.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/cacaodbg.h"
 #endif
 
-#if defined(ENABLE_THREADS)
-# include "threads/native/lock.h"
-# include "threads/native/threads.h"
-#else
-# include "threads/none/lock.h"
+#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"
+
+
+/* debug **********************************************************************/
+
+#if !defined(NDEBUG)
+# define TRACEJNICALLS(format, ...) \
+    do { \
+        if (opt_TraceJNICalls) { \
+            log_println((format), __VA_ARGS__); \
+        } \
+    } while (0)
+#else
+# define TRACEJNICALLS(format, ...)
+#endif
 
 
 /* global variables ***********************************************************/
@@ -117,32 +144,30 @@ 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(ENABLE_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 **************************************************/
@@ -166,6 +191,7 @@ bool jni_init(void)
        hashtable_create(hashtable_global_ref, HASHTABLE_GLOBAL_REF_SIZE);
 
 
+#if defined(ENABLE_JAVASE)
        /* direct buffer stuff */
 
        if (!(class_java_nio_Buffer =
@@ -173,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))
@@ -189,227 +216,21 @@ 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
-
-       return true;
-}
-
-
-/* jni_init_localref_table *****************************************************
-
-   Initializes the local references table of the current thread.
-
-*******************************************************************************/
-
-bool jni_init_localref_table(void)
-{
-       localref_table *lrt;
-
-       lrt = GCNEW(localref_table);
-
-       if (lrt == NULL)
-               return false;
-
-       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;
-
-       return true;
-}
-
-
-/* _Jv_jni_vmargs_from_objectarray *********************************************
-
-   XXX
-
-*******************************************************************************/
-
-static bool _Jv_jni_vmargs_from_objectarray(java_objectheader *o,
-                                                                                       methoddesc *descr,
-                                                                                       vm_arg *vmargs,
-                                                                                       java_objectarray *params)
-{
-       java_objectheader *param;
-       s4                 paramcount;
-       typedesc          *paramtypes;
-       classinfo         *c;
-       s4                 i;
-       s4                 j;
-       s8                 value;
-
-       paramcount = descr->paramcount;
-       paramtypes = descr->paramtypes;
-
-       /* if method is non-static fill first block and skip `this' pointer */
-
-       i = 0;
-
-       if (o != NULL) {
-               /* this pointer */
-               vmargs[0].type   = TYPE_ADR;
-               vmargs[0].data.l = (u8) (ptrint) o;
-
-               paramtypes++;
-               paramcount--;
-               i++;
-       }
-
-       for (j = 0; j < paramcount; i++, j++, paramtypes++) {
-               switch (paramtypes->type) {
-               /* primitive types */
-               case TYPE_INT:
-               case TYPE_LNG:
-               case TYPE_FLT:
-               case TYPE_DBL:
-                       param = params->data[j];
-
-                       if (param == NULL)
-                               goto illegal_arg;
-
-                       /* internally used data type */
-                       vmargs[i].type = paramtypes->type;
-
-                       /* convert the value according to its declared type */
-
-                       c = param->vftbl->class;
-
-                       switch (paramtypes->decltype) {
-                       case PRIMITIVETYPE_BOOLEAN:
-                               if (c == primitivetype_table[paramtypes->decltype].class_wrap)
-                                       value = (s8) ((java_lang_Boolean *) param)->value;
-                               else
-                                       goto illegal_arg;
-
-                               vmargs[i].data.l = value;
-                               break;
-
-                       case PRIMITIVETYPE_BYTE:
-                               if (c == primitivetype_table[paramtypes->decltype].class_wrap)
-                                       value = (s8) ((java_lang_Byte *) param)->value;
-                               else
-                                       goto illegal_arg;
-
-                               vmargs[i].data.l = value;
-                               break;
-
-                       case PRIMITIVETYPE_CHAR:
-                               if (c == primitivetype_table[paramtypes->decltype].class_wrap)
-                                       value = (s8) ((java_lang_Character *) param)->value;
-                               else
-                                       goto illegal_arg;
-
-                               vmargs[i].data.l = value;
-                               break;
-
-                       case PRIMITIVETYPE_SHORT:
-                               if (c == primitivetype_table[paramtypes->decltype].class_wrap)
-                                       value = (s8) ((java_lang_Short *) param)->value;
-                               else if (c == primitivetype_table[PRIMITIVETYPE_BYTE].class_wrap)
-                                       value = (s8) ((java_lang_Byte *) param)->value;
-                               else
-                                       goto illegal_arg;
-
-                               vmargs[i].data.l = value;
-                               break;
-
-                       case PRIMITIVETYPE_INT:
-                               if (c == primitivetype_table[paramtypes->decltype].class_wrap)
-                                       value = (s8) ((java_lang_Integer *) param)->value;
-                               else if (c == primitivetype_table[PRIMITIVETYPE_SHORT].class_wrap)
-                                       value = (s8) ((java_lang_Short *) param)->value;
-                               else if (c == primitivetype_table[PRIMITIVETYPE_BYTE].class_wrap)
-                                       value = (s8) ((java_lang_Byte *) param)->value;
-                               else
-                                       goto illegal_arg;
-
-                               vmargs[i].data.l = value;
-                               break;
-
-                       case PRIMITIVETYPE_LONG:
-                               if (c == primitivetype_table[paramtypes->decltype].class_wrap)
-                                       value = (s8) ((java_lang_Long *) param)->value;
-                               else if (c == primitivetype_table[PRIMITIVETYPE_INT].class_wrap)
-                                       value = (s8) ((java_lang_Integer *) param)->value;
-                               else if (c == primitivetype_table[PRIMITIVETYPE_SHORT].class_wrap)
-                                       value = (s8) ((java_lang_Short *) param)->value;
-                               else if (c == primitivetype_table[PRIMITIVETYPE_BYTE].class_wrap)
-                                       value = (s8) ((java_lang_Byte *) param)->value;
-                               else
-                                       goto illegal_arg;
-
-                               vmargs[i].data.l = value;
-                               break;
-
-                       case PRIMITIVETYPE_FLOAT:
-                               if (c == primitivetype_table[paramtypes->decltype].class_wrap)
-                                       vmargs[i].data.f = (jfloat) ((java_lang_Float *) param)->value;
-                               else
-                                       goto illegal_arg;
-                               break;
-
-                       case PRIMITIVETYPE_DOUBLE:
-                               if (c == primitivetype_table[paramtypes->decltype].class_wrap)
-                                       vmargs[i].data.d = (jdouble) ((java_lang_Double *) param)->value;
-                               else if (c == primitivetype_table[PRIMITIVETYPE_FLOAT].class_wrap)
-                                       vmargs[i].data.f = (jfloat) ((java_lang_Float *) param)->value;
-                               else
-                                       goto illegal_arg;
-                               break;
-
-                       default:
-                               goto illegal_arg;
-                       }
-                       break;
-               
-                       case TYPE_ADR:
-                               if (!resolve_class_from_typedesc(paramtypes, true, true, &c))
-                                       return false;
-
-                               if (params->data[j] != 0) {
-                                       if (paramtypes->arraydim > 0) {
-                                               if (!builtin_arrayinstanceof(params->data[j], c))
-                                                       goto illegal_arg;
-
-                                       } else {
-                                               if (!builtin_instanceof(params->data[j], c))
-                                                       goto illegal_arg;
-                                       }
-                               }
-
-                               vmargs[i].type   = TYPE_ADR;
-                               vmargs[i].data.l = (u8) (ptrint) params->data[j];
-                               break;
-
-                       default:
-                               goto illegal_arg;
-               }
-       }
-
-/*     if (rettype) */
-/*             *rettype = descr->returntype.decltype; */
+#  endif
+# endif
+#endif /* defined(ENABLE_JAVASE) */
 
        return true;
-
-illegal_arg:
-       exceptions_throw_illegalargumentexception();
-       return false;
 }
 
 
@@ -419,12 +240,12 @@ illegal_arg:
 
 *******************************************************************************/
 
-static java_objectheader *_Jv_jni_CallObjectMethod(java_objectheader *o,
-                                                                                                  vftbl_t *vftbl,
-                                                                                                  methodinfo *m, va_list ap)
+static java_handle_t *_Jv_jni_CallObjectMethod(java_handle_t *o,
+                                                                                          vftbl_t *vftbl,
+                                                                                          methodinfo *m, va_list ap)
 {
-       methodinfo        *resm;
-       java_objectheader *ro;
+       methodinfo    *resm;
+       java_handle_t *ro;
 
        STATISTICS(jniinvokation());
 
@@ -466,12 +287,13 @@ static java_objectheader *_Jv_jni_CallObjectMethod(java_objectheader *o,
 
 *******************************************************************************/
 
-static java_objectheader *_Jv_jni_CallObjectMethodA(java_objectheader *o,
-                                                                                                       vftbl_t *vftbl,
-                                                                                                       methodinfo *m, jvalue *args)
+static java_handle_t *_Jv_jni_CallObjectMethodA(java_handle_t *o,
+                                                                                               vftbl_t *vftbl,
+                                                                                               methodinfo *m,
+                                                                                               const jvalue *args)
 {
-       methodinfo        *resm;
-       java_objectheader *ro;
+       methodinfo    *resm;
+       java_handle_t *ro;
 
        STATISTICS(jniinvokation());
 
@@ -514,7 +336,7 @@ static java_objectheader *_Jv_jni_CallObjectMethodA(java_objectheader *o,
 
 *******************************************************************************/
 
-static jint _Jv_jni_CallIntMethod(java_objectheader *o, vftbl_t *vftbl,
+static jint _Jv_jni_CallIntMethod(java_handle_t *o, vftbl_t *vftbl,
                                                                  methodinfo *m, va_list ap)
 {
        methodinfo *resm;
@@ -561,8 +383,8 @@ static jint _Jv_jni_CallIntMethod(java_objectheader *o, vftbl_t *vftbl,
 
 *******************************************************************************/
 
-static jint _Jv_jni_CallIntMethodA(java_objectheader *o, vftbl_t *vftbl,
-                                                                  methodinfo *m, jvalue *args)
+static jint _Jv_jni_CallIntMethodA(java_handle_t *o, vftbl_t *vftbl,
+                                                                  methodinfo *m, const jvalue *args)
 {
        methodinfo *resm;
        jint        i;
@@ -607,7 +429,7 @@ static jint _Jv_jni_CallIntMethodA(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;
@@ -647,13 +469,59 @@ static jlong _Jv_jni_CallLongMethod(java_objectheader *o, vftbl_t *vftbl,
 }
 
 
+/* _Jv_jni_CallLongMethodA *****************************************************
+
+   Internal function to call Java long methods.
+
+*******************************************************************************/
+
+static jlong _Jv_jni_CallLongMethodA(java_handle_t *o, vftbl_t *vftbl,
+                                                                        methodinfo *m, const jvalue *args)
+{
+       methodinfo *resm;
+       jlong       l;
+
+       STATISTICS(jniinvokation());
+
+       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. */
+
+               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;
+}
+
+
 /* _Jv_jni_CallFloatMethod *****************************************************
 
    Internal function to call Java float methods.
 
 *******************************************************************************/
 
-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;
@@ -686,13 +554,52 @@ static jfloat _Jv_jni_CallFloatMethod(java_objectheader *o, vftbl_t *vftbl,
 }
 
 
+/* _Jv_jni_CallFloatMethodA ****************************************************
+
+   Internal function to call Java float methods.
+
+*******************************************************************************/
+
+static jfloat _Jv_jni_CallFloatMethodA(java_handle_t *o, vftbl_t *vftbl,
+                                                                          methodinfo *m, const jvalue *args)
+{
+       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. */
+
+       if (m->flags & ACC_STATIC) {
+               /* For static methods we reset the object. */
+
+               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());
+
+       f = vm_call_method_float_jvalue(resm, o, args);
+
+       return f;
+}
+
+
 /* _Jv_jni_CallDoubleMethod ****************************************************
 
    Internal function to call Java double methods.
 
 *******************************************************************************/
 
-static jdouble _Jv_jni_CallDoubleMethod(java_objectheader *o, vftbl_t *vftbl,
+static jdouble _Jv_jni_CallDoubleMethod(java_handle_t *o, vftbl_t *vftbl,
                                                                                methodinfo *m, va_list ap)
 {
        methodinfo *resm;
@@ -723,13 +630,50 @@ static jdouble _Jv_jni_CallDoubleMethod(java_objectheader *o, vftbl_t *vftbl,
 }
 
 
+/* _Jv_jni_CallDoubleMethodA ***************************************************
+
+   Internal function to call Java double methods.
+
+*******************************************************************************/
+
+static jdouble _Jv_jni_CallDoubleMethodA(java_handle_t *o, vftbl_t *vftbl,
+                                                                                methodinfo *m, const jvalue *args)
+{
+       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. */
+
+       if (m->flags & ACC_STATIC) {
+               /* For static methods we reset the object. */
+
+               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);
+       }
+
+       d = vm_call_method_double_jvalue(resm, o, args);
+
+       return d;
+}
+
+
 /* _Jv_jni_CallVoidMethod ******************************************************
 
    Internal function to call Java void methods.
 
 *******************************************************************************/
 
-static void _Jv_jni_CallVoidMethod(java_objectheader *o, vftbl_t *vftbl,
+static void _Jv_jni_CallVoidMethod(java_handle_t *o, vftbl_t *vftbl,
                                                                   methodinfo *m, va_list ap)
 {      
        methodinfo *resm;
@@ -770,8 +714,8 @@ static void _Jv_jni_CallVoidMethod(java_objectheader *o, vftbl_t *vftbl,
 
 *******************************************************************************/
 
-static void _Jv_jni_CallVoidMethodA(java_objectheader *o, vftbl_t *vftbl,
-                                                                       methodinfo *m, jvalue *args)
+static void _Jv_jni_CallVoidMethodA(java_handle_t *o, vftbl_t *vftbl,
+                                                                       methodinfo *m, const jvalue *args)
 {      
        methodinfo *resm;
 
@@ -816,16 +760,19 @@ static void _Jv_jni_CallVoidMethodA(java_objectheader *o, vftbl_t *vftbl,
 
 *******************************************************************************/
 
-java_objectheader *_Jv_jni_invokeNative(methodinfo *m, java_objectheader *o,
-                                                                               java_objectarray *params)
+java_handle_t *_Jv_jni_invokeNative(methodinfo *m, java_handle_t *o,
+                                                                       java_handle_objectarray_t *params)
 {
-       methodinfo        *resm;
-       vm_arg            *vmargs;
-       java_objectheader *ro;
-       s4                 argcount;
-       s4                 paramcount;
+       methodinfo    *resm;
+       java_handle_t *ro;
+       s4             argcount;
+       s4             paramcount;
+       java_handle_t *xptr;
+       int32_t        dumpsize;
+       uint64_t      *array;
+       imm_union          value;
 
-       if (!m) {
+       if (m == NULL) {
                exceptions_throw_nullpointerexception();
                return NULL;
        }
@@ -843,28 +790,24 @@ java_objectheader *_Jv_jni_invokeNative(methodinfo *m, java_objectheader *o,
           parameter is ignored. */
 
        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");
+               exceptions_throw_illegalargumentexception();
                return NULL;
        }
 
        /* check if we got the right number of arguments */
 
        if (((params == NULL) && (paramcount != 0)) ||
-               (params && (params->header.size != paramcount))) 
+               (params && (LLNI_array_size(params) != paramcount))) 
        {
-               *exceptionptr =
-                       new_exception(string_java_lang_IllegalArgumentException);
+               exceptions_throw_illegalargumentexception();
                return NULL;
        }
 
        /* for instance methods we need an object */
 
        if (!(m->flags & ACC_STATIC) && (o == NULL)) {
-               *exceptionptr =
-                       new_exception_message(string_java_lang_NullPointerException,
-                                                                 "Static mismatch in Java_java_lang_reflect_Method_invokeNative");
+               /* XXX not sure if that is the correct exception */
+               exceptions_throw_nullpointerexception();
                return NULL;
        }
 
@@ -875,222 +818,139 @@ java_objectheader *_Jv_jni_invokeNative(methodinfo *m, java_objectheader *o,
        if (o != NULL) {
                /* for instance methods we must do a vftbl lookup */
                resm = method_vftbl_lookup(o->vftbl, m);
-
-       else {
+       }
+       else {
                /* for static methods, just for convenience */
                resm = m;
        }
 
-       vmargs = MNEW(vm_arg, argcount);
+       /* mark start of dump memory area */
+
+       dumpsize = dump_size();
+
+       /* Fill the argument array from a object-array. */
+
+       array = vm_array_from_objectarray(resm, o, params);
+
+       /* 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. */
+
+       if ((array == NULL) && (exceptions_get_exception() != NULL)) {
+               /* release dump area */
+
+               dump_release(dumpsize);
 
-       if (!_Jv_jni_vmargs_from_objectarray(o, resm->parseddesc, vmargs, params))
                return NULL;
+       }
 
        switch (resm->parseddesc->returntype.decltype) {
        case TYPE_VOID:
-               (void) vm_call_method_vmarg(resm, argcount, vmargs);
-
+               (void) vm_call_array(resm, array);
                ro = NULL;
                break;
 
-       case PRIMITIVETYPE_BOOLEAN: {
-               s4 i;
-               java_lang_Boolean *bo;
+       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;
 
-               i = vm_call_method_int_vmarg(resm, argcount, vmargs);
+       case PRIMITIVETYPE_LONG:
+               value.l = vm_call_long_array(resm, array);
+               ro = primitive_box(resm->parseddesc->returntype.decltype, value);
+               break;
 
-               ro = builtin_new(class_java_lang_Boolean);
+       case PRIMITIVETYPE_FLOAT:
+               value.f = vm_call_float_array(resm, array);
+               ro = primitive_box(resm->parseddesc->returntype.decltype, value);
+               break;
 
-               /* setting the value of the object direct */
+       case PRIMITIVETYPE_DOUBLE:
+               value.d = vm_call_double_array(resm, array);
+               ro = primitive_box(resm->parseddesc->returntype.decltype, value);
+               break;
 
-               bo = (java_lang_Boolean *) ro;
-               bo->value = i;
-       }
-       break;
+       case TYPE_ADR:
+               ro = vm_call_array(resm, array);
+               break;
 
-       case PRIMITIVETYPE_BYTE: {
-               s4 i;
-               java_lang_Byte *bo;
+       default:
+               vm_abort("_Jv_jni_invokeNative: invalid return type %d", resm->parseddesc->returntype.decltype);
+       }
 
-               i = vm_call_method_int_vmarg(resm, argcount, vmargs);
+       xptr = exceptions_get_exception();
 
-               ro = builtin_new(class_java_lang_Byte);
+       if (xptr != NULL) {
+               /* clear exception pointer, we are calling JIT code again */
 
-               /* setting the value of the object direct */
+               exceptions_clear_exception();
 
-               bo = (java_lang_Byte *) ro;
-               bo->value = i;
+               exceptions_throw_invocationtargetexception(xptr);
        }
-       break;
-
-       case PRIMITIVETYPE_CHAR: {
-               s4 i;
-               java_lang_Character *co;
 
-               i = vm_call_method_int_vmarg(resm, argcount, vmargs);
+       /* release dump area */
 
-               ro = builtin_new(class_java_lang_Character);
+       dump_release(dumpsize);
 
-               /* setting the value of the object direct */
+       return ro;
+}
 
-               co = (java_lang_Character *) ro;
-               co->value = i;
-       }
-       break;
 
-       case PRIMITIVETYPE_SHORT: {
-               s4 i;
-               java_lang_Short *so;
+/* GetVersion ******************************************************************
 
-               i = vm_call_method_int_vmarg(resm, argcount, vmargs);
+   Returns the major version number in the higher 16 bits and the
+   minor version number in the lower 16 bits.
 
-               ro = builtin_new(class_java_lang_Short);
+*******************************************************************************/
 
-               /* setting the value of the object direct */
+jint _Jv_JNI_GetVersion(JNIEnv *env)
+{
+       STATISTICS(jniinvokation());
 
-               so = (java_lang_Short *) ro;
-               so->value = i;
-       }
-       break;
+       /* we support JNI 1.4 */
 
-       case PRIMITIVETYPE_INT: {
-               s4 i;
-               java_lang_Integer *io;
+       return JNI_VERSION_1_4;
+}
 
-               i = vm_call_method_int_vmarg(resm, argcount, vmargs);
 
-               ro = builtin_new(class_java_lang_Integer);
+/* Class Operations ***********************************************************/
 
-               /* setting the value of the object direct */
+/* DefineClass *****************************************************************
 
-               io = (java_lang_Integer *) ro;
-               io->value = i;
-       }
-       break;
+   Loads a class from a buffer of raw class data. The buffer
+   containing the raw class data is not referenced by the VM after the
+   DefineClass call returns, and it may be discarded if desired.
 
-       case PRIMITIVETYPE_LONG: {
-               s8 l;
-               java_lang_Long *lo;
+*******************************************************************************/
 
-               l = vm_call_method_long_vmarg(resm, argcount, vmargs);
+jclass _Jv_JNI_DefineClass(JNIEnv *env, const char *name, jobject loader,
+                                                  const jbyte *buf, jsize bufLen)
+{
+#if defined(ENABLE_JAVASE)
+       utf         *u;
+       classloader *cl;
+       classinfo   *c;
 
-               ro = builtin_new(class_java_lang_Long);
+       TRACEJNICALLS("_Jv_JNI_DefineClass(env=%p, name=%s, loader=%p, buf=%p, bufLen=%d)", env, name, loader, buf, bufLen);
 
-               /* setting the value of the object direct */
+       u  = utf_new_char(name);
+       cl = (classloader *) loader;
 
-               lo = (java_lang_Long *) ro;
-               lo->value = l;
-       }
-       break;
+       c = class_define(u, cl, bufLen, (const uint8_t *) buf, NULL);
 
-       case PRIMITIVETYPE_FLOAT: {
-               float f;
-               java_lang_Float *fo;
+       return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) c);
+#else
+       vm_abort("_Jv_JNI_DefineClass: not implemented in this configuration");
 
-               f = vm_call_method_float_vmarg(resm, argcount, vmargs);
+       /* keep compiler happy */
 
-               ro = builtin_new(class_java_lang_Float);
-
-               /* setting the value of the object direct */
-
-               fo = (java_lang_Float *) ro;
-               fo->value = f;
-       }
-       break;
-
-       case PRIMITIVETYPE_DOUBLE: {
-               double d;
-               java_lang_Double *_do;
-
-               d = vm_call_method_double_vmarg(resm, argcount, vmargs);
-
-               ro = builtin_new(class_java_lang_Double);
-
-               /* setting the value of the object direct */
-
-               _do = (java_lang_Double *) ro;
-               _do->value = d;
-       }
-       break;
-
-       case TYPE_ADR:
-               ro = vm_call_method_vmarg(resm, argcount, vmargs);
-               break;
-
-       default:
-               /* if this happens the exception has already been set by
-                  fill_callblock_from_objectarray */
-
-               MFREE(vmargs, vm_arg, argcount);
-
-               return NULL;
-       }
-
-       MFREE(vmargs, vm_arg, argcount);
-
-       if (*exceptionptr) {
-               java_objectheader *cause;
-
-               cause = *exceptionptr;
-
-               /* clear exception pointer, we are calling JIT code again */
-
-               *exceptionptr = NULL;
-
-               *exceptionptr =
-                       new_exception_throwable(string_java_lang_reflect_InvocationTargetException,
-                                                                       (java_lang_Throwable *) cause);
-       }
-
-       return ro;
-}
-
-
-/* GetVersion ******************************************************************
-
-   Returns the major version number in the higher 16 bits and the
-   minor version number in the lower 16 bits.
-
-*******************************************************************************/
-
-jint _Jv_JNI_GetVersion(JNIEnv *env)
-{
-       STATISTICS(jniinvokation());
-
-       /* we support JNI 1.4 */
-
-       return JNI_VERSION_1_4;
-}
-
-
-/* Class Operations ***********************************************************/
-
-/* DefineClass *****************************************************************
-
-   Loads a class from a buffer of raw class data. The buffer
-   containing the raw class data is not referenced by the VM after the
-   DefineClass call returns, and it may be discarded if desired.
-
-*******************************************************************************/
-
-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;
-
-       STATISTICS(jniinvokation());
-
-       cl = (java_lang_ClassLoader *) loader;
-       s  = javastring_new_from_utf_string(name);
-       ba = (java_bytearray *) buf;
-
-       c = (jclass) Java_java_lang_VMClassLoader_defineClass(env, NULL, cl, s, ba,
-                                                                                                                 0, bufLen, NULL);
-
-       return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) c);
+       return 0;
+#endif
 }
 
 
@@ -1104,6 +964,7 @@ jclass _Jv_JNI_DefineClass(JNIEnv *env, const char *name, jobject loader,
 
 jclass _Jv_JNI_FindClass(JNIEnv *env, const char *name)
 {
+#if defined(ENABLE_JAVASE)
        utf       *u;
        classinfo *cc;
        classinfo *c;
@@ -1140,6 +1001,13 @@ jclass _Jv_JNI_FindClass(JNIEnv *env, const char *name)
                return NULL;
 
        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
 }
   
 
@@ -1154,15 +1022,18 @@ jclass _Jv_JNI_FindClass(JNIEnv *env, const char *name)
 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) _Jv_JNI_NewLocalRef(env, (jobject) c);
+       super = class_get_superclass(c);
+
+       return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) super);
 }
   
  
@@ -1174,12 +1045,15 @@ jclass _Jv_JNI_GetSuperclass(JNIEnv *env, jclass sub)
 
 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);
 }
 
 
@@ -1191,9 +1065,13 @@ jboolean _Jv_JNI_IsAssignableFrom(JNIEnv *env, jclass sub, jclass sup)
 
 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;
 }
@@ -1209,23 +1087,25 @@ jint _Jv_JNI_Throw(JNIEnv *env, jthrowable obj)
 
 jint _Jv_JNI_ThrowNew(JNIEnv* env, jclass clazz, const char *msg) 
 {
-       classinfo           *c;
-       java_lang_Throwable *o;
-       java_lang_String    *s;
+       classinfo     *c;
+       java_handle_t *o;
+       java_handle_t *s;
 
        STATISTICS(jniinvokation());
 
-       c = (classinfo *) clazz;
-       s = (java_lang_String *) javastring_new_from_utf_string(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(c, s);
+       o = native_new_and_init_string(c, s);
 
        if (o == NULL)
                return -1;
 
-       *exceptionptr = (java_objectheader *) o;
+       exceptions_set_exception(o);
 
        return 0;
 }
@@ -1241,13 +1121,13 @@ jint _Jv_JNI_ThrowNew(JNIEnv* env, jclass clazz, const char *msg)
 
 jthrowable _Jv_JNI_ExceptionOccurred(JNIEnv *env)
 {
-       java_objectheader *e;
+       java_handle_t *o;
 
        STATISTICS(jniinvokation());
 
-       e = *exceptionptr;
+       o = exceptions_get_exception();
 
-       return _Jv_JNI_NewLocalRef(env, (jthrowable) e);
+       return _Jv_JNI_NewLocalRef(env, (jthrowable) o);
 }
 
 
@@ -1261,33 +1141,33 @@ jthrowable _Jv_JNI_ExceptionOccurred(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 */
 
-               (void) vm_call_method(m, e);
+               (void) vm_call_method(m, o);
        }
 }
 
@@ -1303,7 +1183,7 @@ void _Jv_JNI_ExceptionClear(JNIEnv *env)
 {
        STATISTICS(jniinvokation());
 
-       *exceptionptr = NULL;
+       exceptions_clear_exception();
 }
 
 
@@ -1318,7 +1198,9 @@ 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);
 }
 
 
@@ -1331,44 +1213,16 @@ void _Jv_JNI_FatalError(JNIEnv *env, const char *msg)
 
 jint _Jv_JNI_PushLocalFrame(JNIEnv* env, jint capacity)
 {
-       s4              additionalrefs;
-       localref_table *lrt;
-       localref_table *nlrt;
-
        STATISTICS(jniinvokation());
 
        if (capacity <= 0)
                return -1;
 
-       /* Allocate new local reference table on Java heap.  Calculate the
-          additional memory we have to allocate. */
-
-       if (capacity > LOCALREFTABLE_CAPACITY)
-               additionalrefs = capacity - LOCALREFTABLE_CAPACITY;
-       else
-               additionalrefs = 0;
-
-       nlrt = GCMNEW(u1, sizeof(localref_table) + additionalrefs * SIZEOF_VOID_P);
+       /* add new local reference frame to current table */
 
-       if (nlrt == NULL)
+       if (!localref_frame_push(capacity))
                return -1;
 
-       /* get current local reference table from thread */
-
-       lrt = LOCALREFTABLE;
-
-       /* Set up the new local reference table and add it to the local
-          frames chain. */
-
-       nlrt->capacity    = capacity;
-       nlrt->used        = 0;
-       nlrt->localframes = lrt->localframes + 1;
-       nlrt->prev        = lrt;
-
-       /* store new local reference table in thread */
-
-       LOCALREFTABLE = nlrt;
-
        return 0;
 }
 
@@ -1383,46 +1237,11 @@ jint _Jv_JNI_PushLocalFrame(JNIEnv* env, jint capacity)
 
 jobject _Jv_JNI_PopLocalFrame(JNIEnv* env, jobject result)
 {
-       localref_table *lrt;
-       localref_table *plrt;
-       s4              localframes;
-
        STATISTICS(jniinvokation());
 
-       /* get current local reference table from thread */
-
-       lrt = LOCALREFTABLE;
-
-       localframes = lrt->localframes;
-
-       /* Don't delete the top local frame, as this one is allocated in
-          the native stub on the stack and is freed automagically on
-          return. */
-
-       if (localframes == 1)
-               return _Jv_JNI_NewLocalRef(env, result);
-
        /* release all current local frames */
 
-       for (; localframes >= 1; localframes--) {
-               /* get previous frame */
-
-               plrt = lrt->prev;
-
-               /* clear all reference entries */
-
-               MSET(&lrt->refs[0], 0, java_objectheader*, lrt->capacity);
-
-               lrt->prev = NULL;
-
-               /* set new local references table */
-
-               lrt = plrt;
-       }
-
-       /* store new local reference table in thread */
-
-       LOCALREFTABLE = lrt;
+       localref_frame_pop_all();
 
        /* add local reference and return the value */
 
@@ -1438,13 +1257,13 @@ jobject _Jv_JNI_PopLocalFrame(JNIEnv* env, jobject result)
 
 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) */
 
@@ -1528,7 +1347,7 @@ jobject _Jv_JNI_NewLocalRef(JNIEnv *env, jobject ref)
 
        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;
@@ -1556,8 +1375,6 @@ jint _Jv_JNI_EnsureLocalCapacity(JNIEnv* env, jint capacity)
 {
        localref_table *lrt;
 
-       log_text("JNI-Call: EnsureLocalCapacity");
-
        STATISTICS(jniinvokation());
 
        /* get local reference table (thread specific) */
@@ -1582,23 +1399,21 @@ jint _Jv_JNI_EnsureLocalCapacity(JNIEnv* env, jint capacity)
 
 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 _Jv_JNI_NewLocalRef(env, o);
+       return _Jv_JNI_NewLocalRef(env, (jobject) o);
 }
 
 
@@ -1613,17 +1428,19 @@ jobject _Jv_JNI_AllocObject(JNIEnv *env, jclass clazz)
 
 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 == NULL)
                return NULL;
@@ -1634,7 +1451,7 @@ jobject _Jv_JNI_NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
        _Jv_jni_CallVoidMethod(o, o->vftbl, m, ap);
        va_end(ap);
 
-       return _Jv_JNI_NewLocalRef(env, o);
+       return _Jv_JNI_NewLocalRef(env, (jobject) o);
 }
 
 
@@ -1651,16 +1468,18 @@ jobject _Jv_JNI_NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
 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 == NULL)
                return NULL;
@@ -1669,7 +1488,7 @@ jobject _Jv_JNI_NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID,
 
        _Jv_jni_CallVoidMethod(o, o->vftbl, m, args);
 
-       return _Jv_JNI_NewLocalRef(env, o);
+       return _Jv_JNI_NewLocalRef(env, (jobject) o);
 }
 
 
@@ -1684,18 +1503,20 @@ jobject _Jv_JNI_NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID,
 *******************************************************************************/
 
 jobject _Jv_JNI_NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID,
-                                                  jvalue *args)
+                                                  const jvalue *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 == NULL)
                return NULL;
@@ -1704,7 +1525,7 @@ jobject _Jv_JNI_NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID,
 
        _Jv_jni_CallVoidMethodA(o, o->vftbl, m, args);
 
-       return _Jv_JNI_NewLocalRef(env, o);
+       return _Jv_JNI_NewLocalRef(env, (jobject) o);
 }
 
 
@@ -1716,12 +1537,12 @@ jobject _Jv_JNI_NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID,
 
 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;
@@ -1740,12 +1561,15 @@ jclass _Jv_JNI_GetObjectClass(JNIEnv *env, jobject obj)
 
 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);
 }
 
 
@@ -1760,35 +1584,46 @@ jboolean _Jv_JNI_IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz)
   
 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;
+               rm   = (java_lang_reflect_Method *) method;
+               LLNI_field_get_cls(rm, clazz, c);
+               LLNI_field_get_val(rm, slot , slot);
        }
-       else if (builtin_instanceof(method, class_java_lang_reflect_Constructor)) {
+       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;
+               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
 }
 
 
@@ -1800,9 +1635,11 @@ jmethodID _Jv_JNI_FromReflectedMethod(JNIEnv *env, jobject method)
  
 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());
 
@@ -1811,11 +1648,18 @@ jfieldID _Jv_JNI_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
 }
 
 
@@ -1830,11 +1674,36 @@ jfieldID _Jv_JNI_FromReflectedField(JNIEnv* env, jobject field)
 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;
+
+       /* HotSpot does the same assert. */
+
+       assert(((m->flags & ACC_STATIC) != 0) == (isStatic != 0));
+
+       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
 }
 
 
@@ -1879,9 +1748,9 @@ jmethodID _Jv_JNI_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))
@@ -1893,7 +1762,7 @@ jmethodID _Jv_JNI_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);
@@ -1907,3116 +1776,1346 @@ jmethodID _Jv_JNI_GetMethodID(JNIEnv* env, jclass clazz, const char *name,
 
 /* JNI-functions for calling instance methods *********************************/
 
+#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_objectheader *o;
-       methodinfo        *m;
-       java_objectheader *ret;
-       va_list            ap;
+       java_handle_t *o;
+       methodinfo    *m;
+       java_handle_t *ret;
+       va_list        ap;
 
-       o = (java_objectheader *) obj;
+       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 _Jv_JNI_NewLocalRef(env, ret);
+       return _Jv_JNI_NewLocalRef(env, (jobject) ret);
 }
 
 
 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 _Jv_JNI_NewLocalRef(env, ret);
+       return _Jv_JNI_NewLocalRef(env, (jobject) ret);
 }
 
 
 jobject _Jv_JNI_CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
-                                                                 jvalue *args)
+                                                                 const jvalue *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_CallObjectMethodA(o, o->vftbl, m, args);
 
-       return _Jv_JNI_NewLocalRef(env, ret);
+       return _Jv_JNI_NewLocalRef(env, (jobject) ret);
 }
 
 
-jboolean _Jv_JNI_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);
+       _Jv_jni_CallVoidMethod(o, o->vftbl, m, ap);
        va_end(ap);
-
-       return b;
 }
 
 
-jboolean _Jv_JNI_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);
-
-       return b;
+       _Jv_jni_CallVoidMethod(o, o->vftbl, m, args);
 }
 
 
-jboolean _Jv_JNI_CallBooleanMethodA(JNIEnv *env, jobject obj,
-                                                                       jmethodID methodID, jvalue *args)
+void _Jv_JNI_CallVoidMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
+                                                        const jvalue *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_CallIntMethodA(o, o->vftbl, m, args);
-
-       return b;
+       _Jv_jni_CallVoidMethodA(o, o->vftbl, m, args);
 }
 
 
-jbyte _Jv_JNI_CallByteMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
+
+#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_objectheader *o;
-       methodinfo        *m;
-       va_list            ap;
-       jbyte              b;
+       java_handle_t *o;
+       classinfo     *c;
+       methodinfo    *m;
+       java_handle_t *r;
+       va_list        ap;
 
-       o = (java_objectheader *) obj;
+       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);
+       r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, ap);
        va_end(ap);
 
-       return b;
-
+       return _Jv_JNI_NewLocalRef(env, (jobject) r);
 }
 
 
-jbyte _Jv_JNI_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);
+       r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, args);
 
-       return b;
+       return _Jv_JNI_NewLocalRef(env, (jobject) r);
 }
 
 
-jbyte _Jv_JNI_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 _Jv_JNI_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);
+       _Jv_jni_CallVoidMethod(o, c->vftbl, m, ap);
        va_end(ap);
-
-       return c;
 }
 
 
-jchar _Jv_JNI_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);
-
-       return c;
+       _Jv_jni_CallVoidMethod(o, c->vftbl, m, args);
 }
 
 
-jchar _Jv_JNI_CallCharMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
-                                                         jvalue *args)
-{
-       log_text("JNI-Call: CallCharMethodA: IMPLEMENT ME!");
+void _Jv_JNI_CallNonvirtualVoidMethodA(JNIEnv *env, jobject obj, jclass clazz,
+                                                                          jmethodID methodID, const jvalue * args)
+{      
+       java_handle_t *o;
+       classinfo     *c;
+       methodinfo    *m;
 
-       return 0;
-}
+       o = (java_handle_t *) obj;
+       c = LLNI_classinfo_unwrap(clazz);
+       m = (methodinfo *) methodID;
 
+       _Jv_jni_CallVoidMethodA(o, c->vftbl, m, args);
+}
 
-jshort _Jv_JNI_CallShortMethod(JNIEnv *env, jobject obj, jmethodID methodID,
-                                                          ...)
-{
-       java_objectheader *o;
-       methodinfo        *m;
-       va_list            ap;
-       jshort             s;
 
-       o = (java_objectheader *) obj;
-       m = (methodinfo *) methodID;
+/* Accessing Fields of Objects ************************************************/
 
-       va_start(ap, methodID);
-       s = _Jv_jni_CallIntMethod(o, o->vftbl, m, ap);
-       va_end(ap);
+/* 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 _Jv_JNI_CallShortMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
-                                                               va_list args)
+jfieldID _Jv_JNI_GetFieldID(JNIEnv *env, jclass clazz, const char *name,
+                                                       const char *sig)
 {
-       java_objectheader *o;
-       methodinfo        *m;
-       jshort             s;
+       classinfo *c;
+       fieldinfo *f;
+       utf       *uname;
+       utf       *udesc;
 
-       o = (java_objectheader *) obj;
-       m = (methodinfo *) methodID;
+       STATISTICS(jniinvokation());
+
+       c = LLNI_classinfo_unwrap(clazz);
+
+       /* XXX NPE check? */
+
+       uname = utf_new_char((char *) name);
+       udesc = utf_new_char((char *) sig);
 
-       s = _Jv_jni_CallIntMethod(o, o->vftbl, m, args);
+       f = class_findfield(c, uname, udesc); 
+       
+       if (f == NULL)
+               exceptions_throw_nosuchfielderror(c, uname);  
 
-       return s;
+       return (jfieldID) f;
 }
 
 
-jshort _Jv_JNI_CallShortMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
-                                                               jvalue *args)
-{
-       log_text("JNI-Call: CallShortMethodA: IMPLEMENT ME!");
+/* Get<type>Field Routines *****************************************************
 
-       return 0;
+   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().
+
+*******************************************************************************/
+
+#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)
 
 
-jint _Jv_JNI_CallIntMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
+jobject _Jv_JNI_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID)
 {
-       java_objectheader *o;
-       methodinfo        *m;
-       va_list            ap;
-       jint               i;
+       java_handle_t *o;
 
-       o = (java_objectheader *) obj;
-       m = (methodinfo *) methodID;
+       STATISTICS(jniinvokation());
 
-       va_start(ap, methodID);
-       i = _Jv_jni_CallIntMethod(o, o->vftbl, m, ap);
-       va_end(ap);
+#warning this needs to be fixed
+       o = GET_FIELD(obj, java_handle_t*, fieldID);
 
-       return i;
+       return _Jv_JNI_NewLocalRef(env, (jobject) o);
 }
 
 
-jint _Jv_JNI_CallIntMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
-                                                       va_list args)
-{
-       java_objectheader *o;
-       methodinfo        *m;
-       jint               i;
+/* 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().
 
-       i = _Jv_jni_CallIntMethod(o, o->vftbl, m, args);
+*******************************************************************************/
 
-       return i;
+#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)
 
-jint _Jv_JNI_CallIntMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
-                                                       jvalue *args)
+
+void _Jv_JNI_SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID,
+                                                       jobject value)
 {
-       log_text("JNI-Call: CallIntMethodA: IMPLEMENT ME!");
+       STATISTICS(jniinvokation());
 
-       return 0;
+#warning this needs to be fixed
+       SET_FIELD(obj, java_handle_t*, fieldID, value);
 }
 
 
+/* Calling Static Methods *****************************************************/
 
-jlong _Jv_JNI_CallLongMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
-{
-       java_objectheader *o;
-       methodinfo        *m;
-       va_list            ap;
-       jlong              l;
-
-       o = (java_objectheader *) obj;
-       m = (methodinfo *) methodID;
-
-       va_start(ap, methodID);
-       l = _Jv_jni_CallLongMethod(o, o->vftbl, m, ap);
-       va_end(ap);
-
-       return l;
-}
-
-
-jlong _Jv_JNI_CallLongMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
-                                                         va_list args)
-{
-       java_objectheader *o;
-       methodinfo        *m;
-       jlong              l;
-
-       o = (java_objectheader *) obj;
-       m = (methodinfo *) methodID;
-
-       l = _Jv_jni_CallLongMethod(o, o->vftbl, m, args);
-
-       return l;
-}
-
-
-jlong _Jv_JNI_CallLongMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
-                                                         jvalue *args)
-{
-       log_text("JNI-Call: CallLongMethodA: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-
-jfloat _Jv_JNI_CallFloatMethod(JNIEnv *env, jobject obj, jmethodID methodID,
-                                                          ...)
-{
-       java_objectheader *o;
-       methodinfo        *m;
-       va_list            ap;
-       jfloat             f;
-
-       o = (java_objectheader *) obj;
-       m = (methodinfo *) methodID;
-
-       va_start(ap, methodID);
-       f = _Jv_jni_CallFloatMethod(o, o->vftbl, m, ap);
-       va_end(ap);
-
-       return f;
-}
-
-
-jfloat _Jv_JNI_CallFloatMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
-                                                               va_list args)
-{
-       java_objectheader *o;
-       methodinfo        *m;
-       jfloat             f;
-
-       o = (java_objectheader *) obj;
-       m = (methodinfo *) methodID;
-
-       f = _Jv_jni_CallFloatMethod(o, o->vftbl, m, args);
-
-       return f;
-}
-
-
-jfloat _Jv_JNI_CallFloatMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
-                                                               jvalue *args)
-{
-       log_text("JNI-Call: CallFloatMethodA: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-
-jdouble _Jv_JNI_CallDoubleMethod(JNIEnv *env, jobject obj, jmethodID methodID,
-                                                                ...)
-{
-       java_objectheader *o;
-       methodinfo        *m;
-       va_list            ap;
-       jdouble            d;
-
-       o = (java_objectheader *) obj;
-       m = (methodinfo *) methodID;
-
-       va_start(ap, methodID);
-       d = _Jv_jni_CallDoubleMethod(o, o->vftbl, m, ap);
-       va_end(ap);
-
-       return d;
-}
-
-
-jdouble _Jv_JNI_CallDoubleMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
-                                                                 va_list args)
-{
-       java_objectheader *o;
-       methodinfo        *m;
-       jdouble            d;
-
-       o = (java_objectheader *) obj;
-       m = (methodinfo *) methodID;
-
-       d = _Jv_jni_CallDoubleMethod(o, o->vftbl, m, args);
-
-       return d;
-}
-
-
-jdouble _Jv_JNI_CallDoubleMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
-                                                                 jvalue *args)
-{
-       log_text("JNI-Call: CallDoubleMethodA: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-
-void _Jv_JNI_CallVoidMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
-{
-       java_objectheader *o;
-       methodinfo        *m;
-       va_list            ap;
-
-       o = (java_objectheader *) obj;
-       m = (methodinfo *) methodID;
-
-       va_start(ap, methodID);
-       _Jv_jni_CallVoidMethod(o, o->vftbl, m, ap);
-       va_end(ap);
-}
-
-
-void _Jv_JNI_CallVoidMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
-                                                        va_list args)
-{
-       java_objectheader *o;
-       methodinfo        *m;
-
-       o = (java_objectheader *) obj;
-       m = (methodinfo *) methodID;
-
-       _Jv_jni_CallVoidMethod(o, o->vftbl, m, args);
-}
-
-
-void _Jv_JNI_CallVoidMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
-                                                        jvalue *args)
-{
-       java_objectheader *o;
-       methodinfo        *m;
-
-       o = (java_objectheader *) obj;
-       m = (methodinfo *) methodID;
-
-       _Jv_jni_CallVoidMethodA(o, o->vftbl, m, args);
-}
-
-
-
-jobject _Jv_JNI_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 _Jv_JNI_NewLocalRef(env, r);
-}
-
-
-jobject _Jv_JNI_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;
-
-       r = _Jv_jni_CallObjectMethod(o, c->vftbl, m, args);
-
-       return _Jv_JNI_NewLocalRef(env, r);
-}
-
-
-jobject _Jv_JNI_CallNonvirtualObjectMethodA(JNIEnv *env, jobject obj,
-                                                                                       jclass clazz, jmethodID methodID,
-                                                                                       jvalue *args)
-{
-       log_text("JNI-Call: CallNonvirtualObjectMethodA: IMPLEMENT ME!");
-
-       return _Jv_JNI_NewLocalRef(env, NULL);
-}
-
-
-
-jboolean _Jv_JNI_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;
-
-       va_start(ap, methodID);
-       b = _Jv_jni_CallIntMethod(o, c->vftbl, m, ap);
-       va_end(ap);
-
-       return b;
-}
-
-
-jboolean _Jv_JNI_CallNonvirtualBooleanMethodV(JNIEnv *env, jobject obj,
-                                                                                         jclass clazz, jmethodID methodID,
-                                                                                         va_list args)
-{
-       java_objectheader *o;
-       classinfo         *c;
-       methodinfo        *m;
-       jboolean           b;
-
-       o = (java_objectheader *) obj;
-       c = (classinfo *) clazz;
-       m = (methodinfo *) methodID;
-
-       b = _Jv_jni_CallIntMethod(o, c->vftbl, m, args);
-
-       return b;
-}
-
-
-jboolean _Jv_JNI_CallNonvirtualBooleanMethodA(JNIEnv *env, jobject obj,
-                                                                                         jclass clazz, jmethodID methodID,
-                                                                                         jvalue *args)
-{
-       log_text("JNI-Call: CallNonvirtualBooleanMethodA: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-jbyte _Jv_JNI_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);
-       va_end(ap);
-
-       return b;
-}
-
-
-jbyte _Jv_JNI_CallNonvirtualByteMethodV(JNIEnv *env, jobject obj, jclass clazz,
-                                                                               jmethodID methodID, va_list args)
-{
-       java_objectheader *o;
-       classinfo         *c;
-       methodinfo        *m;
-       jbyte              b;
-
-       o = (java_objectheader *) obj;
-       c = (classinfo *) clazz;
-       m = (methodinfo *) methodID;
-
-       b = _Jv_jni_CallIntMethod(o, c->vftbl, m, args);
-
-       return b;
-}
-
-
-jbyte _Jv_JNI_CallNonvirtualByteMethodA(JNIEnv *env, jobject obj, jclass clazz, 
-                                                                               jmethodID methodID, jvalue *args)
-{
-       log_text("JNI-Call: CallNonvirtualByteMethodA: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-
-jchar _Jv_JNI_CallNonvirtualCharMethod(JNIEnv *env, jobject obj, jclass clazz,
-                                                                          jmethodID methodID, ...)
-{
-       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);
-       va_end(ap);
-
-       return ch;
-}
-
-
-jchar _Jv_JNI_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);
-
-       return ch;
-}
-
-
-jchar _Jv_JNI_CallNonvirtualCharMethodA(JNIEnv *env, jobject obj, jclass clazz,
-                                                                               jmethodID methodID, jvalue *args)
-{
-       log_text("JNI-Call: CallNonvirtualCharMethodA: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-
-jshort _Jv_JNI_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);
-       va_end(ap);
-
-       return s;
-}
-
-
-jshort _Jv_JNI_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);
-
-       return s;
-}
-
-
-jshort _Jv_JNI_CallNonvirtualShortMethodA(JNIEnv *env, jobject obj,
-                                                                                 jclass clazz, jmethodID methodID,
-                                                                                 jvalue *args)
-{
-       log_text("JNI-Call: CallNonvirtualShortMethodA: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-
-jint _Jv_JNI_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);
-       va_end(ap);
-
-       return i;
-}
-
-
-jint _Jv_JNI_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);
-
-       return i;
-}
-
-
-jint _Jv_JNI_CallNonvirtualIntMethodA(JNIEnv *env, jobject obj, jclass clazz,
-                                                                         jmethodID methodID, jvalue *args)
-{
-       log_text("JNI-Call: CallNonvirtualIntMethodA: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-
-jlong _Jv_JNI_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 _Jv_JNI_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 _Jv_JNI_CallNonvirtualLongMethodA(JNIEnv *env, jobject obj, jclass clazz,
-                                                                               jmethodID methodID, jvalue *args)
-{
-       log_text("JNI-Call: CallNonvirtualLongMethodA: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-
-jfloat _Jv_JNI_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 _Jv_JNI_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 _Jv_JNI_CallNonvirtualFloatMethodA(JNIEnv *env, jobject obj,
-                                                                                 jclass clazz, jmethodID methodID,
-                                                                                 jvalue *args)
-{
-       log_text("JNI-Call: CallNonvirtualFloatMethodA: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-
-jdouble _Jv_JNI_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 _Jv_JNI_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 _Jv_JNI_CallNonvirtualDoubleMethodA(JNIEnv *env, jobject obj,
-                                                                                       jclass clazz, jmethodID methodID,
-                                                                                       jvalue *args)
-{
-       log_text("JNI-Call: CallNonvirtualDoubleMethodA: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-
-void _Jv_JNI_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 _Jv_JNI_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 _Jv_JNI_CallNonvirtualVoidMethodA(JNIEnv *env, jobject obj, jclass clazz,
-                                                                          jmethodID methodID, jvalue * args)
-{      
-       java_objectheader *o;
-       classinfo         *c;
-       methodinfo        *m;
-
-       o = (java_objectheader *) obj;
-       c = (classinfo *) clazz;
-       m = (methodinfo *) methodID;
-
-       _Jv_jni_CallVoidMethodA(o, c->vftbl, m, args);
-}
-
-
-/* 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 _Jv_JNI_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 _Jv_JNI_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID)
-{
-       java_objectheader *o;
-
-       STATISTICS(jniinvokation());
-
-       o = GET_FIELD(obj, java_objectheader*, fieldID);
-
-       return _Jv_JNI_NewLocalRef(env, o);
-}
-
-
-jboolean _Jv_JNI_GetBooleanField(JNIEnv *env, jobject obj, jfieldID fieldID)
-{
-       s4 i;
-
-       STATISTICS(jniinvokation());
-
-       i = GET_FIELD(obj, s4, fieldID);
-
-       return (jboolean) i;
-}
-
-
-jbyte _Jv_JNI_GetByteField(JNIEnv *env, jobject obj, jfieldID fieldID)
-{
-       s4 i;
-
-       STATISTICS(jniinvokation());
-
-       i = GET_FIELD(obj, s4, fieldID);
-
-       return (jbyte) i;
-}
-
-
-jchar _Jv_JNI_GetCharField(JNIEnv *env, jobject obj, jfieldID fieldID)
-{
-       s4 i;
-
-       STATISTICS(jniinvokation());
-
-       i = GET_FIELD(obj, s4, fieldID);
-
-       return (jchar) i;
-}
-
-
-jshort _Jv_JNI_GetShortField(JNIEnv *env, jobject obj, jfieldID fieldID)
-{
-       s4 i;
-
-       STATISTICS(jniinvokation());
-
-       i = GET_FIELD(obj, s4, fieldID);
-
-       return (jshort) i;
-}
-
-
-jint _Jv_JNI_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 _Jv_JNI_GetLongField(JNIEnv *env, jobject obj, jfieldID fieldID)
-{
-       s8 l;
-
-       STATISTICS(jniinvokation());
-
-       l = GET_FIELD(obj, s8, fieldID);
-
-       return l;
-}
-
-
-jfloat _Jv_JNI_GetFloatField(JNIEnv *env, jobject obj, jfieldID fieldID)
-{
-       float f;
-
-       STATISTICS(jniinvokation());
-
-       f = GET_FIELD(obj, float, fieldID);
-
-       return f;
-}
-
-
-jdouble _Jv_JNI_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 _Jv_JNI_SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID,
-                                                       jobject value)
-{
-       STATISTICS(jniinvokation());
-
-       SET_FIELD(obj, java_objectheader*, fieldID, value);
-}
-
-
-void _Jv_JNI_SetBooleanField(JNIEnv *env, jobject obj, jfieldID fieldID,
-                                                        jboolean value)
-{
-       STATISTICS(jniinvokation());
-
-       SET_FIELD(obj, s4, fieldID, value);
-}
-
-
-void _Jv_JNI_SetByteField(JNIEnv *env, jobject obj, jfieldID fieldID,
-                                                 jbyte value)
-{
-       STATISTICS(jniinvokation());
-
-       SET_FIELD(obj, s4, fieldID, value);
-}
-
-
-void _Jv_JNI_SetCharField(JNIEnv *env, jobject obj, jfieldID fieldID,
-                                                 jchar value)
-{
-       STATISTICS(jniinvokation());
-
-       SET_FIELD(obj, s4, fieldID, value);
-}
-
-
-void _Jv_JNI_SetShortField(JNIEnv *env, jobject obj, jfieldID fieldID,
-                                                  jshort value)
-{
-       STATISTICS(jniinvokation());
-
-       SET_FIELD(obj, s4, fieldID, value);
-}
-
-
-void _Jv_JNI_SetIntField(JNIEnv *env, jobject obj, jfieldID fieldID, jint value)
-{
-       STATISTICS(jniinvokation());
-
-       SET_FIELD(obj, s4, fieldID, value);
-}
-
-
-void _Jv_JNI_SetLongField(JNIEnv *env, jobject obj, jfieldID fieldID,
-                                                 jlong value)
-{
-       STATISTICS(jniinvokation());
-
-       SET_FIELD(obj, s8, fieldID, value);
-}
-
-
-void _Jv_JNI_SetFloatField(JNIEnv *env, jobject obj, jfieldID fieldID,
-                                                  jfloat value)
-{
-       STATISTICS(jniinvokation());
-
-       SET_FIELD(obj, float, fieldID, value);
-}
-
-
-void _Jv_JNI_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 _Jv_JNI_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 _Jv_JNI_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 _Jv_JNI_NewLocalRef(env, o);
-}
-
-
-jobject _Jv_JNI_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 _Jv_JNI_NewLocalRef(env, o);
-}
-
-
-jobject _Jv_JNI_CallStaticObjectMethodA(JNIEnv *env, jclass clazz,
-                                                                               jmethodID methodID, jvalue *args)
-{
-       methodinfo        *m;
-       java_objectheader *o;
-
-       m = (methodinfo *) methodID;
-
-       o = _Jv_jni_CallObjectMethodA(NULL, NULL, m, args);
-
-       return _Jv_JNI_NewLocalRef(env, o);
-}
-
-
-jboolean _Jv_JNI_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);
-       va_end(ap);
-
-       return b;
-}
-
-
-jboolean _Jv_JNI_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);
-
-       return b;
-}
-
-
-jboolean _Jv_JNI_CallStaticBooleanMethodA(JNIEnv *env, jclass clazz,
-                                                                                 jmethodID methodID, jvalue *args)
-{
-       log_text("JNI-Call: CallStaticBooleanMethodA: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-jbyte _Jv_JNI_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);
-       va_end(ap);
-
-       return b;
-}
-
-
-jbyte _Jv_JNI_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);
-
-       return b;
-}
-
-
-jbyte _Jv_JNI_CallStaticByteMethodA(JNIEnv *env, jclass clazz,
-                                                                       jmethodID methodID, jvalue *args)
-{
-       log_text("JNI-Call: CallStaticByteMethodA: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-jchar _Jv_JNI_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);
-       va_end(ap);
-
-       return c;
-}
-
-
-jchar _Jv_JNI_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);
-
-       return c;
-}
-
-
-jchar _Jv_JNI_CallStaticCharMethodA(JNIEnv *env, jclass clazz,
-                                                                       jmethodID methodID, jvalue *args)
-{
-       log_text("JNI-Call: CallStaticCharMethodA: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-jshort _Jv_JNI_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);
-       va_end(ap);
-
-       return s;
-}
-
-
-jshort _Jv_JNI_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);
-
-       return s;
-}
-
-
-jshort _Jv_JNI_CallStaticShortMethodA(JNIEnv *env, jclass clazz,
-                                                                         jmethodID methodID, jvalue *args)
-{
-       log_text("JNI-Call: CallStaticShortMethodA: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-jint _Jv_JNI_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);
-       va_end(ap);
-
-       return i;
-}
-
-
-jint _Jv_JNI_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);
-
-       return i;
-}
-
-
-jint _Jv_JNI_CallStaticIntMethodA(JNIEnv *env, jclass clazz,
-                                                                 jmethodID methodID, jvalue *args)
-{
-       log_text("JNI-Call: CallStaticIntMethodA: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-jlong _Jv_JNI_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 _Jv_JNI_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 _Jv_JNI_CallStaticLongMethodA(JNIEnv *env, jclass clazz,
-                                                                       jmethodID methodID, jvalue *args)
-{
-       log_text("JNI-Call: CallStaticLongMethodA: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-
-jfloat _Jv_JNI_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 _Jv_JNI_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 _Jv_JNI_CallStaticFloatMethodA(JNIEnv *env, jclass clazz,
-                                                                         jmethodID methodID, jvalue *args)
-{
-       log_text("JNI-Call: CallStaticFloatMethodA: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-jdouble _Jv_JNI_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 _Jv_JNI_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 _Jv_JNI_CallStaticDoubleMethodA(JNIEnv *env, jclass clazz,
-                                                                               jmethodID methodID, jvalue *args)
-{
-       log_text("JNI-Call: CallStaticDoubleMethodA: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-void _Jv_JNI_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 _Jv_JNI_CallStaticVoidMethodV(JNIEnv *env, jclass clazz,
-                                                                  jmethodID methodID, va_list args)
-{
-       methodinfo *m;
-
-       m = (methodinfo *) methodID;
-
-       _Jv_jni_CallVoidMethod(NULL, NULL, m, args);
-}
-
-
-void _Jv_JNI_CallStaticVoidMethodA(JNIEnv *env, jclass clazz,
-                                                                  jmethodID methodID, jvalue * args)
-{
-       methodinfo *m;
-
-       m = (methodinfo *) methodID;
-
-       _Jv_jni_CallVoidMethodA(NULL, NULL, m, args);
-}
-
-
-/* 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 _Jv_JNI_GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name,
-                                                                 const char *sig)
-{
-       fieldinfo *f;
-       utf       *uname;
-       utf       *usig;
-
-       STATISTICS(jniinvokation());
-
-       uname = utf_new_char((char *) name);
-       usig  = utf_new_char((char *) sig);
-
-       f = class_findfield(clazz, uname, usig);
-       
-       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 _Jv_JNI_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 _Jv_JNI_NewLocalRef(env, f->value.a);
-}
-
-
-jboolean _Jv_JNI_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 _Jv_JNI_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 _Jv_JNI_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 _Jv_JNI_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 _Jv_JNI_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 _Jv_JNI_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 _Jv_JNI_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 _Jv_JNI_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 _Jv_JNI_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 _Jv_JNI_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 _Jv_JNI_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 _Jv_JNI_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 _Jv_JNI_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 _Jv_JNI_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 _Jv_JNI_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 _Jv_JNI_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 _Jv_JNI_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 _Jv_JNI_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 == NULL) || (s == NULL))
-               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) _Jv_JNI_NewLocalRef(env, (jobject) s);
-}
-
-
-static jchar emptyStringJ[]={0,0};
-
-/* GetStringLength *************************************************************
-
-   Returns the length (the count of Unicode characters) of a Java
-   string.
-
-*******************************************************************************/
-
-jsize _Jv_JNI_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 *_Jv_JNI_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 _Jv_JNI_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 _Jv_JNI_NewStringUTF(JNIEnv *env, const char *bytes)
-{
-       java_lang_String *s;
-
-       STATISTICS(jniinvokation());
-
-       s = javastring_safe_new_from_utf8(bytes);
-
-    return (jstring) _Jv_JNI_NewLocalRef(env, (jobject) s);
-}
-
-
-/****************** returns the utf8 length in bytes of a string *******************/
-
-jsize _Jv_JNI_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 *_Jv_JNI_GetStringUTFChars(JNIEnv *env, jstring string,
-                                                                         jboolean *isCopy)
-{
-       utf *u;
-
-       STATISTICS(jniinvokation());
-
-       if (string == NULL)
-               return "";
-
-       if (isCopy)
-               *isCopy = JNI_TRUE;
-       
-       u = javastring_toutf((java_lang_String *) string, false);
-
-       if (u != NULL)
-               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 _Jv_JNI_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 _Jv_JNI_GetArrayLength(JNIEnv *env, jarray array)
-{
-       java_arrayheader *a;
-
-       STATISTICS(jniinvokation());
-
-       a = (java_arrayheader *) array;
-
-       return a->size;
-}
-
+/* GetStaticMethodID ***********************************************************
 
-/* NewObjectArray **************************************************************
+   Returns the method ID for a static method of a class. The method is
+   specified by its name and signature.
 
-   Constructs a new array holding objects in class elementClass. All
-   elements are initially set to initialElement.
+   GetStaticMethodID() causes an uninitialized class to be
+   initialized.
 
 *******************************************************************************/
 
-jobjectArray _Jv_JNI_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 == NULL)
-               return NULL;
-
-       /* set all elements to initialElement */
-
-       for (i = 0; i < length; i++)
-               oa->data[i] = initialElement;
-
-       return (jobjectArray) _Jv_JNI_NewLocalRef(env, (jobject) oa);
-}
-
-
-jobject _Jv_JNI_GetObjectArrayElement(JNIEnv *env, jobjectArray array,
-                                                                         jsize index)
+jmethodID _Jv_JNI_GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name,
+                                                                       const char *sig)
 {
-       java_objectarray *oa;
-       jobject           o;
+       classinfo  *c;
+       utf        *uname;
+       utf        *udesc;
+       methodinfo *m;
 
        STATISTICS(jniinvokation());
 
-       oa = (java_objectarray *) array;
+       c = LLNI_classinfo_unwrap(clazz);
 
-       if (index >= oa->header.size) {
-               exceptions_throw_arrayindexoutofboundsexception();
+       if (!c)
                return NULL;
-       }
 
-       o = oa->data[index];
-
-       return _Jv_JNI_NewLocalRef(env, o);
-}
+       if (!(c->state & CLASS_INITIALIZED))
+               if (!initialize_class(c))
+                       return NULL;
 
+       /* try to get the static method of the class */
 
-void _Jv_JNI_SetObjectArrayElement(JNIEnv *env, jobjectArray array,
-                                                                  jsize index, jobject val)
-{
-       java_objectarray  *oa;
-       java_objectheader *o;
+       uname = utf_new_char((char *) name);
+       udesc = utf_new_char((char *) sig);
 
-       STATISTICS(jniinvokation());
+       m = class_resolvemethod(c, uname, udesc);
 
-       oa = (java_objectarray *) array;
-       o  = (java_objectheader *) val;
+       if ((m == NULL) || !(m->flags & ACC_STATIC)) {
+               exceptions_throw_nosuchmethoderror(c, uname, udesc);
 
-       if (index >= oa->header.size) {
-               exceptions_throw_arrayindexoutofboundsexception();
-               return;
+               return NULL;
        }
 
-       /* 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 (jmethodID) m;
+}
 
-               return;
-       }
 
-       oa->data[index] = val;
-}
+#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)
 
 
-jbooleanArray _Jv_JNI_NewBooleanArray(JNIEnv *env, jsize len)
+jobject _Jv_JNI_CallStaticObjectMethod(JNIEnv *env, jclass clazz,
+                                                                          jmethodID methodID, ...)
 {
-       java_booleanarray *ba;
-
-       STATISTICS(jniinvokation());
+       methodinfo    *m;
+       java_handle_t *o;
+       va_list        ap;
 
-       if (len < 0) {
-               exceptions_throw_negativearraysizeexception();
-               return NULL;
-       }
+       m = (methodinfo *) methodID;
 
-       ba = builtin_newarray_boolean(len);
+       va_start(ap, methodID);
+       o = _Jv_jni_CallObjectMethod(NULL, NULL, m, ap);
+       va_end(ap);
 
-       return (jbooleanArray) _Jv_JNI_NewLocalRef(env, (jobject) ba);
+       return _Jv_JNI_NewLocalRef(env, (jobject) o);
 }
 
 
-jbyteArray _Jv_JNI_NewByteArray(JNIEnv *env, jsize len)
+jobject _Jv_JNI_CallStaticObjectMethodV(JNIEnv *env, jclass clazz,
+                                                                               jmethodID methodID, va_list args)
 {
-       java_bytearray *ba;
-
-       STATISTICS(jniinvokation());
+       methodinfo    *m;
+       java_handle_t *o;
 
-       if (len < 0) {
-               exceptions_throw_negativearraysizeexception();
-               return NULL;
-       }
+       m = (methodinfo *) methodID;
 
-       ba = builtin_newarray_byte(len);
+       o = _Jv_jni_CallObjectMethod(NULL, NULL, m, args);
 
-       return (jbyteArray) _Jv_JNI_NewLocalRef(env, (jobject) ba);
+       return _Jv_JNI_NewLocalRef(env, (jobject) o);
 }
 
 
-jcharArray _Jv_JNI_NewCharArray(JNIEnv *env, jsize len)
+jobject _Jv_JNI_CallStaticObjectMethodA(JNIEnv *env, jclass clazz,
+                                                                               jmethodID methodID, const jvalue *args)
 {
-       java_chararray *ca;
-
-       STATISTICS(jniinvokation());
+       methodinfo    *m;
+       java_handle_t *o;
 
-       if (len < 0) {
-               exceptions_throw_negativearraysizeexception();
-               return NULL;
-       }
+       m = (methodinfo *) methodID;
 
-       ca = builtin_newarray_char(len);
+       o = _Jv_jni_CallObjectMethodA(NULL, NULL, m, args);
 
-       return (jcharArray) _Jv_JNI_NewLocalRef(env, (jobject) ca);
+       return _Jv_JNI_NewLocalRef(env, (jobject) o);
 }
 
 
-jshortArray _Jv_JNI_NewShortArray(JNIEnv *env, jsize len)
+void _Jv_JNI_CallStaticVoidMethod(JNIEnv *env, jclass clazz,
+                                                                 jmethodID methodID, ...)
 {
-       java_shortarray *sa;
-
-       STATISTICS(jniinvokation());
-
-       if (len < 0) {
-               exceptions_throw_negativearraysizeexception();
-               return NULL;
-       }
+       methodinfo *m;
+       va_list     ap;
 
-       sa = builtin_newarray_short(len);
+       m = (methodinfo *) methodID;
 
-       return (jshortArray) _Jv_JNI_NewLocalRef(env, (jobject) sa);
+       va_start(ap, methodID);
+       _Jv_jni_CallVoidMethod(NULL, NULL, m, ap);
+       va_end(ap);
 }
 
 
-jintArray _Jv_JNI_NewIntArray(JNIEnv *env, jsize len)
+void _Jv_JNI_CallStaticVoidMethodV(JNIEnv *env, jclass clazz,
+                                                                  jmethodID methodID, va_list args)
 {
-       java_intarray *ia;
-
-       STATISTICS(jniinvokation());
-
-       if (len < 0) {
-               exceptions_throw_negativearraysizeexception();
-               return NULL;
-       }
+       methodinfo *m;
 
-       ia = builtin_newarray_int(len);
+       m = (methodinfo *) methodID;
 
-       return (jintArray) _Jv_JNI_NewLocalRef(env, (jobject) ia);
+       _Jv_jni_CallVoidMethod(NULL, NULL, m, args);
 }
 
 
-jlongArray _Jv_JNI_NewLongArray(JNIEnv *env, jsize len)
+void _Jv_JNI_CallStaticVoidMethodA(JNIEnv *env, jclass clazz,
+                                                                  jmethodID methodID, const jvalue * args)
 {
-       java_longarray *la;
-
-       STATISTICS(jniinvokation());
-
-       if (len < 0) {
-               exceptions_throw_negativearraysizeexception();
-               return NULL;
-       }
+       methodinfo *m;
 
-       la = builtin_newarray_long(len);
+       m = (methodinfo *) methodID;
 
-       return (jlongArray) _Jv_JNI_NewLocalRef(env, (jobject) la);
+       _Jv_jni_CallVoidMethodA(NULL, NULL, m, args);
 }
 
 
-jfloatArray _Jv_JNI_NewFloatArray(JNIEnv *env, jsize len)
-{
-       java_floatarray *fa;
-
-       STATISTICS(jniinvokation());
-
-       if (len < 0) {
-               exceptions_throw_negativearraysizeexception();
-               return NULL;
-       }
+/* Accessing Static Fields ****************************************************/
 
-       fa = builtin_newarray_float(len);
+/* GetStaticFieldID ************************************************************
 
-       return (jfloatArray) _Jv_JNI_NewLocalRef(env, (jobject) fa);
-}
+   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.
 
+*******************************************************************************/
 
-jdoubleArray _Jv_JNI_NewDoubleArray(JNIEnv *env, jsize len)
+jfieldID _Jv_JNI_GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name,
+                                                                 const char *sig)
 {
-       java_doublearray *da;
+       classinfo *c;
+       fieldinfo *f;
+       utf       *uname;
+       utf       *usig;
 
        STATISTICS(jniinvokation());
 
-       if (len < 0) {
-               exceptions_throw_negativearraysizeexception();
-               return NULL;
-       }
+       c = LLNI_classinfo_unwrap(clazz);
+
+       uname = utf_new_char((char *) name);
+       usig  = utf_new_char((char *) sig);
 
-       da = builtin_newarray_double(len);
+       f = class_findfield(c, uname, usig);
+       
+       if (f == NULL)
+               exceptions_throw_nosuchfielderror(c, uname);
 
-       return (jdoubleArray) _Jv_JNI_NewLocalRef(env, (jobject) da);
+       return (jfieldID) f;
 }
 
 
-/* Get<PrimitiveType>ArrayElements *********************************************
+/* GetStatic<type>Field ********************************************************
 
-   A family of functions that returns the body of the primitive array.
+   This family of accessor routines returns the value of a static
+   field of an object.
 
 *******************************************************************************/
 
-jboolean *_Jv_JNI_GetBooleanArrayElements(JNIEnv *env, jbooleanArray array,
-                                                                                 jboolean *isCopy)
-{
-       java_booleanarray *ba;
-
-       STATISTICS(jniinvokation());
-
-       ba = (java_booleanarray *) array;
-
-       if (isCopy)
-               *isCopy = JNI_FALSE;
-
-       return ba->data;
-}
+#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)
 
 
-jbyte *_Jv_JNI_GetByteArrayElements(JNIEnv *env, jbyteArray array,
-                                                                       jboolean *isCopy)
+jobject _Jv_JNI_GetStaticObjectField(JNIEnv *env, jclass clazz,
+                                                                        jfieldID fieldID)
 {
-       java_bytearray *ba;
+       classinfo *c;
+       fieldinfo *f;
 
        STATISTICS(jniinvokation());
 
-       ba = (java_bytearray *) array;
+       c = LLNI_classinfo_unwrap(clazz);
+       f = (fieldinfo *) fieldID;
 
-       if (isCopy)
-               *isCopy = JNI_FALSE;
+       if (!(c->state & CLASS_INITIALIZED))
+               if (!initialize_class(c))
+                       return NULL;
 
-       return ba->data;
+       return _Jv_JNI_NewLocalRef(env, f->value->a);
 }
 
 
-jchar *_Jv_JNI_GetCharArrayElements(JNIEnv *env, jcharArray array,
-                                                                       jboolean *isCopy)
-{
-       java_chararray *ca;
-
-       STATISTICS(jniinvokation());
+/*  SetStatic<type>Field *******************************************************
 
-       ca = (java_chararray *) array;
+       This family of accessor routines sets the value of a static field
+       of an object.
 
-       if (isCopy)
-               *isCopy = JNI_FALSE;
+*******************************************************************************/
 
-       return ca->data;
-}
+#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)
 
 
-jshort *_Jv_JNI_GetShortArrayElements(JNIEnv *env, jshortArray array,
-                                                                         jboolean *isCopy)
+void _Jv_JNI_SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID,
+                                                                 jobject value)
 {
-       java_shortarray *sa;
+       classinfo *c;
+       fieldinfo *f;
 
        STATISTICS(jniinvokation());
 
-       sa = (java_shortarray *) array;
+       c = LLNI_classinfo_unwrap(clazz);
+       f = (fieldinfo *) fieldID;
 
-       if (isCopy)
-               *isCopy = JNI_FALSE;
+       if (!(c->state & CLASS_INITIALIZED))
+               if (!initialize_class(c))
+                       return;
 
-       return sa->data;
+       f->value->a = value;
 }
 
 
-jint *_Jv_JNI_GetIntArrayElements(JNIEnv *env, jintArray array,
-                                                                 jboolean *isCopy)
-{
-       java_intarray *ia;
-
-       STATISTICS(jniinvokation());
-
-       ia = (java_intarray *) array;
+/* String Operations **********************************************************/
 
-       if (isCopy)
-               *isCopy = JNI_FALSE;
+/* NewString *******************************************************************
 
-       return ia->data;
-}
+   Create new java.lang.String object from an array of Unicode
+   characters.
 
+*******************************************************************************/
 
-jlong *_Jv_JNI_GetLongArrayElements(JNIEnv *env, jlongArray array,
-                                                                       jboolean *isCopy)
+jstring _Jv_JNI_NewString(JNIEnv *env, const jchar *buf, 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);
 
-       la = (java_longarray *) array;
+       /* javastring or characterarray could not be created */
+       if ((a == NULL) || (s == NULL))
+               return NULL;
 
-       if (isCopy)
-               *isCopy = JNI_FALSE;
+       /* copy text */
+       for (i = 0; i < len; i++)
+               LLNI_array_direct(a, i) = buf[i];
 
-       /* We cast this one to prevent a compiler warning on 64-bit
-          systems since GNU Classpath typedef jlong to long long. */
+       LLNI_field_set_ref(s, value , a);
+       LLNI_field_set_val(s, offset, 0);
+       LLNI_field_set_val(s, count , len);
 
-       return (jlong *) la->data;
+       return (jstring) _Jv_JNI_NewLocalRef(env, (jobject) s);
 }
 
 
-jfloat *_Jv_JNI_GetFloatArrayElements(JNIEnv *env, jfloatArray array,
-                                                                         jboolean *isCopy)
-{
-       java_floatarray *fa;
-
-       STATISTICS(jniinvokation());
-
-       fa = (java_floatarray *) array;
+static jchar emptyStringJ[]={0,0};
 
-       if (isCopy)
-               *isCopy = JNI_FALSE;
+/* GetStringLength *************************************************************
 
-       return fa->data;
-}
+   Returns the length (the count of Unicode characters) of a Java
+   string.
 
+*******************************************************************************/
 
-jdouble *_Jv_JNI_GetDoubleArrayElements(JNIEnv *env, jdoubleArray array,
-                                                                               jboolean *isCopy)
+jsize _Jv_JNI_GetStringLength(JNIEnv *env, jstring str)
 {
-       java_doublearray *da;
+       java_lang_String *s;
+       jsize             len;
 
-       STATISTICS(jniinvokation());
+       TRACEJNICALLS("_Jv_JNI_GetStringLength(env=%p, str=%p)", env, str);
 
-       da = (java_doublearray *) array;
+       s = (java_lang_String *) str;
 
-       if (isCopy)
-               *isCopy = JNI_FALSE;
+       LLNI_field_get_val(s, count, len);
 
-       return da->data;
+       return len;
 }
 
 
-/* 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.
-
-*******************************************************************************/
-
-void _Jv_JNI_ReleaseBooleanArrayElements(JNIEnv *env, jbooleanArray array,
-                                                                                jboolean *elems, jint mode)
+/********************  convertes javastring to u2-array ****************************/
+       
+u2 *javastring_tou2(jstring so) 
 {
-       java_booleanarray *ba;
+       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;
 
-       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;
-               }
-       }
-}
+       if (!s)
+               return NULL;
 
+       LLNI_field_get_ref(s, value, a);
 
-void _Jv_JNI_ReleaseByteArrayElements(JNIEnv *env, jbyteArray array,
-                                                                         jbyte *elems, jint mode)
-{
-       java_bytearray *ba;
+       if (!a)
+               return NULL;
 
-       STATISTICS(jniinvokation());
+       LLNI_field_get_val(s, count, count);
+       LLNI_field_get_val(s, offset, offset);
 
-       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;
-               }
-       }
-}
+       /* allocate memory */
 
+       stringbuffer = MNEW(u2, count + 1);
 
-void _Jv_JNI_ReleaseCharArrayElements(JNIEnv *env, jcharArray array,
-                                                                         jchar *elems, jint mode)
-{
-       java_chararray *ca;
+       /* copy text */
 
-       STATISTICS(jniinvokation());
+       for (i = 0; i < count; i++)
+               stringbuffer[i] = LLNI_array_direct(a, offset + i);
+       
+       /* terminate string */
 
-       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;
-               }
-       }
-}
+       stringbuffer[i] = '\0';
 
+       return stringbuffer;
+}
 
-void _Jv_JNI_ReleaseShortArrayElements(JNIEnv *env, jshortArray array,
-                                                                          jshort *elems, jint mode)
-{
-       java_shortarray *sa;
 
-       STATISTICS(jniinvokation());
+/* GetStringChars **************************************************************
 
-       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;
-               }
-       }
-}
+   Returns a pointer to the array of Unicode characters of the
+   string. This pointer is valid until ReleaseStringChars() is called.
 
+*******************************************************************************/
 
-void _Jv_JNI_ReleaseIntArrayElements(JNIEnv *env, jintArray array, jint *elems,
-                                                                        jint mode)
-{
-       java_intarray *ia;
+const jchar *_Jv_JNI_GetStringChars(JNIEnv *env, jstring str, jboolean *isCopy)
+{      
+       jchar *jc;
 
        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;
-               }
-       }
-}
+       jc = javastring_tou2(str);
 
+       if (jc) {
+               if (isCopy)
+                       *isCopy = JNI_TRUE;
 
-void _Jv_JNI_ReleaseLongArrayElements(JNIEnv *env, jlongArray array,
-                                                                         jlong *elems, jint mode)
-{
-       java_longarray *la;
+               return jc;
+       }
 
-       STATISTICS(jniinvokation());
+       if (isCopy)
+               *isCopy = JNI_TRUE;
 
-       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 emptyStringJ;
 }
 
 
-void _Jv_JNI_ReleaseFloatArrayElements(JNIEnv *env, jfloatArray array,
-                                                                          jfloat *elems, jint mode)
-{
-       java_floatarray *fa;
-
-       STATISTICS(jniinvokation());
+/* ReleaseStringChars **********************************************************
 
-       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;
-               }
-       }
-}
+   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 _Jv_JNI_ReleaseDoubleArrayElements(JNIEnv *env, jdoubleArray array,
-                                                                               jdouble *elems, jint mode)
+void _Jv_JNI_ReleaseStringChars(JNIEnv *env, jstring str, const jchar *chars)
 {
-       java_doublearray *da;
+       java_lang_String *s;
 
        STATISTICS(jniinvokation());
 
-       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;
-               }
-       }
+       if (chars == emptyStringJ)
+               return;
+
+       s = (java_lang_String *) str;
+
+       MFREE(((jchar *) chars), jchar, LLNI_field_direct(s, count) + 1);
 }
 
 
-/*  Get<PrimitiveType>ArrayRegion **********************************************
+/* NewStringUTF ****************************************************************
 
-       A family of functions that copies a region of a primitive array
-       into a buffer.
+   Constructs a new java.lang.String object from an array of UTF-8
+   characters.
 
 *******************************************************************************/
 
-void _Jv_JNI_GetBooleanArrayRegion(JNIEnv *env, jbooleanArray array,
-                                                                  jsize start, jsize len, jboolean *buf)
+jstring _Jv_JNI_NewStringUTF(JNIEnv *env, const char *bytes)
 {
-       java_booleanarray *ba;
+       java_lang_String *s;
 
-       STATISTICS(jniinvokation());
+       TRACEJNICALLS("_Jv_JNI_NewStringUTF(env=%p, bytes=%s)", env, bytes);
 
-       ba = (java_booleanarray *) array;
+       s = (java_lang_String *) javastring_safe_new_from_utf8(bytes);
 
-    if ((start < 0) || (len < 0) || (start + len > ba->header.size))
-               exceptions_throw_arrayindexoutofboundsexception();
-    else
-               MCOPY(buf, &ba->data[start], u1, len);
+    return (jstring) _Jv_JNI_NewLocalRef(env, (jobject) s);
 }
 
 
-void _Jv_JNI_GetByteArrayRegion(JNIEnv *env, jbyteArray array, jsize start,
-                                                               jsize len, jbyte *buf)
-{
-       java_bytearray *ba;
+/****************** returns the utf8 length in bytes of a string *******************/
 
-       STATISTICS(jniinvokation());
+jsize _Jv_JNI_GetStringUTFLength(JNIEnv *env, jstring string)
+{   
+       java_lang_String *s;
+       s4                length;
 
-       ba = (java_bytearray *) array;
+       TRACEJNICALLS("_Jv_JNI_GetStringUTFLength(env=%p, string=%p)", env, string);
 
-       if ((start < 0) || (len < 0) || (start + len > ba->header.size))
-               exceptions_throw_arrayindexoutofboundsexception();
-       else
-               MCOPY(buf, &ba->data[start], s1, len);
-}
+       s = (java_lang_String *) string;
 
+       length = u2_utflength(LLNI_field_direct(s, value)->data, LLNI_field_direct(s, count));
 
-void _Jv_JNI_GetCharArrayRegion(JNIEnv *env, jcharArray array, jsize start,
-                                                               jsize len, jchar *buf)
-{
-       java_chararray *ca;
+       return length;
+}
 
-       STATISTICS(jniinvokation());
 
-       ca = (java_chararray *) array;
+/* GetStringUTFChars ***********************************************************
 
-       if ((start < 0) || (len < 0) || (start + len > ca->header.size))
-               exceptions_throw_arrayindexoutofboundsexception();
-       else
-               MCOPY(buf, &ca->data[start], u2, len);
-}
+   Returns a pointer to an array of UTF-8 characters of the
+   string. This array is valid until it is released by
+   ReleaseStringUTFChars().
 
+*******************************************************************************/
 
-void _Jv_JNI_GetShortArrayRegion(JNIEnv *env, jshortArray array, jsize start,
-                                                                jsize len, jshort *buf)
+const char *_Jv_JNI_GetStringUTFChars(JNIEnv *env, jstring string,
+                                                                         jboolean *isCopy)
 {
-       java_shortarray *sa;
+       utf *u;
 
        STATISTICS(jniinvokation());
 
-       sa = (java_shortarray *) array;
+       if (string == NULL)
+               return "";
 
-       if ((start < 0) || (len < 0) || (start + len > sa->header.size))
-               exceptions_throw_arrayindexoutofboundsexception();
-       else    
-               MCOPY(buf, &sa->data[start], s2, len);
-}
+       if (isCopy)
+               *isCopy = JNI_TRUE;
+       
+       u = javastring_toutf((java_handle_t *) string, false);
 
+       if (u != NULL)
+               return u->text;
 
-void _Jv_JNI_GetIntArrayRegion(JNIEnv *env, jintArray array, jsize start,
-                                                          jsize len, jint *buf)
-{
-       java_intarray *ia;
+       return "";
+}
 
-       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 _Jv_JNI_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 _Jv_JNI_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 _Jv_JNI_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 _Jv_JNI_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 _Jv_JNI_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 _Jv_JNI_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 _Jv_JNI_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 _Jv_JNI_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 _Jv_JNI_SetLongArrayRegion(JNIEnv* env, jlongArray array, jsize start,
-                                                               jsize len, jlong *buf)
-{
-       java_longarray *la;
 
-       STATISTICS(jniinvokation());
+/* Get<PrimitiveType>ArrayElements *********************************************
+
+   A family of functions that returns the body of the primitive array.
 
-       la = (java_longarray *) 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 _Jv_JNI_SetFloatArrayRegion(JNIEnv *env, jfloatArray array, jsize start,
-                                                                jsize len, jfloat *buf)
-{
-       java_floatarray *fa;
+/* Release<PrimitiveType>ArrayElements *****************************************
 
-       STATISTICS(jniinvokation());
+   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 _Jv_JNI_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;
+#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)
 
-       if ((start < 0) || (len < 0) || (start + len > da->header.size))
-               exceptions_throw_arrayindexoutofboundsexception();
-       else
-               MCOPY(&da->data[start], buf, double, len);
-}
+
+/*  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 *************************************************/
@@ -5034,13 +3133,18 @@ void _Jv_JNI_SetDoubleArrayRegion(JNIEnv *env, jdoubleArray array, jsize start,
 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;
 }
 
@@ -5150,30 +3254,59 @@ jint _Jv_JNI_GetJavaVM(JNIEnv *env, JavaVM **vm)
 void _Jv_JNI_GetStringRegion(JNIEnv* env, jstring str, jsize start, jsize len,
                                                         jchar *buf)
 {
-       java_lang_String *s;
-       java_chararray   *ca;
+       java_lang_String        *s;
+       java_handle_chararray_t *ca;
 
        STATISTICS(jniinvokation());
 
        s  = (java_lang_String *) str;
-       ca = s->value;
+       LLNI_field_get_ref(s, value, ca);
 
-       if ((start < 0) || (len < 0) || (start > s->count) ||
-               (start + len > s->count)) {
+       if ((start < 0) || (len < 0) || (start > LLNI_field_direct(s, count)) ||
+               (start + len > LLNI_field_direct(s, count))) {
                exceptions_throw_stringindexoutofboundsexception();
                return;
        }
 
-       MCOPY(buf, &ca->data[start], u2, len);
+       MCOPY(buf, &LLNI_array_direct(ca, start), u2, len);
 }
 
 
+/* 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';
 }
 
 
@@ -5186,14 +3319,14 @@ void _Jv_JNI_GetStringUTFRegion(JNIEnv* env, jstring str, jsize start,
 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 = _Jv_JNI_GetByteArrayElements(env, ba, isCopy);
+       bp = _Jv_JNI_GetByteArrayElements(env, (jbyteArray) ba, isCopy);
 
        return (void *) bp;
 }
@@ -5272,9 +3405,12 @@ jobject _Jv_JNI_NewGlobalRef(JNIEnv* env, jobject obj)
        hashtable_global_ref_entry *gre;
        u4   key;                           /* hashkey                            */
        u4   slot;                          /* slot in hashtable                  */
+       java_handle_t *o;
 
        STATISTICS(jniinvokation());
 
+       o = (java_handle_t *) obj;
+
        LOCK_MONITOR_ENTER(hashtable_global_ref->header);
 
        /* normally addresses are aligned to 4, 8 or 16 bytes */
@@ -5286,7 +3422,7 @@ jobject _Jv_JNI_NewGlobalRef(JNIEnv* env, jobject obj)
        /* search external hash chain for the entry */
 
        while (gre) {
-               if (gre->o == obj) {
+               if (gre->o == o) {
                        /* global object found, increment the reference */
 
                        gre->refs++;
@@ -5303,7 +3439,7 @@ jobject _Jv_JNI_NewGlobalRef(JNIEnv* env, jobject obj)
 
        gre = NEW(hashtable_global_ref_entry);
 
-       gre->o    = obj;
+       gre->o    = o;
        gre->refs = 1;
 
        /* insert entry into hashtable */
@@ -5334,9 +3470,12 @@ void _Jv_JNI_DeleteGlobalRef(JNIEnv* env, jobject globalRef)
        hashtable_global_ref_entry *prevgre;
        u4   key;                           /* hashkey                            */
        u4   slot;                          /* slot in hashtable                  */
+       java_handle_t              *o;
 
        STATISTICS(jniinvokation());
 
+       o = (java_handle_t *) globalRef;
+
        LOCK_MONITOR_ENTER(hashtable_global_ref->header);
 
        /* normally addresses are aligned to 4, 8 or 16 bytes */
@@ -5352,7 +3491,7 @@ void _Jv_JNI_DeleteGlobalRef(JNIEnv* env, jobject globalRef)
        /* search external hash chain for the entry */
 
        while (gre) {
-               if (gre->o == globalRef) {
+               if (gre->o == o) {
                        /* global object found, decrement the reference count */
 
                        gre->refs--;
@@ -5394,9 +3533,13 @@ void _Jv_JNI_DeleteGlobalRef(JNIEnv* env, jobject globalRef)
 
 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;
 }
 
 
@@ -5412,29 +3555,31 @@ jboolean _Jv_JNI_ExceptionCheck(JNIEnv *env)
 
 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 */
 
@@ -5445,6 +3590,13 @@ jobject _Jv_JNI_NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
        /* add local reference and return the value */
 
        return _Jv_JNI_NewLocalRef(env, nbuf);
+#else
+       vm_abort("_Jv_JNI_NewDirectByteBuffer: not implemented in this configuration");
+
+       /* keep compiler happy */
+
+       return NULL;
+#endif
 }
 
 
@@ -5457,12 +3609,14 @@ jobject _Jv_JNI_NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
 
 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());
 
@@ -5471,16 +3625,28 @@ void *_Jv_JNI_GetDirectBufferAddress(JNIEnv *env, jobject buf)
 
        nbuf = (java_nio_DirectByteBufferImpl *) buf;
 
-#if SIZEOF_VOID_P == 8
-       address = (gnu_classpath_Pointer64 *) nbuf->address;
-#else
-       address = (gnu_classpath_Pointer32 *) nbuf->address;
-#endif
+# 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 (address == NULL)
+       if (paddress == NULL)
                return NULL;
 
-       return (void *) address->data;
+       LLNI_field_get_val(paddress, data, address);
+       /* this was the cast to avaoid warning: (void *) paddress->data */
+
+       return address;
+#else
+       vm_abort("_Jv_JNI_GetDirectBufferAddress: not implemented in this configuration");
+
+       /* keep compiler happy */
+
+       return NULL;
+#endif
 }
 
 
@@ -5493,16 +3659,30 @@ void *_Jv_JNI_GetDirectBufferAddress(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
 }
 
 
@@ -5557,7 +3737,7 @@ static s4 jni_attach_current_thread(void **p_env, void *thr_args, bool isdaemon)
                if (!threads_attach_current_thread(vm_aargs, false))
                        return JNI_ERR;
 
-               if (!jni_init_localref_table())
+               if (!localref_table_init())
                        return JNI_ERR;
        }
 #endif
@@ -5687,7 +3867,7 @@ jint _Jv_JNI_AttachCurrentThreadAsDaemon(JavaVM *vm, void **penv, void *args)
 
 /* JNI invocation table *******************************************************/
 
-const struct JNIInvokeInterface _Jv_JNIInvokeInterface = {
+const struct JNIInvokeInterface_ _Jv_JNIInvokeInterface = {
        NULL,
        NULL,
        NULL,
@@ -5702,7 +3882,7 @@ const struct JNIInvokeInterface _Jv_JNIInvokeInterface = {
 
 /* JNI function table *********************************************************/
 
-struct JNINativeInterface _Jv_JNINativeInterface = {
+struct JNINativeInterface_ _Jv_JNINativeInterface = {
        NULL,
        NULL,
        NULL,
@@ -6020,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;
 }
 
 
@@ -6035,6 +4223,8 @@ jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
 
 jint JNI_CreateJavaVM(JavaVM **p_vm, void **p_env, void *vm_args)
 {
+       TRACEJNICALLS("JNI_CreateJavaVM(p_vm=%p, p_env=%p, vm_args=%p)", p_vm, p_env, vm_args);
+
        /* actually create the JVM */
 
        if (!vm_createjvm(p_vm, p_env, vm_args))