* src/vm/vm.c (vm_call_method_intern): Removed.
[cacao.git] / src / native / jni.c
index 100565efbe0f0eab526003ba7e832befb0ebe03b..0e58a9a6176e855198b40ae4ffa9a9ad486d8ac6 100644 (file)
@@ -32,7 +32,7 @@
             Christian Thalinger
                        Edwin Steiner
 
-   $Id: jni.c 4530 2006-02-21 09:11:53Z twisti $
+   $Id: jni.c 4559 2006-03-05 23:24:50Z twisti $
 
 */
 
@@ -111,8 +111,6 @@ static JavaVM ptr_jvm = (JavaVM) &JNI_JavaVMTable;
 void *ptr_env = (void*) &JNI_JNIEnvTable;
 
 
-#define PTR_TO_ITEM(ptr)   ((u8)(size_t)(ptr))
-
 /* global variables ***********************************************************/
 
 /* global reference table *****************************************************/
@@ -233,84 +231,15 @@ bool jni_init(void)
 }
 
 
-static void fill_callblock_from_vargs(void *obj, methoddesc *descr,
-                                                                         jni_callblock blk[], va_list data,
-                                                                         s4 rettype)
-{
-       typedesc *paramtypes;
-       s4        i;
-
-       paramtypes = descr->paramtypes;
-
-       /* if method is non-static fill first block and skip `this' pointer */
-
-       i = 0;
-
-       if (obj != NULL) {
-               /* the `this' pointer */
-               blk[0].itemtype = TYPE_ADR;
-               blk[0].item = PTR_TO_ITEM(obj);
-
-               paramtypes++;
-               i++;
-       } 
-
-       for (; i < descr->paramcount; i++, paramtypes++) {
-               switch (paramtypes->decltype) {
-               /* primitive types */
-               case PRIMITIVETYPE_BYTE:
-               case PRIMITIVETYPE_CHAR:
-               case PRIMITIVETYPE_SHORT: 
-               case PRIMITIVETYPE_BOOLEAN: 
-                       blk[i].itemtype = TYPE_INT;
-                       blk[i].item = (s8) va_arg(data, s4);
-                       break;
-
-               case PRIMITIVETYPE_INT:
-                       blk[i].itemtype = TYPE_INT;
-                       blk[i].item = (s8) va_arg(data, s4);
-                       break;
-
-               case PRIMITIVETYPE_LONG:
-                       blk[i].itemtype = TYPE_LNG;
-                       blk[i].item = (s8) va_arg(data, s8);
-                       break;
-
-               case PRIMITIVETYPE_FLOAT:
-                       blk[i].itemtype = TYPE_FLT;
-#if defined(__ALPHA__)
-                       /* this keeps the assembler function much simpler */
-
-                       *((jdouble *) (&blk[i].item)) = (jdouble) va_arg(data, jdouble);
-#else
-                       *((jfloat *) (&blk[i].item)) = (jfloat) va_arg(data, jdouble);
-#endif
-                       break;
-
-               case PRIMITIVETYPE_DOUBLE:
-                       blk[i].itemtype = TYPE_DBL;
-                       *((jdouble *) (&blk[i].item)) = (jdouble) va_arg(data, jdouble);
-                       break;
-
-               case TYPE_ADR: 
-                       blk[i].itemtype = TYPE_ADR;
-                       blk[i].item = PTR_TO_ITEM(va_arg(data, void*));
-                       break;
-               }
-       }
-
-       /* The standard doesn't say anything about return value checking,
-          but it appears to be useful. */
+/* _Jv_jni_vmargs_from_objectarray *********************************************
 
-       if (rettype != descr->returntype.decltype)
-               log_text("\n====\nWarning call*Method called for function with wrong return type\n====");
-}
+   XXX
 
+*******************************************************************************/
 
-/* XXX it could be considered if we should do typechecking here in the future */
-
-static bool fill_callblock_from_objectarray(void *obj, methoddesc *descr,
-                                                                                       jni_callblock blk[],
+static bool _Jv_jni_vmargs_from_objectarray(java_objectheader *o,
+                                                                                       methoddesc *descr,
+                                                                                       vm_arg *vmargs,
                                                                                        java_objectarray *params)
 {
        java_objectheader *param;
@@ -327,10 +256,10 @@ static bool fill_callblock_from_objectarray(void *obj, methoddesc *descr,
 
        i = 0;
 
-       if (obj) {
+       if (o != NULL) {
                /* this pointer */
-               blk[0].itemtype = TYPE_ADR;
-               blk[0].item = PTR_TO_ITEM(obj);
+               vmargs[0].type = TYPE_ADR;
+               vmargs[0].data = (u8) (ptrint) o;
 
                paramtypes++;
                paramcount--;
@@ -345,11 +274,12 @@ static bool fill_callblock_from_objectarray(void *obj, methoddesc *descr,
                case TYPE_FLOAT:
                case TYPE_DOUBLE:
                        param = params->data[j];
-                       if (!param)
+
+                       if (param == NULL)
                                goto illegal_arg;
 
                        /* internally used data type */
-                       blk[i].itemtype = paramtypes->type;
+                       vmargs[i].type = paramtypes->type;
 
                        /* convert the value according to its declared type */
 
@@ -358,77 +288,77 @@ static bool fill_callblock_from_objectarray(void *obj, methoddesc *descr,
                        switch (paramtypes->decltype) {
                        case PRIMITIVETYPE_BOOLEAN:
                                if (c == primitivetype_table[paramtypes->decltype].class_wrap)
-                                       blk[i].item = (s8) ((java_lang_Boolean *) param)->value;
+                                       vmargs[i].data = (s8) ((java_lang_Boolean *) param)->value;
                                else
                                        goto illegal_arg;
                                break;
 
                        case PRIMITIVETYPE_BYTE:
                                if (c == primitivetype_table[paramtypes->decltype].class_wrap)
-                                       blk[i].item = (s8) ((java_lang_Byte *) param)->value;
+                                       vmargs[i].data = (s8) ((java_lang_Byte *) param)->value;
                                else
                                        goto illegal_arg;
                                break;
 
                        case PRIMITIVETYPE_CHAR:
                                if (c == primitivetype_table[paramtypes->decltype].class_wrap)
-                                       blk[i].item = (s8) ((java_lang_Character *) param)->value;
+                                       vmargs[i].data = (s8) ((java_lang_Character *) param)->value;
                                else
                                        goto illegal_arg;
                                break;
 
                        case PRIMITIVETYPE_SHORT:
                                if (c == primitivetype_table[paramtypes->decltype].class_wrap)
-                                       blk[i].item = (s8) ((java_lang_Short *) param)->value;
+                                       vmargs[i].data = (s8) ((java_lang_Short *) param)->value;
                                else if (c == primitivetype_table[PRIMITIVETYPE_BYTE].class_wrap)
-                                       blk[i].item = (s8) ((java_lang_Byte *) param)->value;
+                                       vmargs[i].data = (s8) ((java_lang_Byte *) param)->value;
                                else
                                        goto illegal_arg;
                                break;
 
                        case PRIMITIVETYPE_INT:
                                if (c == primitivetype_table[paramtypes->decltype].class_wrap)
-                                       blk[i].item = (s8) ((java_lang_Integer *) param)->value;
+                                       vmargs[i].data = (s8) ((java_lang_Integer *) param)->value;
                                else if (c == primitivetype_table[PRIMITIVETYPE_SHORT].class_wrap)
-                                       blk[i].item = (s8) ((java_lang_Short *) param)->value;
+                                       vmargs[i].data = (s8) ((java_lang_Short *) param)->value;
                                else if (c == primitivetype_table[PRIMITIVETYPE_BYTE].class_wrap)
-                                       blk[i].item = (s8) ((java_lang_Byte *) param)->value;
+                                       vmargs[i].data = (s8) ((java_lang_Byte *) param)->value;
                                else
                                        goto illegal_arg;
                                break;
 
                        case PRIMITIVETYPE_LONG:
                                if (c == primitivetype_table[paramtypes->decltype].class_wrap)
-                                       blk[i].item = (s8) ((java_lang_Long *) param)->value;
+                                       vmargs[i].data = (s8) ((java_lang_Long *) param)->value;
                                else if (c == primitivetype_table[PRIMITIVETYPE_INT].class_wrap)
-                                       blk[i].item = (s8) ((java_lang_Integer *) param)->value;
+                                       vmargs[i].data = (s8) ((java_lang_Integer *) param)->value;
                                else if (c == primitivetype_table[PRIMITIVETYPE_SHORT].class_wrap)
-                                       blk[i].item = (s8) ((java_lang_Short *) param)->value;
+                                       vmargs[i].data = (s8) ((java_lang_Short *) param)->value;
                                else if (c == primitivetype_table[PRIMITIVETYPE_BYTE].class_wrap)
-                                       blk[i].item = (s8) ((java_lang_Byte *) param)->value;
+                                       vmargs[i].data = (s8) ((java_lang_Byte *) param)->value;
                                else
                                        goto illegal_arg;
                                break;
 
                        case PRIMITIVETYPE_FLOAT:
                                if (c == primitivetype_table[paramtypes->decltype].class_wrap)
-                                       *((jfloat *) (&blk[i].item)) = (jfloat) ((java_lang_Float *) param)->value;
+                                       *((jfloat *) (&vmargs[i].data)) = (jfloat) ((java_lang_Float *) param)->value;
                                else
                                        goto illegal_arg;
                                break;
 
                        case PRIMITIVETYPE_DOUBLE:
                                if (c == primitivetype_table[paramtypes->decltype].class_wrap)
-                                       *((jdouble *) (&blk[i].item)) = (jdouble) ((java_lang_Double *) param)->value;
+                                       *((jdouble *) (&vmargs[i].data)) = (jdouble) ((java_lang_Double *) param)->value;
                                else if (c == primitivetype_table[PRIMITIVETYPE_FLOAT].class_wrap)
-                                       *((jfloat *) (&blk[i].item)) = (jfloat) ((java_lang_Float *) param)->value;
+                                       *((jfloat *) (&vmargs[i].data)) = (jfloat) ((java_lang_Float *) param)->value;
                                else
                                        goto illegal_arg;
                                break;
 
                        default:
                                goto illegal_arg;
-                       } /* end declared type switch */
+                       }
                        break;
                
                        case TYPE_ADDRESS:
@@ -445,15 +375,14 @@ static bool fill_callblock_from_objectarray(void *obj, methoddesc *descr,
                                                        goto illegal_arg;
                                        }
                                }
-                               blk[i].itemtype = TYPE_ADR;
-                               blk[i].item = PTR_TO_ITEM(params->data[j]);
-                               break;                  
+                               vmargs[i].type = TYPE_ADR;
+                               vmargs[i].data = (u8) (ptrint) params->data[j];
+                               break;
 
                        default:
                                goto illegal_arg;
-               } /* end param type switch */
-
-       } /* end param loop */
+               }
+       }
 
 /*     if (rettype) */
 /*             *rettype = descr->returntype.decltype; */
@@ -477,10 +406,7 @@ static java_objectheader *_Jv_jni_CallObjectMethod(java_objectheader *o,
                                                                                                   methodinfo *m, va_list ap)
 {
        methodinfo        *resm;
-       s4                 paramcount;
-       jni_callblock     *blk;
-       java_objectheader *ret;
-       s4                 dumpsize;
+       java_objectheader *ro;
 
        STATISTICS(jniinvokation());
 
@@ -508,27 +434,58 @@ static java_objectheader *_Jv_jni_CallObjectMethod(java_objectheader *o,
                resm = method_vftbl_lookup(vftbl, m);
        }
 
-       /* mark start of dump memory area */
+       STATISTICS(jnicallXmethodnvokation());
+
+       ro = vm_call_method_valist(resm, o, ap);
 
-       dumpsize = dump_size();
+       return ro;
+}
 
-       paramcount = resm->parseddesc->paramcount;
 
-       blk = DMNEW(jni_callblock, paramcount);
+/* _Jv_jni_CallObjectMethodA ***************************************************
 
-       fill_callblock_from_vargs(o, resm->parseddesc, blk, ap, TYPE_ADR);
+   Internal function to call Java Object methods.
 
-       STATISTICS(jnicallXmethodnvokation());
+*******************************************************************************/
 
-       ASM_CALLJAVAFUNCTION2_ADR(ret, resm, paramcount,
-                                                         paramcount * sizeof(jni_callblock),
-                                                         blk);
+static java_objectheader *_Jv_jni_CallObjectMethodA(java_objectheader *o,
+                                                                                                       vftbl_t *vftbl,
+                                                                                                       methodinfo *m, jvalue *args)
+{
+       methodinfo        *resm;
+       java_objectheader *ro;
+
+       STATISTICS(jniinvokation());
+
+       if (m == NULL) {
+               exceptions_throw_nullpointerexception();
+               return NULL;
+       }
+
+       /* Class initialization is done by the JIT compiler.  This is ok
+          since a static method always belongs to the declaring class. */
+
+       if (m->flags & ACC_STATIC) {
+               /* For static methods we reset the object. */
+
+               if (o != NULL)
+                       o = NULL;
+
+               /* for convenience */
+
+               resm = m;
+
+       } else {
+               /* For instance methods we make a virtual function table lookup. */
 
-       /* release dump area */
+               resm = method_vftbl_lookup(vftbl, m);
+       }
 
-       dump_release(dumpsize);
+       STATISTICS(jnicallXmethodnvokation());
 
-       return ret;
+       ro = vm_call_method_jvalue(resm, o, args);
+
+       return ro;
 }
 
 
@@ -540,13 +497,10 @@ static java_objectheader *_Jv_jni_CallObjectMethod(java_objectheader *o,
 *******************************************************************************/
 
 static jint _Jv_jni_CallIntMethod(java_objectheader *o, vftbl_t *vftbl,
-                                                                 methodinfo *m, va_list ap, s4 type)
+                                                                 methodinfo *m, va_list ap)
 {
-       methodinfo    *resm;
-       s4             paramcount;
-       jni_callblock *blk;
-       jint           ret;
-       s4             dumpsize;
+       methodinfo *resm;
+       jint        i;
 
        STATISTICS(jniinvokation());
 
@@ -574,27 +528,11 @@ static jint _Jv_jni_CallIntMethod(java_objectheader *o, vftbl_t *vftbl,
                resm = method_vftbl_lookup(vftbl, m);
        }
 
-       /* mark start of dump memory area */
-
-       dumpsize = dump_size();
-
-       paramcount = resm->parseddesc->paramcount;
-
-       blk = DMNEW(jni_callblock, paramcount);
-
-       fill_callblock_from_vargs(o, resm->parseddesc, blk, ap, type);
-
        STATISTICS(jnicallXmethodnvokation());
 
-       ASM_CALLJAVAFUNCTION2_INT(ret, resm, paramcount,
-                                                         paramcount * sizeof(jni_callblock),
-                                                         blk);
-
-       /* release dump area */
+       i = vm_call_method_int_valist(resm, o, ap);
 
-       dump_release(dumpsize);
-
-       return ret;
+       return i;
 }
 
 
@@ -607,11 +545,8 @@ static jint _Jv_jni_CallIntMethod(java_objectheader *o, vftbl_t *vftbl,
 static jlong _Jv_jni_CallLongMethod(java_objectheader *o, vftbl_t *vftbl,
                                                                        methodinfo *m, va_list ap)
 {
-       methodinfo    *resm;
-       s4             paramcount;
-       jni_callblock *blk;
-       jlong          ret;
-       s4             dumpsize;
+       methodinfo *resm;
+       jlong       l;
 
        STATISTICS(jniinvokation());
 
@@ -639,27 +574,11 @@ static jlong _Jv_jni_CallLongMethod(java_objectheader *o, vftbl_t *vftbl,
                resm = method_vftbl_lookup(vftbl, m);
        }
 
-       /* mark start of dump memory area */
-
-       dumpsize = dump_size();
-
-       paramcount = resm->parseddesc->paramcount;
-
-       blk = DMNEW(jni_callblock, paramcount);
-
-       fill_callblock_from_vargs(o, resm->parseddesc, blk, ap, PRIMITIVETYPE_LONG);
-
        STATISTICS(jnicallXmethodnvokation());
 
-       ASM_CALLJAVAFUNCTION2_LONG(ret, resm, paramcount,
-                                                          paramcount * sizeof(jni_callblock),
-                                                          blk);
-
-       /* release dump area */
+       l = vm_call_method_long_valist(resm, o, ap);
 
-       dump_release(dumpsize);
-
-       return ret;
+       return l;
 }
 
 
@@ -672,11 +591,8 @@ static jlong _Jv_jni_CallLongMethod(java_objectheader *o, vftbl_t *vftbl,
 static jfloat _Jv_jni_CallFloatMethod(java_objectheader *o, vftbl_t *vftbl,
                                                                          methodinfo *m, va_list ap)
 {
-       methodinfo    *resm;
-       s4             paramcount;
-       jni_callblock *blk;
-       jdouble        ret;
-       s4             dumpsize;
+       methodinfo *resm;
+       jfloat      f;
 
        /* Class initialization is done by the JIT compiler.  This is ok
           since a static method always belongs to the declaring class. */
@@ -697,28 +613,11 @@ static jfloat _Jv_jni_CallFloatMethod(java_objectheader *o, vftbl_t *vftbl,
                resm = method_vftbl_lookup(vftbl, m);
        }
 
-       /* mark start of dump memory area */
-
-       dumpsize = dump_size();
-
-       paramcount = resm->parseddesc->paramcount;
-
-       blk = DMNEW(jni_callblock, paramcount);
-
-       fill_callblock_from_vargs(o, resm->parseddesc, blk, ap,
-                                                         PRIMITIVETYPE_FLOAT);
-
        STATISTICS(jnicallXmethodnvokation());
 
-       ASM_CALLJAVAFUNCTION2_FLOAT(ret, resm, paramcount,
-                                                               paramcount * sizeof(jni_callblock),
-                                                               blk);
-
-       /* release dump area */
-
-       dump_release(dumpsize);
+       f = vm_call_method_float_valist(resm, o, ap);
 
-       return ret;
+       return f;
 }
 
 
@@ -731,11 +630,8 @@ static jfloat _Jv_jni_CallFloatMethod(java_objectheader *o, vftbl_t *vftbl,
 static jdouble _Jv_jni_CallDoubleMethod(java_objectheader *o, vftbl_t *vftbl,
                                                                                methodinfo *m, va_list ap)
 {
-       methodinfo    *resm;
-       s4             paramcount;
-       jni_callblock *blk;
-       jfloat         ret;
-       s4             dumpsize;
+       methodinfo *resm;
+       jdouble     d;
 
        /* Class initialization is done by the JIT compiler.  This is ok
           since a static method always belongs to the declaring class. */
@@ -756,28 +652,9 @@ static jdouble _Jv_jni_CallDoubleMethod(java_objectheader *o, vftbl_t *vftbl,
                resm = method_vftbl_lookup(vftbl, m);
        }
 
-       /* mark start of dump memory area */
-
-       dumpsize = dump_size();
-
-       paramcount = resm->parseddesc->paramcount;
-
-       blk = DMNEW(jni_callblock, paramcount);
-
-       fill_callblock_from_vargs(o, resm->parseddesc, blk, ap,
-                                                         PRIMITIVETYPE_DOUBLE);
+       d = vm_call_method_double_valist(resm, o, ap);
 
-       STATISTICS(jnicallXmethodnvokation());
-
-       ASM_CALLJAVAFUNCTION2_DOUBLE(ret, resm, paramcount,
-                                                                paramcount * sizeof(jni_callblock),
-                                                                blk);
-
-       /* release dump area */
-
-       dump_release(dumpsize);
-
-       return ret;
+       return d;
 }
 
 
@@ -790,10 +667,7 @@ static jdouble _Jv_jni_CallDoubleMethod(java_objectheader *o, vftbl_t *vftbl,
 static void _Jv_jni_CallVoidMethod(java_objectheader *o, vftbl_t *vftbl,
                                                                   methodinfo *m, va_list ap)
 {      
-       methodinfo    *resm;
-       s4             paramcount;
-       jni_callblock *blk;
-       s4             dumpsize;
+       methodinfo *resm;
 
        if (m == NULL) {
                exceptions_throw_nullpointerexception();
@@ -819,25 +693,50 @@ static void _Jv_jni_CallVoidMethod(java_objectheader *o, vftbl_t *vftbl,
                resm = method_vftbl_lookup(vftbl, m);
        }
 
-       /* mark start of dump memory area */
+       STATISTICS(jnicallXmethodnvokation());
+
+       (void) vm_call_method_valist(resm, o, ap);
+}
 
-       dumpsize = dump_size();
 
-       paramcount = resm->parseddesc->paramcount;
+/* _Jv_jni_CallVoidMethodA *****************************************************
 
-       blk = DMNEW(jni_callblock, paramcount);
+   Internal function to call Java void methods.
 
-       fill_callblock_from_vargs(o, resm->parseddesc, blk, ap, TYPE_VOID);
+*******************************************************************************/
 
-       STATISTICS(jnicallXmethodnvokation());
+static void _Jv_jni_CallVoidMethodA(java_objectheader *o, vftbl_t *vftbl,
+                                                                       methodinfo *m, jvalue *args)
+{      
+       methodinfo *resm;
 
-       ASM_CALLJAVAFUNCTION2(resm, paramcount,
-                                                 paramcount * sizeof(jni_callblock),
-                                                 blk);
+       if (m == NULL) {
+               exceptions_throw_nullpointerexception();
+               return;
+       }
 
-       /* release dump area */
+       /* Class initialization is done by the JIT compiler.  This is ok
+          since a static method always belongs to the declaring class. */
+
+       if (m->flags & ACC_STATIC) {
+               /* For static methods we reset the object. */
+
+               if (o != NULL)
+                       o = NULL;
+
+               /* for convenience */
+
+               resm = m;
+
+       } else {
+               /* For instance methods we make a virtual function table lookup. */
+
+               resm = method_vftbl_lookup(vftbl, m);
+       }
+
+       STATISTICS(jnicallXmethodnvokation());
 
-       dump_release(dumpsize);
+       (void) vm_call_method_jvalue(resm, o, args);
 }
 
 
@@ -856,7 +755,7 @@ java_objectheader *_Jv_jni_invokeNative(methodinfo *m, java_objectheader *o,
                                                                                java_objectarray *params)
 {
        methodinfo        *resm;
-       jni_callblock     *blk;
+       vm_arg            *vmargs;
        java_objectheader *ro;
        s4                 argcount;
        s4                 paramcount;
@@ -878,9 +777,7 @@ java_objectheader *_Jv_jni_invokeNative(methodinfo *m, java_objectheader *o,
           class the method belongs to. For static methods the obj
           parameter is ignored. */
 
-       if (!(m->flags & ACC_STATIC) && o &&
-               (!builtin_instanceof(o, m->class)))
-       {
+       if (!(m->flags & ACC_STATIC) && o && (!builtin_instanceof(o, m->class))) {
                *exceptionptr =
                        new_exception_message(string_java_lang_IllegalArgumentException,
                                                                  "Object parameter of wrong type in Java_java_lang_reflect_Method_invokeNative");
@@ -919,16 +816,14 @@ java_objectheader *_Jv_jni_invokeNative(methodinfo *m, java_objectheader *o,
                resm = m;
        }
 
-       blk = MNEW(jni_callblock, argcount);
+       vmargs = MNEW(vm_arg, argcount);
 
-       if (!fill_callblock_from_objectarray(o, resm->parseddesc, blk, params))
+       if (!_Jv_jni_vmargs_from_objectarray(o, resm->parseddesc, vmargs, params))
                return NULL;
 
        switch (resm->parseddesc->returntype.decltype) {
        case TYPE_VOID:
-               ASM_CALLJAVAFUNCTION2(resm, argcount,
-                                                         argcount * sizeof(jni_callblock),
-                                                         blk);
+               (void) vm_call_method_vmarg(resm, argcount, vmargs);
 
                ro = NULL;
                break;
@@ -937,9 +832,7 @@ java_objectheader *_Jv_jni_invokeNative(methodinfo *m, java_objectheader *o,
                s4 i;
                java_lang_Boolean *bo;
 
-               ASM_CALLJAVAFUNCTION2_INT(i, resm, argcount,
-                                                                 argcount * sizeof(jni_callblock),
-                                                                 blk);
+               i = vm_call_method_int_vmarg(resm, argcount, vmargs);
 
                ro = builtin_new(class_java_lang_Boolean);
 
@@ -954,9 +847,7 @@ java_objectheader *_Jv_jni_invokeNative(methodinfo *m, java_objectheader *o,
                s4 i;
                java_lang_Byte *bo;
 
-               ASM_CALLJAVAFUNCTION2_INT(i, resm, argcount,
-                                                                 argcount * sizeof(jni_callblock),
-                                                                 blk);
+               i = vm_call_method_int_vmarg(resm, argcount, vmargs);
 
                ro = builtin_new(class_java_lang_Byte);
 
@@ -971,9 +862,7 @@ java_objectheader *_Jv_jni_invokeNative(methodinfo *m, java_objectheader *o,
                s4 i;
                java_lang_Character *co;
 
-               ASM_CALLJAVAFUNCTION2_INT(i, resm, argcount,
-                                                                 argcount * sizeof(jni_callblock),
-                                                                 blk);
+               i = vm_call_method_int_vmarg(resm, argcount, vmargs);
 
                ro = builtin_new(class_java_lang_Character);
 
@@ -988,9 +877,7 @@ java_objectheader *_Jv_jni_invokeNative(methodinfo *m, java_objectheader *o,
                s4 i;
                java_lang_Short *so;
 
-               ASM_CALLJAVAFUNCTION2_INT(i, resm, argcount,
-                                                                 argcount * sizeof(jni_callblock),
-                                                                 blk);
+               i = vm_call_method_int_vmarg(resm, argcount, vmargs);
 
                ro = builtin_new(class_java_lang_Short);
 
@@ -1005,9 +892,7 @@ java_objectheader *_Jv_jni_invokeNative(methodinfo *m, java_objectheader *o,
                s4 i;
                java_lang_Integer *io;
 
-               ASM_CALLJAVAFUNCTION2_INT(i, resm, argcount,
-                                                                 argcount * sizeof(jni_callblock),
-                                                                 blk);
+               i = vm_call_method_int_vmarg(resm, argcount, vmargs);
 
                ro = builtin_new(class_java_lang_Integer);
 
@@ -1022,9 +907,7 @@ java_objectheader *_Jv_jni_invokeNative(methodinfo *m, java_objectheader *o,
                s8 l;
                java_lang_Long *lo;
 
-               ASM_CALLJAVAFUNCTION2_LONG(l, resm, argcount,
-                                                                  argcount * sizeof(jni_callblock),
-                                                                  blk);
+               l = vm_call_method_long_vmarg(resm, argcount, vmargs);
 
                ro = builtin_new(class_java_lang_Long);
 
@@ -1039,9 +922,7 @@ java_objectheader *_Jv_jni_invokeNative(methodinfo *m, java_objectheader *o,
                float f;
                java_lang_Float *fo;
 
-               ASM_CALLJAVAFUNCTION2_FLOAT(f, resm, argcount,
-                                                                       argcount * sizeof(jni_callblock),
-                                                                       blk);
+               f = vm_call_method_float_vmarg(resm, argcount, vmargs);
 
                ro = builtin_new(class_java_lang_Float);
 
@@ -1056,9 +937,7 @@ java_objectheader *_Jv_jni_invokeNative(methodinfo *m, java_objectheader *o,
                double d;
                java_lang_Double *_do;
 
-               ASM_CALLJAVAFUNCTION2_DOUBLE(d, resm, argcount,
-                                                                        argcount * sizeof(jni_callblock),
-                                                                        blk);
+               d = vm_call_method_double_vmarg(resm, argcount, vmargs);
 
                ro = builtin_new(class_java_lang_Double);
 
@@ -1070,21 +949,19 @@ java_objectheader *_Jv_jni_invokeNative(methodinfo *m, java_objectheader *o,
        break;
 
        case TYPE_ADR:
-               ASM_CALLJAVAFUNCTION2_ADR(ro, resm, argcount,
-                                                                 argcount * sizeof(jni_callblock),
-                                                                 blk);
+               ro = vm_call_method_vmarg(resm, argcount, vmargs);
                break;
 
        default:
                /* if this happens the exception has already been set by
                   fill_callblock_from_objectarray */
 
-               MFREE(blk, jni_callblock, argcount);
+               MFREE(vmargs, vm_arg, argcount);
 
                return NULL;
        }
 
-       MFREE(blk, jni_callblock, argcount);
+       MFREE(vmargs, vm_arg, argcount);
 
        if (*exceptionptr) {
                java_objectheader *cause;
@@ -1359,7 +1236,7 @@ void ExceptionDescribe(JNIEnv *env)
 
                /* print the stacktrace */
 
-               ASM_CALLJAVAFUNCTION(m, e, NULL, NULL, NULL);
+               (void) vm_call_method(m, e);
        }
 }
 
@@ -1620,7 +1497,7 @@ jobject NewObject(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
 
        o = builtin_new(clazz);
        
-       if (!o)
+       if (o == NULL)
                return NULL;
 
        /* call constructor */
@@ -1656,7 +1533,7 @@ jobject NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID, va_list args)
 
        o = builtin_new(clazz);
        
-       if (!o)
+       if (o == NULL)
                return NULL;
 
        /* call constructor */
@@ -1667,21 +1544,37 @@ jobject NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID, va_list args)
 }
 
 
-/*********************************************************************************** 
+/* NewObjectA ***************************************************************** 
 
-       Constructs a new Java object
-       arguments that are to be passed to the constructor are placed in 
-       args array of jvalues 
+   Programmers place all arguments that are to be passed to the
+   constructor in an args array of jvalues that immediately follows
+   the methodID argument. NewObjectA() accepts the arguments in this
+   array, and, in turn, passes them to the Java method that the
+   programmer wishes to invoke.
 
-***********************************************************************************/
+*******************************************************************************/
 
 jobject NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID, jvalue *args)
 {
+       java_objectheader *o;
+       methodinfo        *m;
+
        STATISTICS(jniinvokation());
 
-       log_text("JNI-Call: NewObjectA: IMPLEMENT ME!");
+       m = (methodinfo *) methodID;
+
+       /* create object */
 
-       return NewLocalRef(env, NULL);
+       o = builtin_new(clazz);
+       
+       if (o == NULL)
+               return NULL;
+
+       /* call constructor */
+
+       _Jv_jni_CallVoidMethodA(o, o->vftbl, m, args);
+
+       return NewLocalRef(env, o);
 }
 
 
@@ -1916,11 +1809,18 @@ jobject CallObjectMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list
 }
 
 
-jobject CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
+jobject CallObjectMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
 {
-       log_text("JNI-Call: CallObjectMethodA: IMPLEMENT ME!");
+       java_objectheader *o;
+       methodinfo        *m;
+       java_objectheader *ret;
 
-       return NewLocalRef(env, NULL);
+       o = (java_objectheader *) obj;
+       m = (methodinfo *) methodID;
+
+       ret = _Jv_jni_CallObjectMethodA(o, o->vftbl, m, args);
+
+       return NewLocalRef(env, ret);
 }
 
 
@@ -1935,7 +1835,7 @@ jboolean CallBooleanMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
        m = (methodinfo *) methodID;
 
        va_start(ap, methodID);
-       b = _Jv_jni_CallIntMethod(o, o->vftbl, m, ap, PRIMITIVETYPE_BOOLEAN);
+       b = _Jv_jni_CallIntMethod(o, o->vftbl, m, ap);
        va_end(ap);
 
        return b;
@@ -1951,7 +1851,7 @@ jboolean CallBooleanMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_lis
        o = (java_objectheader *) obj;
        m = (methodinfo *) methodID;
 
-       b = _Jv_jni_CallIntMethod(o, o->vftbl, m, args, PRIMITIVETYPE_BOOLEAN);
+       b = _Jv_jni_CallIntMethod(o, o->vftbl, m, args);
 
        return b;
 }
@@ -1976,7 +1876,7 @@ jbyte CallByteMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
        m = (methodinfo *) methodID;
 
        va_start(ap, methodID);
-       b = _Jv_jni_CallIntMethod(o, o->vftbl, m, ap, PRIMITIVETYPE_BYTE);
+       b = _Jv_jni_CallIntMethod(o, o->vftbl, m, ap);
        va_end(ap);
 
        return b;
@@ -1992,7 +1892,7 @@ jbyte CallByteMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args
        o = (java_objectheader *) obj;
        m = (methodinfo *) methodID;
 
-       b = _Jv_jni_CallIntMethod(o, o->vftbl, m, args, PRIMITIVETYPE_BYTE);
+       b = _Jv_jni_CallIntMethod(o, o->vftbl, m, args);
 
        return b;
 }
@@ -2017,7 +1917,7 @@ jchar CallCharMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
        m = (methodinfo *) methodID;
 
        va_start(ap, methodID);
-       c = _Jv_jni_CallIntMethod(o, o->vftbl, m, ap, PRIMITIVETYPE_CHAR);
+       c = _Jv_jni_CallIntMethod(o, o->vftbl, m, ap);
        va_end(ap);
 
        return c;
@@ -2033,7 +1933,7 @@ jchar CallCharMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args
        o = (java_objectheader *) obj;
        m = (methodinfo *) methodID;
 
-       c = _Jv_jni_CallIntMethod(o, o->vftbl, m, args, PRIMITIVETYPE_CHAR);
+       c = _Jv_jni_CallIntMethod(o, o->vftbl, m, args);
 
        return c;
 }
@@ -2058,7 +1958,7 @@ jshort CallShortMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
        m = (methodinfo *) methodID;
 
        va_start(ap, methodID);
-       s = _Jv_jni_CallIntMethod(o, o->vftbl, m, ap, PRIMITIVETYPE_SHORT);
+       s = _Jv_jni_CallIntMethod(o, o->vftbl, m, ap);
        va_end(ap);
 
        return s;
@@ -2074,7 +1974,7 @@ jshort CallShortMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list ar
        o = (java_objectheader *) obj;
        m = (methodinfo *) methodID;
 
-       s = _Jv_jni_CallIntMethod(o, o->vftbl, m, args, PRIMITIVETYPE_SHORT);
+       s = _Jv_jni_CallIntMethod(o, o->vftbl, m, args);
 
        return s;
 }
@@ -2100,7 +2000,7 @@ jint CallIntMethod(JNIEnv *env, jobject obj, jmethodID methodID, ...)
        m = (methodinfo *) methodID;
 
        va_start(ap, methodID);
-       i = _Jv_jni_CallIntMethod(o, o->vftbl, m, ap, PRIMITIVETYPE_INT);
+       i = _Jv_jni_CallIntMethod(o, o->vftbl, m, ap);
        va_end(ap);
 
        return i;
@@ -2116,7 +2016,7 @@ jint CallIntMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
        o = (java_objectheader *) obj;
        m = (methodinfo *) methodID;
 
-       i = _Jv_jni_CallIntMethod(o, o->vftbl, m, args, PRIMITIVETYPE_INT);
+       i = _Jv_jni_CallIntMethod(o, o->vftbl, m, args);
 
        return i;
 }
@@ -2286,7 +2186,13 @@ void CallVoidMethodV(JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
 
 void CallVoidMethodA(JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
 {
-       log_text("JNI-Call: CallVoidMethodA: IMPLEMENT ME!");
+       java_objectheader *o;
+       methodinfo        *m;
+
+       o = (java_objectheader *) obj;
+       m = (methodinfo *) methodID;
+
+       _Jv_jni_CallVoidMethodA(o, o->vftbl, m, args);
 }
 
 
@@ -2350,7 +2256,7 @@ jboolean CallNonvirtualBooleanMethod(JNIEnv *env, jobject obj, jclass clazz, jme
        m = (methodinfo *) methodID;
 
        va_start(ap, methodID);
-       b = _Jv_jni_CallIntMethod(o, c->vftbl, m, ap, PRIMITIVETYPE_BOOLEAN);
+       b = _Jv_jni_CallIntMethod(o, c->vftbl, m, ap);
        va_end(ap);
 
        return b;
@@ -2368,7 +2274,7 @@ jboolean CallNonvirtualBooleanMethodV(JNIEnv *env, jobject obj, jclass clazz, jm
        c = (classinfo *) clazz;
        m = (methodinfo *) methodID;
 
-       b = _Jv_jni_CallIntMethod(o, c->vftbl, m, args, PRIMITIVETYPE_BOOLEAN);
+       b = _Jv_jni_CallIntMethod(o, c->vftbl, m, args);
 
        return b;
 }
@@ -2395,7 +2301,7 @@ jbyte CallNonvirtualByteMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID
        m = (methodinfo *) methodID;
 
        va_start(ap, methodID);
-       b = _Jv_jni_CallIntMethod(o, c->vftbl, m, ap, PRIMITIVETYPE_BYTE);
+       b = _Jv_jni_CallIntMethod(o, c->vftbl, m, ap);
        va_end(ap);
 
        return b;
@@ -2413,7 +2319,7 @@ jbyte CallNonvirtualByteMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodI
        c = (classinfo *) clazz;
        m = (methodinfo *) methodID;
 
-       b = _Jv_jni_CallIntMethod(o, c->vftbl, m, args, PRIMITIVETYPE_BYTE);
+       b = _Jv_jni_CallIntMethod(o, c->vftbl, m, args);
 
        return b;
 }
@@ -2441,7 +2347,7 @@ jchar CallNonvirtualCharMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID
        m = (methodinfo *) methodID;
 
        va_start(ap, methodID);
-       ch = _Jv_jni_CallIntMethod(o, c->vftbl, m, ap, PRIMITIVETYPE_CHAR);
+       ch = _Jv_jni_CallIntMethod(o, c->vftbl, m, ap);
        va_end(ap);
 
        return ch;
@@ -2459,7 +2365,7 @@ jchar CallNonvirtualCharMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodI
        c = (classinfo *) clazz;
        m = (methodinfo *) methodID;
 
-       ch = _Jv_jni_CallIntMethod(o, c->vftbl, m, args, PRIMITIVETYPE_CHAR);
+       ch = _Jv_jni_CallIntMethod(o, c->vftbl, m, args);
 
        return ch;
 }
@@ -2487,7 +2393,7 @@ jshort CallNonvirtualShortMethod(JNIEnv *env, jobject obj, jclass clazz, jmethod
        m = (methodinfo *) methodID;
 
        va_start(ap, methodID);
-       s = _Jv_jni_CallIntMethod(o, c->vftbl, m, ap, PRIMITIVETYPE_SHORT);
+       s = _Jv_jni_CallIntMethod(o, c->vftbl, m, ap);
        va_end(ap);
 
        return s;
@@ -2505,7 +2411,7 @@ jshort CallNonvirtualShortMethodV(JNIEnv *env, jobject obj, jclass clazz, jmetho
        c = (classinfo *) clazz;
        m = (methodinfo *) methodID;
 
-       s = _Jv_jni_CallIntMethod(o, c->vftbl, m, args, PRIMITIVETYPE_SHORT);
+       s = _Jv_jni_CallIntMethod(o, c->vftbl, m, args);
 
        return s;
 }
@@ -2533,7 +2439,7 @@ jint CallNonvirtualIntMethod(JNIEnv *env, jobject obj, jclass clazz, jmethodID m
        m = (methodinfo *) methodID;
 
        va_start(ap, methodID);
-       i = _Jv_jni_CallIntMethod(o, c->vftbl, m, ap, PRIMITIVETYPE_INT);
+       i = _Jv_jni_CallIntMethod(o, c->vftbl, m, ap);
        va_end(ap);
 
        return i;
@@ -2551,7 +2457,7 @@ jint CallNonvirtualIntMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID
        c = (classinfo *) clazz;
        m = (methodinfo *) methodID;
 
-       i = _Jv_jni_CallIntMethod(o, c->vftbl, m, args, PRIMITIVETYPE_INT);
+       i = _Jv_jni_CallIntMethod(o, c->vftbl, m, args);
 
        return i;
 }
@@ -2736,8 +2642,16 @@ void CallNonvirtualVoidMethodV(JNIEnv *env, jobject obj, jclass clazz, jmethodID
 
 
 void CallNonvirtualVoidMethodA(JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, jvalue * args)
-{
-       log_text("JNI-Call: CallNonvirtualVoidMethodA: IMPLEMENT ME!");
+{      
+       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);
 }
 
 
@@ -3068,7 +2982,7 @@ jboolean CallStaticBooleanMethod(JNIEnv *env, jclass clazz, jmethodID methodID,
        m = (methodinfo *) methodID;
 
        va_start(ap, methodID);
-       b = _Jv_jni_CallIntMethod(NULL, NULL, m, ap, PRIMITIVETYPE_BOOLEAN);
+       b = _Jv_jni_CallIntMethod(NULL, NULL, m, ap);
        va_end(ap);
 
        return b;
@@ -3082,7 +2996,7 @@ jboolean CallStaticBooleanMethodV(JNIEnv *env, jclass clazz, jmethodID methodID,
 
        m = (methodinfo *) methodID;
 
-       b = _Jv_jni_CallIntMethod(NULL, NULL, m, args, PRIMITIVETYPE_BOOLEAN);
+       b = _Jv_jni_CallIntMethod(NULL, NULL, m, args);
 
        return b;
 }
@@ -3105,7 +3019,7 @@ jbyte CallStaticByteMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
        m = (methodinfo *) methodID;
 
        va_start(ap, methodID);
-       b = _Jv_jni_CallIntMethod(NULL, NULL, m, ap, PRIMITIVETYPE_BYTE);
+       b = _Jv_jni_CallIntMethod(NULL, NULL, m, ap);
        va_end(ap);
 
        return b;
@@ -3119,7 +3033,7 @@ jbyte CallStaticByteMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_li
 
        m = (methodinfo *) methodID;
 
-       b = _Jv_jni_CallIntMethod(NULL, NULL, m, args, PRIMITIVETYPE_BYTE);
+       b = _Jv_jni_CallIntMethod(NULL, NULL, m, args);
 
        return b;
 }
@@ -3142,7 +3056,7 @@ jchar CallStaticCharMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
        m = (methodinfo *) methodID;
 
        va_start(ap, methodID);
-       c = _Jv_jni_CallIntMethod(NULL, NULL, m, ap, PRIMITIVETYPE_CHAR);
+       c = _Jv_jni_CallIntMethod(NULL, NULL, m, ap);
        va_end(ap);
 
        return c;
@@ -3156,7 +3070,7 @@ jchar CallStaticCharMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_li
 
        m = (methodinfo *) methodID;
 
-       c = _Jv_jni_CallIntMethod(NULL, NULL, m, args, PRIMITIVETYPE_CHAR);
+       c = _Jv_jni_CallIntMethod(NULL, NULL, m, args);
 
        return c;
 }
@@ -3179,7 +3093,7 @@ jshort CallStaticShortMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
        m = (methodinfo *) methodID;
 
        va_start(ap, methodID);
-       s = _Jv_jni_CallIntMethod(NULL, NULL, m, ap, PRIMITIVETYPE_SHORT);
+       s = _Jv_jni_CallIntMethod(NULL, NULL, m, ap);
        va_end(ap);
 
        return s;
@@ -3193,7 +3107,7 @@ jshort CallStaticShortMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_
 
        m = (methodinfo *) methodID;
 
-       s = _Jv_jni_CallIntMethod(NULL, NULL, m, args, PRIMITIVETYPE_SHORT);
+       s = _Jv_jni_CallIntMethod(NULL, NULL, m, args);
 
        return s;
 }
@@ -3216,7 +3130,7 @@ jint CallStaticIntMethod(JNIEnv *env, jclass clazz, jmethodID methodID, ...)
        m = (methodinfo *) methodID;
 
        va_start(ap, methodID);
-       i = _Jv_jni_CallIntMethod(NULL, NULL, m, ap, PRIMITIVETYPE_INT);
+       i = _Jv_jni_CallIntMethod(NULL, NULL, m, ap);
        va_end(ap);
 
        return i;
@@ -3230,7 +3144,7 @@ jint CallStaticIntMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_list
 
        m = (methodinfo *) methodID;
 
-       i = _Jv_jni_CallIntMethod(NULL, NULL, m, args, PRIMITIVETYPE_INT);
+       i = _Jv_jni_CallIntMethod(NULL, NULL, m, args);
 
        return i;
 }
@@ -3382,7 +3296,11 @@ void CallStaticVoidMethodV(JNIEnv *env, jclass clazz, jmethodID methodID, va_lis
 
 void CallStaticVoidMethodA(JNIEnv *env, jclass clazz, jmethodID methodID, jvalue * args)
 {
-       log_text("JNI-Call: CallStaticVoidMethodA: IMPLEMENT ME!");
+       methodinfo *m;
+
+       m = (methodinfo *) methodID;
+
+       _Jv_jni_CallVoidMethodA(NULL, NULL, m, args);
 }
 
 
@@ -5060,7 +4978,7 @@ jobject NewGlobalRef(JNIEnv* env, jobject lobj)
        builtin_monitorenter(*global_ref_table);
 #endif
        
-       ASM_CALLJAVAFUNCTION_ADR(o, getmid, *global_ref_table, lobj, NULL, NULL);
+       o = vm_call_method(getmid, *global_ref_table, lobj);
 
        refcount = (java_lang_Integer *) o;
 
@@ -5074,7 +4992,7 @@ jobject NewGlobalRef(JNIEnv* env, jobject lobj)
                        return NULL;
                }
 
-               ASM_CALLJAVAFUNCTION(putmid, *global_ref_table, lobj, newval, NULL);
+               (void) vm_call_method(putmid, *global_ref_table, lobj, newval);
 
        } else {
                /* we can access the object itself, as we are in a
@@ -5109,8 +5027,7 @@ void DeleteGlobalRef(JNIEnv* env, jobject globalRef)
        builtin_monitorenter(*global_ref_table);
 #endif
 
-       ASM_CALLJAVAFUNCTION_ADR(o, getmid, *global_ref_table, globalRef, NULL,
-                                                        NULL);
+       o = vm_call_method(getmid, *global_ref_table, globalRef);
 
        refcount = (java_lang_Integer *) o;
 
@@ -5125,8 +5042,7 @@ void DeleteGlobalRef(JNIEnv* env, jobject globalRef)
        val = refcount->value - 1;
 
        if (val == 0) {
-               ASM_CALLJAVAFUNCTION(removemid, *global_ref_table, refcount, NULL,
-                                                        NULL);
+               (void) vm_call_method(removemid, *global_ref_table, refcount);
 
        } else {
                /* we do not create a new object, but set the new value into