* Removed all Id tags.
[cacao.git] / src / native / jni.c
index f70fb02c77b4b592770b72f86807f90a724f53bd..a28cd68df14fa8481bda0f7a7d8034280a0b197d 100644 (file)
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   $Id: jni.c 7926 2007-05-21 08:27:06Z 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"
 
 #if defined(ENABLE_JAVASE)
 #include "native/include/java_lang_Throwable.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_Method.h"
 
 # include "native/include/java_nio_Buffer.h"
-# include "native/include/java_nio_DirectByteBufferImpl.h"
+
+# if defined(WITH_CLASSPATH_GNU)
+#  include "native/include/java_nio_DirectByteBufferImpl.h"
+# endif
 #endif
 
 #if defined(ENABLE_JVMTI)
@@ -82,6 +91,7 @@
 
 #if defined(ENABLE_JAVASE)
 # include "native/vm/java_lang_ClassLoader.h"
+# include "native/vm/reflect.h"
 #endif
 
 #include "threads/lock-common.h"
 #include "vm/exceptions.h"
 #include "vm/global.h"
 #include "vm/initialize.h"
+#include "vm/primitive.h"
+#include "vm/resolve.h"
 #include "vm/stringlocal.h"
 #include "vm/vm.h"
 
 
 #include "vmcore/loader.h"
 #include "vmcore/options.h"
-#include "vm/resolve.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 ***********************************************************/
 
 /* global reference table *****************************************************/
@@ -136,20 +161,13 @@ static methodinfo *dbbirw_init;
 #endif
 
 
-/* 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 **************************************************/
@@ -181,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))
@@ -197,7 +216,6 @@ bool jni_init(void)
                                                        utf_new_char("(Ljava/lang/Object;Lgnu/classpath/Pointer;III)V"))))
                return false;
 
-# if defined(WITH_CLASSPATH_GNU)
 #  if SIZEOF_VOID_P == 8
        if (!(class_gnu_classpath_Pointer64 =
                  load_class_bootstrap(utf_new_char("gnu/classpath/Pointer64"))) ||
@@ -216,226 +234,18 @@ bool jni_init(void)
 }
 
 
-/* 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; */
-
-       return true;
-
-illegal_arg:
-       exceptions_throw_illegalargumentexception();
-       return false;
-}
-
-
 /* _Jv_jni_CallObjectMethod ****************************************************
 
    Internal function to call Java Object methods.
 
 *******************************************************************************/
 
-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());
 
@@ -477,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());
 
@@ -525,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;
@@ -572,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;
@@ -618,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;
@@ -664,8 +475,8 @@ static jlong _Jv_jni_CallLongMethod(java_objectheader *o, vftbl_t *vftbl,
 
 *******************************************************************************/
 
-static jlong _Jv_jni_CallLongMethodA(java_objectheader *o, vftbl_t *vftbl,
-                                                                        methodinfo *m, jvalue *args)
+static jlong _Jv_jni_CallLongMethodA(java_handle_t *o, vftbl_t *vftbl,
+                                                                        methodinfo *m, const jvalue *args)
 {
        methodinfo *resm;
        jlong       l;
@@ -710,7 +521,7 @@ static jlong _Jv_jni_CallLongMethodA(java_objectheader *o, vftbl_t *vftbl,
 
 *******************************************************************************/
 
-static jfloat _Jv_jni_CallFloatMethod(java_objectheader *o, vftbl_t *vftbl,
+static jfloat _Jv_jni_CallFloatMethod(java_handle_t *o, vftbl_t *vftbl,
                                                                          methodinfo *m, va_list ap)
 {
        methodinfo *resm;
@@ -749,8 +560,8 @@ static jfloat _Jv_jni_CallFloatMethod(java_objectheader *o, vftbl_t *vftbl,
 
 *******************************************************************************/
 
-static jfloat _Jv_jni_CallFloatMethodA(java_objectheader *o, vftbl_t *vftbl,
-                                                                          methodinfo *m, jvalue *args)
+static jfloat _Jv_jni_CallFloatMethodA(java_handle_t *o, vftbl_t *vftbl,
+                                                                          methodinfo *m, const jvalue *args)
 {
        methodinfo *resm;
        jfloat      f;
@@ -788,7 +599,7 @@ static jfloat _Jv_jni_CallFloatMethodA(java_objectheader *o, vftbl_t *vftbl,
 
 *******************************************************************************/
 
-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;
@@ -825,8 +636,8 @@ static jdouble _Jv_jni_CallDoubleMethod(java_objectheader *o, vftbl_t *vftbl,
 
 *******************************************************************************/
 
-static jdouble _Jv_jni_CallDoubleMethodA(java_objectheader *o, vftbl_t *vftbl,
-                                                                                methodinfo *m, jvalue *args)
+static jdouble _Jv_jni_CallDoubleMethodA(java_handle_t *o, vftbl_t *vftbl,
+                                                                                methodinfo *m, const jvalue *args)
 {
        methodinfo *resm;
        jdouble     d;
@@ -862,7 +673,7 @@ static jdouble _Jv_jni_CallDoubleMethodA(java_objectheader *o, vftbl_t *vftbl,
 
 *******************************************************************************/
 
-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;
@@ -903,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;
 
@@ -949,15 +760,17 @@ 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;
-       java_objectheader *xptr;
+       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 == NULL) {
                exceptions_throw_nullpointerexception();
@@ -984,7 +797,7 @@ java_objectheader *_Jv_jni_invokeNative(methodinfo *m, java_objectheader *o,
        /* 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))) 
        {
                exceptions_throw_illegalargumentexception();
                return NULL;
@@ -1011,155 +824,65 @@ java_objectheader *_Jv_jni_invokeNative(methodinfo *m, java_objectheader *o,
                resm = m;
        }
 
-       vmargs = MNEW(vm_arg, argcount);
-
-       if (!_Jv_jni_vmargs_from_objectarray(o, resm->parseddesc, vmargs, params)) {
-               MFREE(vmargs, vm_arg, argcount);
-               return NULL;
-       }
-
-       switch (resm->parseddesc->returntype.decltype) {
-       case TYPE_VOID:
-               (void) vm_call_method_vmarg(resm, argcount, vmargs);
-
-               ro = NULL;
-               break;
-
-       case PRIMITIVETYPE_BOOLEAN: {
-               s4 i;
-               java_lang_Boolean *bo;
-
-               i = vm_call_method_int_vmarg(resm, argcount, vmargs);
-
-               ro = builtin_new(class_java_lang_Boolean);
-
-               /* setting the value of the object direct */
-
-               bo = (java_lang_Boolean *) ro;
-               bo->value = i;
-       }
-       break;
-
-       case PRIMITIVETYPE_BYTE: {
-               s4 i;
-               java_lang_Byte *bo;
-
-               i = vm_call_method_int_vmarg(resm, argcount, vmargs);
-
-               ro = builtin_new(class_java_lang_Byte);
-
-               /* setting the value of the object direct */
-
-               bo = (java_lang_Byte *) ro;
-               bo->value = i;
-       }
-       break;
-
-       case PRIMITIVETYPE_CHAR: {
-               s4 i;
-               java_lang_Character *co;
-
-               i = vm_call_method_int_vmarg(resm, argcount, vmargs);
-
-               ro = builtin_new(class_java_lang_Character);
-
-               /* setting the value of the object direct */
-
-               co = (java_lang_Character *) ro;
-               co->value = i;
-       }
-       break;
-
-       case PRIMITIVETYPE_SHORT: {
-               s4 i;
-               java_lang_Short *so;
-
-               i = vm_call_method_int_vmarg(resm, argcount, vmargs);
-
-               ro = builtin_new(class_java_lang_Short);
-
-               /* setting the value of the object direct */
-
-               so = (java_lang_Short *) ro;
-               so->value = i;
-       }
-       break;
-
-       case PRIMITIVETYPE_INT: {
-               s4 i;
-               java_lang_Integer *io;
-
-               i = vm_call_method_int_vmarg(resm, argcount, vmargs);
-
-               ro = builtin_new(class_java_lang_Integer);
-
-               /* setting the value of the object direct */
-
-               io = (java_lang_Integer *) ro;
-               io->value = i;
-       }
-       break;
-
-       case PRIMITIVETYPE_LONG: {
-               s8 l;
-               java_lang_Long *lo;
-
-               l = vm_call_method_long_vmarg(resm, argcount, vmargs);
+       /* mark start of dump memory area */
 
-               ro = builtin_new(class_java_lang_Long);
+       dumpsize = dump_size();
 
-               /* setting the value of the object direct */
-
-               lo = (java_lang_Long *) ro;
-               lo->value = l;
-       }
-       break;
+       /* Fill the argument array from a object-array. */
 
-       case PRIMITIVETYPE_FLOAT: {
-               float f;
-               java_lang_Float *fo;
+       array = vm_array_from_objectarray(resm, o, params);
 
-               f = vm_call_method_float_vmarg(resm, argcount, vmargs);
+       /* The array can be NULL if we don't have any arguments to pass
+          and the architecture does not have any argument registers
+          (e.g. i386).  In that case we additionally check for an
+          exception thrown. */
 
-               ro = builtin_new(class_java_lang_Float);
+       if ((array == NULL) && (exceptions_get_exception() != NULL)) {
+               /* release dump area */
 
-               /* setting the value of the object direct */
+               dump_release(dumpsize);
 
-               fo = (java_lang_Float *) ro;
-               fo->value = f;
+               return NULL;
        }
-       break;
 
-       case PRIMITIVETYPE_DOUBLE: {
-               double d;
-               java_lang_Double *_do;
+       switch (resm->parseddesc->returntype.decltype) {
+       case TYPE_VOID:
+               (void) vm_call_array(resm, array);
+               ro = NULL;
+               break;
 
-               d = vm_call_method_double_vmarg(resm, argcount, vmargs);
+       case PRIMITIVETYPE_BOOLEAN:
+       case PRIMITIVETYPE_BYTE:
+       case PRIMITIVETYPE_CHAR:
+       case PRIMITIVETYPE_SHORT:
+       case PRIMITIVETYPE_INT:
+               value.i = vm_call_int_array(resm, array);
+               ro = primitive_box(resm->parseddesc->returntype.decltype, value);
+               break;
 
-               ro = builtin_new(class_java_lang_Double);
+       case PRIMITIVETYPE_LONG:
+               value.l = vm_call_long_array(resm, array);
+               ro = primitive_box(resm->parseddesc->returntype.decltype, value);
+               break;
 
-               /* setting the value of the object direct */
+       case PRIMITIVETYPE_FLOAT:
+               value.f = vm_call_float_array(resm, array);
+               ro = primitive_box(resm->parseddesc->returntype.decltype, value);
+               break;
 
-               _do = (java_lang_Double *) ro;
-               _do->value = d;
-       }
-       break;
+       case PRIMITIVETYPE_DOUBLE:
+               value.d = vm_call_double_array(resm, array);
+               ro = primitive_box(resm->parseddesc->returntype.decltype, value);
+               break;
 
        case TYPE_ADR:
-               ro = vm_call_method_vmarg(resm, argcount, vmargs);
+               ro = vm_call_array(resm, array);
                break;
 
        default:
-               /* if this happens the exception has already been set by
-                  fill_callblock_from_objectarray */
-
-               MFREE(vmargs, vm_arg, argcount);
-
-               return NULL;
+               vm_abort("_Jv_jni_invokeNative: invalid return type %d", resm->parseddesc->returntype.decltype);
        }
 
-       MFREE(vmargs, vm_arg, argcount);
-
        xptr = exceptions_get_exception();
 
        if (xptr != NULL) {
@@ -1170,6 +893,10 @@ java_objectheader *_Jv_jni_invokeNative(methodinfo *m, java_objectheader *o,
                exceptions_throw_invocationtargetexception(xptr);
        }
 
+       /* release dump area */
+
+       dump_release(dumpsize);
+
        return ro;
 }
 
@@ -1205,19 +932,16 @@ jclass _Jv_JNI_DefineClass(JNIEnv *env, const char *name, jobject loader,
                                                   const jbyte *buf, jsize bufLen)
 {
 #if defined(ENABLE_JAVASE)
-       java_lang_ClassLoader *cl;
-       java_lang_String      *s;
-       java_bytearray        *ba;
-       jclass                 c;
+       utf         *u;
+       classloader *cl;
+       classinfo   *c;
 
-       STATISTICS(jniinvokation());
+       TRACEJNICALLS("_Jv_JNI_DefineClass(env=%p, name=%s, loader=%p, buf=%p, bufLen=%d)", env, name, loader, buf, bufLen);
 
-       cl = (java_lang_ClassLoader *) loader;
-       s  = (java_lang_String *) javastring_new_from_utf_string(name);
-       ba = (java_bytearray *) buf;
+       u  = utf_new_char(name);
+       cl = (classloader *) loader;
 
-       c = (jclass) _Jv_java_lang_ClassLoader_defineClass(cl, s, ba, 0, bufLen,
-                                                                                                          NULL);
+       c = class_define(u, cl, bufLen, (const uint8_t *) buf, NULL);
 
        return (jclass) _Jv_JNI_NewLocalRef(env, (jobject) c);
 #else
@@ -1298,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);
 }
   
  
@@ -1338,11 +1065,11 @@ jboolean _Jv_JNI_IsAssignableFrom(JNIEnv *env, jclass sub, jclass sup)
 
 jint _Jv_JNI_Throw(JNIEnv *env, jthrowable obj)
 {
-       java_objectheader *o;
+       java_handle_t *o;
 
        STATISTICS(jniinvokation());
 
-       o = (java_objectheader *) obj;
+       o = (java_handle_t *) obj;
 
        exceptions_set_exception(o);
 
@@ -1360,13 +1087,15 @@ jint _Jv_JNI_Throw(JNIEnv *env, jthrowable obj)
 
 jint _Jv_JNI_ThrowNew(JNIEnv* env, jclass clazz, const char *msg) 
 {
-       classinfo         *c;
-       java_objectheader *o;
-       java_objectheader *s;
+       classinfo     *c;
+       java_handle_t *o;
+       java_handle_t *s;
 
        STATISTICS(jniinvokation());
 
-       c = (classinfo *) clazz;
+       c = LLNI_classinfo_unwrap(clazz);
+       if (msg == NULL)
+               msg = "";
        s = javastring_new_from_utf_string(msg);
 
        /* instantiate exception object */
@@ -1392,7 +1121,7 @@ jint _Jv_JNI_ThrowNew(JNIEnv* env, jclass clazz, const char *msg)
 
 jthrowable _Jv_JNI_ExceptionOccurred(JNIEnv *env)
 {
-       java_objectheader *o;
+       java_handle_t *o;
 
        STATISTICS(jniinvokation());
 
@@ -1412,8 +1141,8 @@ jthrowable _Jv_JNI_ExceptionOccurred(JNIEnv *env)
 
 void _Jv_JNI_ExceptionDescribe(JNIEnv *env)
 {
-       java_objectheader *o;
-       methodinfo        *m;
+       java_handle_t *o;
+       methodinfo    *m;
 
        STATISTICS(jniinvokation());
 
@@ -1471,7 +1200,7 @@ void _Jv_JNI_FatalError(JNIEnv *env, const char *msg)
 
        /* this seems to be the best way */
 
-       vm_abort(msg);
+       vm_abort("JNI Fatal error: %s", msg);
 }
 
 
@@ -1484,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. */
+       /* add new local reference frame to current table */
 
-       if (capacity > LOCALREFTABLE_CAPACITY)
-               additionalrefs = capacity - LOCALREFTABLE_CAPACITY;
-       else
-               additionalrefs = 0;
-
-       nlrt = GCMNEW(u1, sizeof(localref_table) + additionalrefs * SIZEOF_VOID_P);
-
-       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;
 }
 
@@ -1536,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 */
 
@@ -1591,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) */
 
@@ -1681,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;
@@ -1733,12 +1399,12 @@ 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)) {
                exceptions_throw_instantiationexception(c);
@@ -1747,7 +1413,7 @@ jobject _Jv_JNI_AllocObject(JNIEnv *env, jclass clazz)
                
        o = builtin_new(c);
 
-       return _Jv_JNI_NewLocalRef(env, o);
+       return _Jv_JNI_NewLocalRef(env, (jobject) o);
 }
 
 
@@ -1762,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;
@@ -1783,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);
 }
 
 
@@ -1800,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;
@@ -1818,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);
 }
 
 
@@ -1833,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;
@@ -1853,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);
 }
 
 
@@ -1865,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;
@@ -1913,35 +1585,38 @@ jboolean _Jv_JNI_IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz)
 jmethodID _Jv_JNI_FromReflectedMethod(JNIEnv *env, jobject method)
 {
 #if defined(ENABLE_JAVASE)
-       methodinfo *mi;
-       classinfo  *c;
-       s4          slot;
+       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) mi;
+       return (jmethodID) m;
 #else
        vm_abort("_Jv_JNI_FromReflectedMethod: not implemented in this configuration");
 
@@ -1964,6 +1639,7 @@ jfieldID _Jv_JNI_FromReflectedField(JNIEnv* env, jobject field)
        java_lang_reflect_Field *rf;
        classinfo               *c;
        fieldinfo               *f;
+       int32_t                  slot;
 
        STATISTICS(jniinvokation());
 
@@ -1972,9 +1648,9 @@ 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
@@ -1998,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
 }
 
 
@@ -2047,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))
@@ -2061,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);
@@ -2075,3160 +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;
+/* Accessing Fields of Objects ************************************************/
 
-       o = (java_objectheader *) obj;
-       m = (methodinfo *) methodID;
+/* GetFieldID ******************************************************************
 
-       va_start(ap, methodID);
-       s = _Jv_jni_CallIntMethod(o, o->vftbl, m, ap);
-       va_end(ap);
-
-       return s;
-}
-
-
-jshort _Jv_JNI_CallShortMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
-                                                               va_list args)
-{
-       java_objectheader *o;
-       methodinfo        *m;
-       jshort             s;
-
-       o = (java_objectheader *) obj;
-       m = (methodinfo *) methodID;
-
-       s = _Jv_jni_CallIntMethod(o, o->vftbl, m, args);
-
-       return s;
-}
-
-
-jshort _Jv_JNI_CallShortMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
-                                                               jvalue *args)
-{
-       log_text("JNI-Call: CallShortMethodA: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-
-jint _Jv_JNI_CallIntMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
-{
-       java_objectheader *o;
-       methodinfo        *m;
-       va_list            ap;
-       jint               i;
-
-       o = (java_objectheader *) obj;
-       m = (methodinfo *) methodID;
-
-       va_start(ap, methodID);
-       i = _Jv_jni_CallIntMethod(o, o->vftbl, m, ap);
-       va_end(ap);
-
-       return i;
-}
-
-
-jint _Jv_JNI_CallIntMethodV(JNIEnv *env, jobject obj, jmethodID methodID,
-                                                       va_list args)
-{
-       java_objectheader *o;
-       methodinfo        *m;
-       jint               i;
-
-       o = (java_objectheader *) obj;
-       m = (methodinfo *) methodID;
-
-       i = _Jv_jni_CallIntMethod(o, o->vftbl, m, args);
-
-       return i;
-}
-
-
-jint _Jv_JNI_CallIntMethodA(JNIEnv *env, jobject obj, jmethodID methodID,
-                                                       jvalue *args)
-{
-       log_text("JNI-Call: CallIntMethodA: IMPLEMENT ME!");
-
-       return 0;
-}
-
-
-
-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) 
-{
-       classinfo *c;
-       fieldinfo *f;
-       utf       *uname;
-       utf       *udesc;
-
-       STATISTICS(jniinvokation());
-
-       c = (classinfo *) clazz;
-
-       uname = utf_new_char((char *) name);
-       udesc = utf_new_char((char *) sig);
-
-       f = class_findfield(clazz, uname, udesc); 
-       
-       if (f == NULL)
-               exceptions_throw_nosuchfielderror(c, uname);  
-
-       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)
-{
-       methodinfo *m;
-       jboolean    b;
-
-       m = (methodinfo *) methodID;
-
-       b = _Jv_jni_CallIntMethodA(NULL, NULL, m, args);
-
-       return b;
-}
-
-
-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)
-{
-       methodinfo *m;
-       jbyte       b;
-
-       m = (methodinfo *) methodID;
-
-       b = _Jv_jni_CallIntMethodA(NULL, NULL, m, args);
-
-       return b;
-}
-
-
-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)
-{
-       methodinfo *m;
-       jchar       c;
-
-       m = (methodinfo *) methodID;
-
-       c = _Jv_jni_CallIntMethodA(NULL, NULL, m, args);
-
-       return c;
-}
-
-
-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)
-{
-       methodinfo *m;
-       jshort      s;
-
-       m = (methodinfo *) methodID;
-
-       s = _Jv_jni_CallIntMethodA(NULL, NULL, m, args);
-
-       return s;
-}
-
-
-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)
-{
-       methodinfo *m;
-       jint        i;
-
-       m = (methodinfo *) methodID;
-
-       i = _Jv_jni_CallIntMethodA(NULL, NULL, m, args);
-
-       return i;
-}
-
-
-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)
-{
-       methodinfo *m;
-       jlong       l;
-
-       m = (methodinfo *) methodID;
-
-       l = _Jv_jni_CallLongMethodA(NULL, NULL, m, args);
-
-       return l;
-}
-
-
-
-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)
-{
-       methodinfo *m;
-       jfloat      f;
-
-       m = (methodinfo *) methodID;
-
-       f = _Jv_jni_CallFloatMethodA(NULL, NULL, m, args);
-
-       return f;
-}
-
-
-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)
-{
-       methodinfo *m;
-       jdouble     d;
-
-       m = (methodinfo *) methodID;
-
-       d = _Jv_jni_CallDoubleMethodA(NULL, NULL, m, args);
-
-       return d;
-}
-
-
-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)
-{
-       classinfo *c;
-       fieldinfo *f;
-       utf       *uname;
-       utf       *usig;
-
-       STATISTICS(jniinvokation());
-
-       c = (classinfo *) clazz;
-
-       uname = utf_new_char((char *) name);
-       usig  = utf_new_char((char *) sig);
-
-       f = class_findfield(clazz, uname, usig);
-       
-       if (f == NULL)
-               exceptions_throw_nosuchfielderror(c, uname);
-
-       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;
-}
+   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.
 
+*******************************************************************************/
 
-void _Jv_JNI_SetStaticDoubleField(JNIEnv *env, jclass clazz, jfieldID fieldID,
-                                                                 jdouble value)
+jfieldID _Jv_JNI_GetFieldID(JNIEnv *env, jclass clazz, const char *name,
+                                                       const char *sig)
 {
        classinfo *c;
        fieldinfo *f;
+       utf       *uname;
+       utf       *udesc;
 
        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 = (java_lang_String *) 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;
+       c = LLNI_classinfo_unwrap(clazz);
 
-       STATISTICS(jniinvokation());
+       /* XXX NPE check? */
 
-       if (string == NULL)
-               return "";
+       uname = utf_new_char((char *) name);
+       udesc = utf_new_char((char *) sig);
 
-       if (isCopy)
-               *isCopy = JNI_TRUE;
+       f = class_findfield(c, uname, udesc); 
        
-       u = javastring_toutf((java_objectheader *) 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;
+       if (f == NULL)
+               exceptions_throw_nosuchfielderror(c, uname);  
 
-       return a->size;
+       return (jfieldID) f;
 }
 
 
-/* NewObjectArray **************************************************************
+/* Get<type>Field Routines *****************************************************
 
-   Constructs a new array holding objects in class elementClass. All
-   elements are initially set to initialElement.
+   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().
 
 *******************************************************************************/
 
-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);
+#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)
 
-jobject _Jv_JNI_GetObjectArrayElement(JNIEnv *env, jobjectArray array,
-                                                                         jsize index)
+
+jobject _Jv_JNI_GetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID)
 {
-       java_objectarray *oa;
-       jobject           o;
+       java_handle_t *o;
 
        STATISTICS(jniinvokation());
 
-       oa = (java_objectarray *) array;
+#warning this needs to be fixed
+       o = GET_FIELD(obj, java_handle_t*, fieldID);
 
-       if (index >= oa->header.size) {
-               exceptions_throw_arrayindexoutofboundsexception();
-               return NULL;
-       }
+       return _Jv_JNI_NewLocalRef(env, (jobject) o);
+}
 
-       o = oa->data[index];
 
-       return _Jv_JNI_NewLocalRef(env, o);
+/* 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().
+
+*******************************************************************************/
+
+#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)
 
-void _Jv_JNI_SetObjectArrayElement(JNIEnv *env, jobjectArray array,
-                                                                  jsize index, jobject val)
-{
-       java_objectarray  *oa;
-       java_objectheader *o;
 
+void _Jv_JNI_SetObjectField(JNIEnv *env, jobject obj, jfieldID fieldID,
+                                                       jobject value)
+{
        STATISTICS(jniinvokation());
 
-       oa = (java_objectarray *) array;
-       o  = (java_objectheader *) val;
+#warning this needs to be fixed
+       SET_FIELD(obj, java_handle_t*, fieldID, value);
+}
 
-       if (index >= oa->header.size) {
-               exceptions_throw_arrayindexoutofboundsexception();
-               return;
-       }
 
-       /* check if the class of value is a subclass of the element class
-          of the array */
+/* Calling Static Methods *****************************************************/
 
-       if (!builtin_canstore(oa, o))
-               return;
+/* GetStaticMethodID ***********************************************************
 
-       oa->data[index] = val;
-}
+   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.
 
+*******************************************************************************/
 
-jbooleanArray _Jv_JNI_NewBooleanArray(JNIEnv *env, jsize len)
+jmethodID _Jv_JNI_GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name,
+                                                                       const char *sig)
 {
-       java_booleanarray *ba;
+       classinfo  *c;
+       utf        *uname;
+       utf        *udesc;
+       methodinfo *m;
 
        STATISTICS(jniinvokation());
 
-       if (len < 0) {
-               exceptions_throw_negativearraysizeexception();
+       c = LLNI_classinfo_unwrap(clazz);
+
+       if (!c)
                return NULL;
-       }
 
-       ba = builtin_newarray_boolean(len);
+       if (!(c->state & CLASS_INITIALIZED))
+               if (!initialize_class(c))
+                       return NULL;
 
-       return (jbooleanArray) _Jv_JNI_NewLocalRef(env, (jobject) ba);
-}
+       /* try to get the static method of the class */
 
+       uname = utf_new_char((char *) name);
+       udesc = utf_new_char((char *) sig);
 
-jbyteArray _Jv_JNI_NewByteArray(JNIEnv *env, jsize len)
-{
-       java_bytearray *ba;
+       m = class_resolvemethod(c, uname, udesc);
 
-       STATISTICS(jniinvokation());
+       if ((m == NULL) || !(m->flags & ACC_STATIC)) {
+               exceptions_throw_nosuchmethoderror(c, uname, udesc);
 
-       if (len < 0) {
-               exceptions_throw_negativearraysizeexception();
                return NULL;
        }
 
-       ba = builtin_newarray_byte(len);
-
-       return (jbyteArray) _Jv_JNI_NewLocalRef(env, (jobject) ba);
+       return (jmethodID) m;
 }
 
 
-jcharArray _Jv_JNI_NewCharArray(JNIEnv *env, jsize len)
-{
-       java_chararray *ca;
+#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)
 
-       STATISTICS(jniinvokation());
 
-       if (len < 0) {
-               exceptions_throw_negativearraysizeexception();
-               return NULL;
-       }
+jobject _Jv_JNI_CallStaticObjectMethod(JNIEnv *env, jclass clazz,
+                                                                          jmethodID methodID, ...)
+{
+       methodinfo    *m;
+       java_handle_t *o;
+       va_list        ap;
 
-       ca = builtin_newarray_char(len);
+       m = (methodinfo *) methodID;
+
+       va_start(ap, methodID);
+       o = _Jv_jni_CallObjectMethod(NULL, NULL, m, ap);
+       va_end(ap);
 
-       return (jcharArray) _Jv_JNI_NewLocalRef(env, (jobject) ca);
+       return _Jv_JNI_NewLocalRef(env, (jobject) o);
 }
 
 
-jshortArray _Jv_JNI_NewShortArray(JNIEnv *env, jsize len)
+jobject _Jv_JNI_CallStaticObjectMethodV(JNIEnv *env, jclass clazz,
+                                                                               jmethodID methodID, va_list args)
 {
-       java_shortarray *sa;
-
-       STATISTICS(jniinvokation());
+       methodinfo    *m;
+       java_handle_t *o;
 
-       if (len < 0) {
-               exceptions_throw_negativearraysizeexception();
-               return NULL;
-       }
+       m = (methodinfo *) methodID;
 
-       sa = builtin_newarray_short(len);
+       o = _Jv_jni_CallObjectMethod(NULL, NULL, m, args);
 
-       return (jshortArray) _Jv_JNI_NewLocalRef(env, (jobject) sa);
+       return _Jv_JNI_NewLocalRef(env, (jobject) o);
 }
 
 
-jintArray _Jv_JNI_NewIntArray(JNIEnv *env, jsize len)
+jobject _Jv_JNI_CallStaticObjectMethodA(JNIEnv *env, jclass clazz,
+                                                                               jmethodID methodID, const jvalue *args)
 {
-       java_intarray *ia;
-
-       STATISTICS(jniinvokation());
+       methodinfo    *m;
+       java_handle_t *o;
 
-       if (len < 0) {
-               exceptions_throw_negativearraysizeexception();
-               return NULL;
-       }
+       m = (methodinfo *) methodID;
 
-       ia = builtin_newarray_int(len);
+       o = _Jv_jni_CallObjectMethodA(NULL, NULL, m, args);
 
-       return (jintArray) _Jv_JNI_NewLocalRef(env, (jobject) ia);
+       return _Jv_JNI_NewLocalRef(env, (jobject) o);
 }
 
 
-jlongArray _Jv_JNI_NewLongArray(JNIEnv *env, jsize len)
+void _Jv_JNI_CallStaticVoidMethod(JNIEnv *env, jclass clazz,
+                                                                 jmethodID methodID, ...)
 {
-       java_longarray *la;
-
-       STATISTICS(jniinvokation());
-
-       if (len < 0) {
-               exceptions_throw_negativearraysizeexception();
-               return NULL;
-       }
+       methodinfo *m;
+       va_list     ap;
 
-       la = builtin_newarray_long(len);
+       m = (methodinfo *) methodID;
 
-       return (jlongArray) _Jv_JNI_NewLocalRef(env, (jobject) la);
+       va_start(ap, methodID);
+       _Jv_jni_CallVoidMethod(NULL, NULL, m, ap);
+       va_end(ap);
 }
 
 
-jfloatArray _Jv_JNI_NewFloatArray(JNIEnv *env, jsize len)
+void _Jv_JNI_CallStaticVoidMethodV(JNIEnv *env, jclass clazz,
+                                                                  jmethodID methodID, va_list args)
 {
-       java_floatarray *fa;
-
-       STATISTICS(jniinvokation());
-
-       if (len < 0) {
-               exceptions_throw_negativearraysizeexception();
-               return NULL;
-       }
+       methodinfo *m;
 
-       fa = builtin_newarray_float(len);
+       m = (methodinfo *) methodID;
 
-       return (jfloatArray) _Jv_JNI_NewLocalRef(env, (jobject) fa);
+       _Jv_jni_CallVoidMethod(NULL, NULL, m, args);
 }
 
 
-jdoubleArray _Jv_JNI_NewDoubleArray(JNIEnv *env, jsize len)
+void _Jv_JNI_CallStaticVoidMethodA(JNIEnv *env, jclass clazz,
+                                                                  jmethodID methodID, const jvalue * args)
 {
-       java_doublearray *da;
-
-       STATISTICS(jniinvokation());
-
-       if (len < 0) {
-               exceptions_throw_negativearraysizeexception();
-               return NULL;
-       }
+       methodinfo *m;
 
-       da = builtin_newarray_double(len);
+       m = (methodinfo *) methodID;
 
-       return (jdoubleArray) _Jv_JNI_NewLocalRef(env, (jobject) da);
+       _Jv_jni_CallVoidMethodA(NULL, NULL, m, args);
 }
 
 
-/* Get<PrimitiveType>ArrayElements *********************************************
+/* Accessing Static Fields ****************************************************/
 
-   A family of functions that returns the body of the primitive array.
+/* 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.
 
 *******************************************************************************/
 
-jboolean *_Jv_JNI_GetBooleanArrayElements(JNIEnv *env, jbooleanArray array,
-                                                                                 jboolean *isCopy)
+jfieldID _Jv_JNI_GetStaticFieldID(JNIEnv *env, jclass clazz, const char *name,
+                                                                 const char *sig)
 {
-       java_booleanarray *ba;
+       classinfo *c;
+       fieldinfo *f;
+       utf       *uname;
+       utf       *usig;
 
        STATISTICS(jniinvokation());
 
-       ba = (java_booleanarray *) array;
+       c = LLNI_classinfo_unwrap(clazz);
 
-       if (isCopy)
-               *isCopy = JNI_FALSE;
+       uname = utf_new_char((char *) name);
+       usig  = utf_new_char((char *) sig);
 
-       return ba->data;
-}
+       f = class_findfield(c, uname, usig);
+       
+       if (f == NULL)
+               exceptions_throw_nosuchfielderror(c, uname);
 
+       return (jfieldID) f;
+}
 
-jbyte *_Jv_JNI_GetByteArrayElements(JNIEnv *env, jbyteArray array,
-                                                                       jboolean *isCopy)
-{
-       java_bytearray *ba;
 
-       STATISTICS(jniinvokation());
+/* GetStatic<type>Field ********************************************************
 
-       ba = (java_bytearray *) array;
+   This family of accessor routines returns the value of a static
+   field of an object.
 
-       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)
 
 
-jchar *_Jv_JNI_GetCharArrayElements(JNIEnv *env, jcharArray array,
-                                                                       jboolean *isCopy)
+jobject _Jv_JNI_GetStaticObjectField(JNIEnv *env, jclass clazz,
+                                                                        jfieldID fieldID)
 {
-       java_chararray *ca;
+       classinfo *c;
+       fieldinfo *f;
 
        STATISTICS(jniinvokation());
 
-       ca = (java_chararray *) 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 ca->data;
+       return _Jv_JNI_NewLocalRef(env, f->value->a);
 }
 
 
-jshort *_Jv_JNI_GetShortArrayElements(JNIEnv *env, jshortArray array,
-                                                                         jboolean *isCopy)
-{
-       java_shortarray *sa;
-
-       STATISTICS(jniinvokation());
+/*  SetStatic<type>Field *******************************************************
 
-       sa = (java_shortarray *) array;
+       This family of accessor routines sets the value of a static field
+       of an object.
 
-       if (isCopy)
-               *isCopy = JNI_FALSE;
+*******************************************************************************/
 
-       return sa->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)
 
 
-jint *_Jv_JNI_GetIntArrayElements(JNIEnv *env, jintArray array,
-                                                                 jboolean *isCopy)
+void _Jv_JNI_SetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID,
+                                                                 jobject value)
 {
-       java_intarray *ia;
+       classinfo *c;
+       fieldinfo *f;
 
        STATISTICS(jniinvokation());
 
-       ia = (java_intarray *) 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 ia->data;
+       f->value->a = value;
 }
 
 
-jlong *_Jv_JNI_GetLongArrayElements(JNIEnv *env, jlongArray array,
-                                                                       jboolean *isCopy)
-{
-       java_longarray *la;
-
-       STATISTICS(jniinvokation());
-
-       la = (java_longarray *) array;
-
-       if (isCopy)
-               *isCopy = JNI_FALSE;
+/* String Operations **********************************************************/
 
-       /* We cast this one to prevent a compiler warning on 64-bit
-          systems since GNU Classpath typedef jlong to long long. */
+/* NewString *******************************************************************
 
-       return (jlong *) la->data;
-}
+   Create new java.lang.String object from an array of Unicode
+   characters.
 
+*******************************************************************************/
 
-jfloat *_Jv_JNI_GetFloatArrayElements(JNIEnv *env, jfloatArray array,
-                                                                         jboolean *isCopy)
+jstring _Jv_JNI_NewString(JNIEnv *env, const jchar *buf, jsize len)
 {
-       java_floatarray *fa;
+       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);
+
+       /* javastring or characterarray could not be created */
+       if ((a == NULL) || (s == NULL))
+               return NULL;
 
-       fa = (java_floatarray *) array;
+       /* copy text */
+       for (i = 0; i < len; i++)
+               LLNI_array_direct(a, i) = buf[i];
 
-       if (isCopy)
-               *isCopy = JNI_FALSE;
+       LLNI_field_set_ref(s, value , a);
+       LLNI_field_set_val(s, offset, 0);
+       LLNI_field_set_val(s, count , len);
 
-       return fa->data;
+       return (jstring) _Jv_JNI_NewLocalRef(env, (jobject) s);
 }
 
 
-jdouble *_Jv_JNI_GetDoubleArrayElements(JNIEnv *env, jdoubleArray array,
-                                                                               jboolean *isCopy)
-{
-       java_doublearray *da;
+static jchar emptyStringJ[]={0,0};
 
-       STATISTICS(jniinvokation());
+/* GetStringLength *************************************************************
 
-       da = (java_doublearray *) array;
+   Returns the length (the count of Unicode characters) of a Java
+   string.
 
-       if (isCopy)
-               *isCopy = JNI_FALSE;
+*******************************************************************************/
 
-       return da->data;
-}
+jsize _Jv_JNI_GetStringLength(JNIEnv *env, jstring str)
+{
+       java_lang_String *s;
+       jsize             len;
 
+       TRACEJNICALLS("_Jv_JNI_GetStringLength(env=%p, str=%p)", env, str);
 
-/* Release<PrimitiveType>ArrayElements *****************************************
+       s = (java_lang_String *) str;
 
-   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.
+       LLNI_field_get_val(s, count, len);
 
-*******************************************************************************/
+       return len;
+}
 
-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);
 
+       /* copy text */
 
-void _Jv_JNI_ReleaseCharArrayElements(JNIEnv *env, jcharArray array,
-                                                                         jchar *elems, jint mode)
-{
-       java_chararray *ca;
+       for (i = 0; i < count; i++)
+               stringbuffer[i] = LLNI_array_direct(a, offset + i);
+       
+       /* terminate string */
 
-       STATISTICS(jniinvokation());
+       stringbuffer[i] = '\0';
 
-       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;
-               }
-       }
+       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 *********************************************
 
-       la = (java_longarray *) array;
+   A family of functions that returns the body of the primitive array.
 
-       if ((start < 0) || (len < 0) || (start + len > la->header.size))
-               exceptions_throw_arrayindexoutofboundsexception();
-       else
-               MCOPY(&la->data[start], buf, s8, len);
-}
+*******************************************************************************/
 
+#define JNI_GET_ARRAY_ELEMENTS(name, type, intern)                     \
+type *_Jv_JNI_Get##name##ArrayElements(JNIEnv *env, type##Array array, \
+                                                                                jboolean *isCopy)             \
+{                                                                      \
+       java_handle_##intern##array_t *a;                                  \
+                                                                       \
+       STATISTICS(jniinvokation());                                       \
+                                                                       \
+       a = (java_handle_##intern##array_t *) array;                       \
+                                                                       \
+       if (isCopy)                                                        \
+               *isCopy = JNI_FALSE;                                           \
+                                                                       \
+       return LLNI_array_data(a);                                         \
+}
+
+JNI_GET_ARRAY_ELEMENTS(Boolean, jboolean, boolean)
+JNI_GET_ARRAY_ELEMENTS(Byte,    jbyte,    byte)
+JNI_GET_ARRAY_ELEMENTS(Char,    jchar,    char)
+JNI_GET_ARRAY_ELEMENTS(Short,   jshort,   short)
+JNI_GET_ARRAY_ELEMENTS(Int,     jint,     int)
+JNI_GET_ARRAY_ELEMENTS(Long,    jlong,    long)
+JNI_GET_ARRAY_ELEMENTS(Float,   jfloat,   float)
+JNI_GET_ARRAY_ELEMENTS(Double,  jdouble,  double)
 
-void _Jv_JNI_SetFloatArrayRegion(JNIEnv *env, jfloatArray array, jsize start,
-                                                                jsize len, jfloat *buf)
-{
-       java_floatarray *fa;
 
-       STATISTICS(jniinvokation());
+/* Release<PrimitiveType>ArrayElements *****************************************
 
-       fa = (java_floatarray *) array;
+   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.
 
-       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;
 
-       STATISTICS(jniinvokation());
+/*  Get<PrimitiveType>ArrayRegion **********************************************
 
-       da = (java_doublearray *) array;
+       A family of functions that copies a region of a primitive array
+       into a buffer.
 
-       if ((start < 0) || (len < 0) || (start + len > da->header.size))
-               exceptions_throw_arrayindexoutofboundsexception();
-       else
-               MCOPY(&da->data[start], buf, double, len);
-}
+*******************************************************************************/
+
+#define JNI_GET_ARRAY_REGION(name, type, intern, intern2)               \
+void _Jv_JNI_Get##name##ArrayRegion(JNIEnv *env, type##Array array,     \
+                                                                       jsize start, jsize len, type *buf)  \
+{                                                                       \
+       java_handle_##intern##array_t *a;                                   \
+                                                                        \
+       STATISTICS(jniinvokation());                                        \
+                                                                        \
+       a = (java_handle_##intern##array_t *) array;                        \
+                                                                        \
+       if ((start < 0) || (len < 0) || (start + len > LLNI_array_size(a))) \
+               exceptions_throw_arrayindexoutofboundsexception();              \
+       else                                                                \
+               MCOPY(buf, &LLNI_array_direct(a, start), intern2, len);         \
+}
+
+JNI_GET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
+JNI_GET_ARRAY_REGION(Byte,    jbyte,    byte,    s1)
+JNI_GET_ARRAY_REGION(Char,    jchar,    char,    u2)
+JNI_GET_ARRAY_REGION(Short,   jshort,   short,   s2)
+JNI_GET_ARRAY_REGION(Int,     jint,     int,     s4)
+JNI_GET_ARRAY_REGION(Long,    jlong,    long,    s8)
+JNI_GET_ARRAY_REGION(Float,   jfloat,   float,   float)
+JNI_GET_ARRAY_REGION(Double,  jdouble,  double,  double)
+
+
+/*  Set<PrimitiveType>ArrayRegion **********************************************
+
+       A family of functions that copies back a region of a primitive
+       array from a buffer.
+
+*******************************************************************************/
+
+#define JNI_SET_ARRAY_REGION(name, type, intern, intern2)                    \
+void _Jv_JNI_Set##name##ArrayRegion(JNIEnv *env, type##Array array,          \
+                                                                       jsize start, jsize len, const type *buf) \
+{                                                                            \
+       java_handle_##intern##array_t *a;                                        \
+                                                                             \
+       STATISTICS(jniinvokation());                                             \
+                                                                             \
+       a = (java_handle_##intern##array_t *) array;                             \
+                                                                             \
+       if ((start < 0) || (len < 0) || (start + len > LLNI_array_size(a)))      \
+               exceptions_throw_arrayindexoutofboundsexception();                   \
+       else                                                                     \
+               MCOPY(&LLNI_array_direct(a, start), buf, intern2, len);              \
+}
+
+JNI_SET_ARRAY_REGION(Boolean, jboolean, boolean, u1)
+JNI_SET_ARRAY_REGION(Byte,    jbyte,    byte,    s1)
+JNI_SET_ARRAY_REGION(Char,    jchar,    char,    u2)
+JNI_SET_ARRAY_REGION(Short,   jshort,   short,   s2)
+JNI_SET_ARRAY_REGION(Int,     jint,     int,     s4)
+JNI_SET_ARRAY_REGION(Long,    jlong,    long,    s8)
+JNI_SET_ARRAY_REGION(Float,   jfloat,   float,   float)
+JNI_SET_ARRAY_REGION(Double,  jdouble,  double,  double)
 
 
 /* Registering Native Methods *************************************************/
@@ -5246,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;
 }
 
@@ -5362,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);
+
+       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);
 
-       log_text("JNI-Call: GetStringUTFRegion: IMPLEMENT ME!");
+       buf[i] = '\0';
 }
 
 
@@ -5398,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;
 }
@@ -5484,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 */
@@ -5498,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++;
@@ -5515,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 */
@@ -5546,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 */
@@ -5564,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--;
@@ -5606,7 +3533,7 @@ void _Jv_JNI_DeleteGlobalRef(JNIEnv* env, jobject globalRef)
 
 jboolean _Jv_JNI_ExceptionCheck(JNIEnv *env)
 {
-       java_objectheader *o;
+       java_handle_t *o;
 
        STATISTICS(jniinvokation());
 
@@ -5628,8 +3555,9 @@ jboolean _Jv_JNI_ExceptionCheck(JNIEnv *env)
 
 jobject _Jv_JNI_NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
 {
-#if defined(ENABLE_JAVASE)
-       java_objectheader       *nbuf;
+#if defined(ENABLE_JAVASE) && defined(WITH_CLASSPATH_GNU)
+       java_handle_t           *nbuf;
+
 # if SIZEOF_VOID_P == 8
        gnu_classpath_Pointer64 *paddress;
 # else
@@ -5651,7 +3579,7 @@ jobject _Jv_JNI_NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
 
        /* 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 */
 
@@ -5681,13 +3609,14 @@ jobject _Jv_JNI_NewDirectByteBuffer(JNIEnv *env, void *address, jlong capacity)
 
 void *_Jv_JNI_GetDirectBufferAddress(JNIEnv *env, jobject buf)
 {
-#if defined(ENABLE_JAVASE)
+#if defined(ENABLE_JAVASE) && defined(WITH_CLASSPATH_GNU)
        java_nio_DirectByteBufferImpl *nbuf;
 # if SIZEOF_VOID_P == 8
-       gnu_classpath_Pointer64       *address;
+       gnu_classpath_Pointer64       *paddress;
 # else
-       gnu_classpath_Pointer32       *address;
+       gnu_classpath_Pointer32       *paddress;
 # endif
+       void                          *address;
 
        STATISTICS(jniinvokation());
 
@@ -5697,15 +3626,20 @@ void *_Jv_JNI_GetDirectBufferAddress(JNIEnv *env, jobject buf)
        nbuf = (java_nio_DirectByteBufferImpl *) buf;
 
 # if SIZEOF_VOID_P == 8
-       address = (gnu_classpath_Pointer64 *) nbuf->address;
+       LLNI_field_get_ref(nbuf, address, paddress);
+       /* this was the cast to avaoid warning: (gnu_classpath_Pointer64 *) nbuf->address; */
 # else
-       address = (gnu_classpath_Pointer32 *) nbuf->address;
+       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");
 
@@ -5725,17 +3659,23 @@ void *_Jv_JNI_GetDirectBufferAddress(JNIEnv *env, jobject buf)
 
 jlong _Jv_JNI_GetDirectBufferCapacity(JNIEnv* env, jobject buf)
 {
-#if defined(ENABLE_JAVASE)
+#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 (jlong) nbuf->cap;
+       return capacity;
 #else
        vm_abort("_Jv_JNI_GetDirectBufferCapacity: not implemented in this configuration");
 
@@ -5797,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
@@ -5927,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,
@@ -5942,7 +3882,7 @@ const struct JNIInvokeInterface _Jv_JNIInvokeInterface = {
 
 /* JNI function table *********************************************************/
 
-struct JNINativeInterface _Jv_JNINativeInterface = {
+struct JNINativeInterface_ _Jv_JNINativeInterface = {
        NULL,
        NULL,
        NULL,
@@ -6260,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;
 }
 
 
@@ -6275,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))