Before that, all vm_call_method_*() functions returned unsigned long
which was not a good idea because there was no way to handle jlong or
jdouble this way on x86.

This patch changes the API, so that vm_call_method_*() functions are
given a pointer to a union jvalue to which the result should be
saved. This way we can use vm_call_method_*() functions in a machine
and type independed way.

While at it, implement JNI funciton families:
 CallStatic*Method()
 CallStatic*MethodV()
 Call*Method()

Signed-off-by: Tomek Grabiec <tgrab...@gmail.com>
---
 arch/x86/call.c    |  222 +++++++++++++++++++++++++++++++++++++++-----
 include/vm/call.h  |   85 +++++++++--------
 vm/call.c          |   40 ++++----
 vm/jni-interface.c |  265 +++++++++++++++++++++-------------------------------
 vm/reflection.c    |   21 +++--
 5 files changed, 385 insertions(+), 248 deletions(-)

diff --git a/arch/x86/call.c b/arch/x86/call.c
index 08b7ac9..717d53d 100644
--- a/arch/x86/call.c
+++ b/arch/x86/call.c
@@ -37,14 +37,13 @@
 #ifdef CONFIG_X86_32
 
 /**
- * This calls a function with call arguments copied from @args
- * array. The array contains @args_count elements of machine word
- * size. The @target must be a variable holding a function
- * pointer. Call result will be stored in @result.
+ * Calls @method which address is obtained from a memory
+ * pointed by @target. Function returns call result which
+ * is supposed to be saved to %eax.
  */
-unsigned long native_call(struct vm_method *method,
-                         const void *target,
-                         unsigned long *args)
+static unsigned long native_call_gp(struct vm_method *method,
+                                   const void *target,
+                                   unsigned long *args)
 {
        unsigned long result;
 
@@ -66,15 +65,9 @@ unsigned long native_call(struct vm_method *method,
        return result;
 }
 
-/**
- * This calls a VM native function with call arguments copied from
- * @args array. The array contains @args_count elements of machine
- * word size. The @target must be a pointer to a VM function. Call
- * result will be stored in @result.
- */
-unsigned long vm_native_call(struct vm_method *method,
-                            const void *target,
-                            unsigned long *args)
+static unsigned long vm_native_call_gp(struct vm_method *method,
+                                      const void *target,
+                                      unsigned long *args)
 {
        unsigned long result;
 
@@ -108,11 +101,104 @@ unsigned long vm_native_call(struct vm_method *method,
        return result;
 }
 
+/**
+ * This calls a function with call arguments copied from @args
+ * array. The array contains @args_count elements of machine word
+ * size. The @target must be a variable holding a function
+ * pointer. Call result will be stored in @result.
+ */
+void native_call(struct vm_method *method,
+                const void *target,
+                unsigned long *args,
+                union jvalue *result)
+{
+       switch (method->return_type.vm_type) {
+       case J_VOID:
+               native_call_gp(method, target, args);
+               break;
+       case J_REFERENCE:
+               result->l = (jobject) native_call_gp(method, target, args);
+               break;
+       case J_INT:
+               result->i = (jint) native_call_gp(method, target, args);
+               break;
+       case J_CHAR:
+               result->c = (jchar) native_call_gp(method, target, args);
+               break;
+       case J_BYTE:
+               result->b = (jbyte) native_call_gp(method, target, args);
+               break;
+       case J_SHORT:
+               result->s = (jshort) native_call_gp(method, target, args);
+               break;
+       case J_BOOLEAN:
+               result->z = (jboolean) native_call_gp(method, target, args);
+               break;
+       case J_LONG:
+       case J_DOUBLE:
+       case J_FLOAT:
+               NOT_IMPLEMENTED;
+               break;
+       case J_RETURN_ADDRESS:
+       case VM_TYPE_MAX:
+               die("unexpected type");
+       }
+}
+
+/**
+ * This calls a VM native function with call arguments copied from
+ * @args array. The array contains @args_count elements of machine
+ * word size. The @target must be a pointer to a VM function. Call
+ * result will be stored in @result.
+ */
+void vm_native_call(struct vm_method *method,
+                   const void *target,
+                   unsigned long *args,
+                   union jvalue *result)
+{
+       switch (method->return_type.vm_type) {
+       case J_VOID:
+               vm_native_call_gp(method, target, args);
+               break;
+       case J_REFERENCE:
+               result->l = (jobject) vm_native_call_gp(method, target, args);
+               break;
+       case J_INT:
+               result->i = (jint) vm_native_call_gp(method, target, args);
+               break;
+       case J_CHAR:
+               result->c = (jchar) vm_native_call_gp(method, target, args);
+               break;
+       case J_BYTE:
+               result->b = (jbyte) vm_native_call_gp(method, target, args);
+               break;
+       case J_SHORT:
+               result->s = (jshort) vm_native_call_gp(method, target, args);
+               break;
+       case J_BOOLEAN:
+               result->z = (jboolean) vm_native_call_gp(method, target, args);
+               break;
+       case J_LONG:
+       case J_DOUBLE:
+       case J_FLOAT:
+               NOT_IMPLEMENTED;
+               break;
+       case J_RETURN_ADDRESS:
+       case VM_TYPE_MAX:
+               die("unexpected type");
+       }
+}
+
 #else /* CONFIG_X86_32 */
 
-unsigned long native_call(struct vm_method *method,
-                         const void *target,
-                         unsigned long *args)
+/**
+ * Calls @method which address is obtained from a memory
+ * pointed by @target. Function returns call result which
+ * is supposed to be saved to %rax.
+ */
+static unsigned long native_call_gp(struct vm_method *method,
+                                   const void *target,
+                                   unsigned long *args)
 {
        int i, sp = 0, r = 0;
        unsigned long *stack, regs[6];
@@ -161,15 +247,107 @@ unsigned long native_call(struct vm_method *method,
        return 0;
 }
 
-unsigned long vm_native_call(struct vm_method *method,
-                            const void *target,
-                            unsigned long *args)
+static unsigned long vm_native_call_gp(struct vm_method *method,
+                                      const void *target,
+                                      unsigned long *args)
 {
        abort();
 
        return 0;
 }
 
+/**
+ * This calls a function with call arguments copied from @args
+ * array. The array contains @args_count elements of machine word
+ * size. The @target must be a variable holding a function
+ * pointer. Call result will be stored in @result.
+ */
+void native_call(struct vm_method *method,
+                const void *target,
+                unsigned long *args,
+                union jvalue *result)
+{
+       switch (method->return_type.vm_type) {
+       case J_VOID:
+               native_call_gp(method, target, args);
+               break;
+       case J_REFERENCE:
+               result->l = (jobject) native_call_gp(method, target, args);
+               break;
+       case J_INT:
+               result->i = (jint) native_call_gp(method, target, args);
+               break;
+       case J_CHAR:
+               result->c = (jchar) native_call_gp(method, target, args);
+               break;
+       case J_BYTE:
+               result->b = (jbyte) native_call_gp(method, target, args);
+               break;
+       case J_SHORT:
+               result->s = (jshort) native_call_gp(method, target, args);
+               break;
+       case J_BOOLEAN:
+               result->z = (jboolean) native_call_gp(method, target, args);
+               break;
+       case J_LONG:
+               result->j = (jlong) native_call_gp(method, target, args);
+               break;
+       case J_DOUBLE:
+       case J_FLOAT:
+               NOT_IMPLEMENTED;
+               break;
+       case J_RETURN_ADDRESS:
+       case VM_TYPE_MAX:
+               die("unexpected type");
+       }
+}
+
+/**
+ * This calls a VM native function with call arguments copied from
+ * @args array. The array contains @args_count elements of machine
+ * word size. The @target must be a pointer to a VM function. Call
+ * result will be stored in @result.
+ */
+void vm_native_call(struct vm_method *method,
+                   const void *target,
+                   unsigned long *args,
+                   union jvalue *result)
+{
+       switch (method->return_type.vm_type) {
+       case J_VOID:
+               vm_native_call_gp(method, target, args);
+               break;
+       case J_REFERENCE:
+               result->l = (jobject) vm_native_call_gp(method, target, args);
+               break;
+       case J_INT:
+               result->i = (jint) vm_native_call_gp(method, target, args);
+               break;
+       case J_CHAR:
+               result->c = (jchar) vm_native_call_gp(method, target, args);
+               break;
+       case J_BYTE:
+               result->b = (jbyte) vm_native_call_gp(method, target, args);
+               break;
+       case J_SHORT:
+               result->s = (jshort) vm_native_call_gp(method, target, args);
+               break;
+       case J_BOOLEAN:
+               result->z = (jboolean) vm_native_call_gp(method, target, args);
+               break;
+       case J_LONG:
+               result->j = (jlong) vm_native_call_gp(method, target, args);
+               break;
+       case J_DOUBLE:
+       case J_FLOAT:
+               NOT_IMPLEMENTED;
+               break;
+       case J_RETURN_ADDRESS:
+       case VM_TYPE_MAX:
+               die("unexpected type");
+       }
+}
+
 #warning NOT IMPLEMENTED
 
 #endif /* CONFIG_X86_32 */
diff --git a/include/vm/call.h b/include/vm/call.h
index eed2b0e..1e2d877 100644
--- a/include/vm/call.h
+++ b/include/vm/call.h
@@ -9,76 +9,83 @@
 struct vm_method;
 struct vm_object;
 
-unsigned long vm_call_method_v(struct vm_method *method, va_list args);
-unsigned long vm_call_method_this_v(struct vm_method *method,
-                                   struct vm_object *this,
-                                   va_list args);
-unsigned long vm_call_method_this_a(struct vm_method *method,
-                                   struct vm_object *this,
-                                   unsigned long *args);
-unsigned long vm_call_method_a(struct vm_method *method, unsigned long *args);
+void vm_call_method_v(struct vm_method *method, va_list args, union jvalue 
*result);
+void vm_call_method_this_v(struct vm_method *method,
+                          struct vm_object *this,
+                          va_list args,
+                          union jvalue *result);
+void vm_call_method_this_a(struct vm_method *method,
+                          struct vm_object *this,
+                          unsigned long *args,
+                          union jvalue *result);
+void vm_call_method_a(struct vm_method *method,
+                     unsigned long *args,
+                     union jvalue *result);
 
-#define DECLARE_VM_CALL_METHOD(type)                                   \
+#define DECLARE_VM_CALL_METHOD(type, symbol)                           \
        static inline j ## type                                         \
        vm_call_method_ ## type(struct vm_method *method, ...)          \
        {                                                               \
-               j ## type result;                                       \
+               union jvalue result;                                    \
                va_list args;                                           \
                                                                        \
                va_start(args, method);                                 \
-               result = (j ## type)vm_call_method_v(method, args);     \
+               vm_call_method_v(method, args, &result);                \
                va_end(args);                                           \
                                                                        \
-               return result;                                          \
+               return result.symbol;                                   \
        }
 
-#define DECLARE_VM_CALL_METHOD_THIS(type)                              \
+#define DECLARE_VM_CALL_METHOD_THIS(type, symbol)                      \
        static inline j ## type                                         \
        vm_call_method_this_ ## type(struct vm_method *method,          \
                                     struct vm_object *this, ...)       \
        {                                                               \
-               j ## type result;                                       \
+               union jvalue result;                                    \
                va_list args;                                           \
                                                                        \
                va_start(args, this);                                   \
-               result = (j ## type)vm_call_method_this_v(method, this, args); \
+               vm_call_method_this_v(method, this, args, &result);     \
                va_end(args);                                           \
                                                                        \
-               return result;                                          \
+               return result.symbol;                                   \
        }
 
 static inline void vm_call_method(struct vm_method *method, ...)
 {
+       union jvalue result;
        va_list args;
 
        va_start(args, method);
-       vm_call_method_v(method, args);
+       vm_call_method_v(method, args, &result);
        va_end(args);
 }
 
-DECLARE_VM_CALL_METHOD(byte);
-DECLARE_VM_CALL_METHOD(boolean);
-DECLARE_VM_CALL_METHOD(double);
-DECLARE_VM_CALL_METHOD(float);
-DECLARE_VM_CALL_METHOD(long);
-DECLARE_VM_CALL_METHOD(short);
-DECLARE_VM_CALL_METHOD(object);
-DECLARE_VM_CALL_METHOD(int);
+DECLARE_VM_CALL_METHOD(byte, b);
+DECLARE_VM_CALL_METHOD(boolean, z);
+DECLARE_VM_CALL_METHOD(double, d);
+DECLARE_VM_CALL_METHOD(float, f);
+DECLARE_VM_CALL_METHOD(long, j);
+DECLARE_VM_CALL_METHOD(short, s);
+DECLARE_VM_CALL_METHOD(object, l);
+DECLARE_VM_CALL_METHOD(int, i);
 
-DECLARE_VM_CALL_METHOD_THIS(byte);
-DECLARE_VM_CALL_METHOD_THIS(boolean);
-DECLARE_VM_CALL_METHOD_THIS(double);
-DECLARE_VM_CALL_METHOD_THIS(float);
-DECLARE_VM_CALL_METHOD_THIS(long);
-DECLARE_VM_CALL_METHOD_THIS(short);
-DECLARE_VM_CALL_METHOD_THIS(object);
-DECLARE_VM_CALL_METHOD_THIS(int);
+DECLARE_VM_CALL_METHOD_THIS(byte, b);
+DECLARE_VM_CALL_METHOD_THIS(boolean, z);
+DECLARE_VM_CALL_METHOD_THIS(double, d);
+DECLARE_VM_CALL_METHOD_THIS(float, f);
+DECLARE_VM_CALL_METHOD_THIS(long, j);
+DECLARE_VM_CALL_METHOD_THIS(short, s);
+DECLARE_VM_CALL_METHOD_THIS(object, l);
+DECLARE_VM_CALL_METHOD_THIS(int, i);
 
-extern unsigned long native_call(struct vm_method *method,
-                                const void *target,
-                                unsigned long *args);
-extern unsigned long vm_native_call(struct vm_method *method,
-                                   const void *target,
-                                   unsigned long *args);
+extern void native_call(struct vm_method *method,
+                       const void *target,
+                       unsigned long *args,
+                       union jvalue *result);
+extern void vm_native_call(struct vm_method *method,
+                          const void *target,
+                          unsigned long *args,
+                          union jvalue *result);
 
 #endif
diff --git a/vm/call.c b/vm/call.c
index a33e6a7..b9b9577 100644
--- a/vm/call.c
+++ b/vm/call.c
@@ -36,11 +36,11 @@
 #include "vm/object.h"
 #include "vm/stack-trace.h"
 
-static unsigned long
-call_method_a(struct vm_method *method, void *target, unsigned long *args)
+static void
+call_method_a(struct vm_method *method, void *target, unsigned long *args,
+             union jvalue *result)
 {
        struct vm_object *exception;
-       unsigned long result;
 
        /*
         * XXX: We cannot call JIT code with exception signalled
@@ -52,20 +52,19 @@ call_method_a(struct vm_method *method, void *target, 
unsigned long *args)
        clear_exception();
 
        if (vm_method_is_vm_native(method)) {
-               result = vm_native_call(method, target, args);
+               vm_native_call(method, target, args, result);
                goto out;
        }
 
-       result = native_call(method, target, args);
+       native_call(method, target, args, result);
 
  out:
        if (!exception_occurred() && exception)
                signal_exception(exception);
-
-       return result;
 }
 
-unsigned long vm_call_method_v(struct vm_method *method, va_list args)
+void vm_call_method_v(struct vm_method *method, va_list args,
+                     union jvalue *result)
 {
        unsigned long args_array[method->args_count];
 
@@ -73,29 +72,32 @@ unsigned long vm_call_method_v(struct vm_method *method, 
va_list args)
                args_array[i] = va_arg(args, unsigned long);
 
        void *target = vm_method_call_ptr(method);
-       return call_method_a(method, target, args_array);
+       call_method_a(method, target, args_array, result);
 }
 
-unsigned long vm_call_method_this_a(struct vm_method *method,
-                                   struct vm_object *this,
-                                   unsigned long *args)
+void vm_call_method_this_a(struct vm_method *method,
+                          struct vm_object *this,
+                          unsigned long *args,
+                          union jvalue *result)
 {
        void *target;
 
        target = this->class->vtable.native_ptr[method->virtual_index];
        assert(args[0] == (unsigned long) this);
 
-       return call_method_a(method, target, args);
+       call_method_a(method, target, args, result);
 }
 
-unsigned long vm_call_method_a(struct vm_method *method, unsigned long *args)
+void vm_call_method_a(struct vm_method *method, unsigned long *args,
+                     union jvalue *result)
 {
-       return call_method_a(method, vm_method_call_ptr(method), args);
+       call_method_a(method, vm_method_call_ptr(method), args, result);
 }
 
-unsigned long vm_call_method_this_v(struct vm_method *method,
-                                   struct vm_object *this,
-                                   va_list args)
+void vm_call_method_this_v(struct vm_method *method,
+                          struct vm_object *this,
+                          va_list args,
+                          union jvalue *result)
 {
        unsigned long args_array[method->args_count];
 
@@ -104,5 +106,5 @@ unsigned long vm_call_method_this_v(struct vm_method 
*method,
        for (int i = 1; i < method->args_count; i++)
                args_array[i] = va_arg(args, unsigned long);
 
-       return vm_call_method_this_a(method, this, args_array);
+       vm_call_method_this_a(method, this, args_array, result);
 }
diff --git a/vm/jni-interface.c b/vm/jni-interface.c
index dca174a..ec1d1c3 100644
--- a/vm/jni-interface.c
+++ b/vm/jni-interface.c
@@ -339,7 +339,7 @@ vm_jni_call_static_void_method(struct vm_jni_env *env, 
jclass clazz,
        enter_vm_from_jni();
 
        va_start(args, methodID);
-       vm_call_method_v(methodID, args);
+       vm_call_method_v(methodID, args, NULL);
        va_end(args);
 }
 
@@ -348,67 +348,57 @@ vm_jni_call_static_void_method_v(struct vm_jni_env *env, 
jclass clazz,
                                 jmethodID methodID, va_list args)
 {
        enter_vm_from_jni();
-       vm_call_method_v(methodID, args);
+       vm_call_method_v(methodID, args, NULL);
 }
 
-static jobject
-vm_jni_call_static_object_method(struct vm_jni_env *env, jclass clazz,
-                                jmethodID methodID, ...)
-{
-       jobject result;
-       va_list args;
-
-       enter_vm_from_jni();
-
-       va_start(args, methodID);
-       result = (jobject) vm_call_method_v(methodID, args);
-       va_end(args);
-
-       return result;
-}
-
-static jobject
-vm_jni_call_static_object_method_v(struct vm_jni_env *env, jclass clazz,
-                                  jmethodID methodID, va_list args)
-{
-       enter_vm_from_jni();
-
-       return (jobject) vm_call_method_v(methodID, args);
-}
-
-static jbyte
-vm_jni_call_static_byte_method(struct vm_jni_env *env, jclass clazz,
-                              jmethodID methodID, ...)
-{
-       jbyte result;
-       va_list args;
-
-       enter_vm_from_jni();
-
-       va_start(args, methodID);
-       result = (jbyte) vm_call_method_v(methodID, args);
-       va_end(args);
-
-       return result;
-}
-
-static jbyte
-vm_jni_call_static_byte_method_v(struct vm_jni_env *env, jclass clazz,
-                                jmethodID methodID, va_list args)
-{
-       enter_vm_from_jni();
-
-       return (jbyte) vm_call_method_v(methodID, args);
-}
+#define DECLARE_CALL_STATIC_XXX_METHOD(name, symbol)                   \
+       static j ## name vm_jni_call_static_ ## name ## _method         \
+       (struct vm_jni_env *env, jclass clazz, jmethodID methodID, ...) \
+       {                                                               \
+               union jvalue result;                                    \
+               va_list args;                                           \
+                                                                       \
+               enter_vm_from_jni();                                    \
+                                                                       \
+               va_start(args, methodID);                               \
+               vm_call_method_v(methodID, args, &result);              \
+               va_end(args);                                           \
+                                                                       \
+               return result.symbol;                                   \
+       }
 
-static jshort
-vm_jni_call_static_short_method_v(struct vm_jni_env *env, jclass clazz,
-                                 jmethodID methodID, va_list args)
-{
-       enter_vm_from_jni();
+DECLARE_CALL_STATIC_XXX_METHOD(boolean, z);
+DECLARE_CALL_STATIC_XXX_METHOD(byte, b);
+DECLARE_CALL_STATIC_XXX_METHOD(char, c);
+DECLARE_CALL_STATIC_XXX_METHOD(short, s);
+DECLARE_CALL_STATIC_XXX_METHOD(int, i);
+DECLARE_CALL_STATIC_XXX_METHOD(long, j);
+DECLARE_CALL_STATIC_XXX_METHOD(float, f);
+DECLARE_CALL_STATIC_XXX_METHOD(double, d);
+DECLARE_CALL_STATIC_XXX_METHOD(object, l);
+
+#define DECLARE_CALL_STATIC_XXX_METHOD_V(name, symbol)                 \
+       static j ## name vm_jni_call_static_ ## name ## _method_v       \
+       (struct vm_jni_env *env, jclass clazz,                          \
+        jmethodID methodID, va_list args)                              \
+       {                                                               \
+               union jvalue result;                                    \
+                                                                       \
+               enter_vm_from_jni();                                    \
+                                                                       \
+               vm_call_method_v(methodID, args, &result);              \
+               return result.symbol;                                   \
+       }
 
-       return (jshort) vm_call_method_v(methodID, args);
-}
+DECLARE_CALL_STATIC_XXX_METHOD_V(boolean, z);
+DECLARE_CALL_STATIC_XXX_METHOD_V(byte, b);
+DECLARE_CALL_STATIC_XXX_METHOD_V(char, c);
+DECLARE_CALL_STATIC_XXX_METHOD_V(short, s);
+DECLARE_CALL_STATIC_XXX_METHOD_V(int, i);
+DECLARE_CALL_STATIC_XXX_METHOD_V(long, j);
+DECLARE_CALL_STATIC_XXX_METHOD_V(float, f);
+DECLARE_CALL_STATIC_XXX_METHOD_V(double, d);
+DECLARE_CALL_STATIC_XXX_METHOD_V(object, l);
 
 #define DECLARE_SET_XXX_FIELD(type, vmtype)                            \
 static void                                                            \
@@ -535,7 +525,7 @@ static jobject vm_jni_new_object(struct vm_jni_env *env, 
jobject clazz,
        obj = vm_object_alloc(class);
 
        va_start(args, method);
-       vm_call_method_this_v(method, obj, args);
+       vm_call_method_this_v(method, obj, args, NULL);
        va_end(args);
 
        return obj;
@@ -649,65 +639,53 @@ vm_jni_get_direct_buffer_address(struct vm_jni_env *env, 
jobject buf)
        return NULL;
 }
 
-static jint vm_jni_call_int_method(struct vm_jni_env *env, jobject this,
-                                  jmethodID methodID, ...)
-{
-       va_list args;
-       jint result;
-
-       enter_vm_from_jni();
-
-       /*
-        * TODO: When these functions are used to call private methods
-        * and constructors, the method ID must be derived from the
-        * real class of obj, not from one of its superclasses.
-        */
-       va_start(args, methodID);
-       result = (jint) vm_call_method_this_v(methodID, this, args);
-       va_end(args);
-
-       return result;
-}
-
-static jboolean vm_jni_call_boolean_method(struct vm_jni_env *env, jobject 
this,
-                                          jmethodID methodID, ...)
+/*
+ * TODO: When these functions are used to call private methods and
+ * constructors, the method ID must be derived from the real class of
+ * obj, not from one of its superclasses.
+ */
+static void vm_jni_call_void_method(struct vm_jni_env *env, jobject this,
+                                   jmethodID methodID, ...)
 {
        va_list args;
-       jboolean result;
 
        enter_vm_from_jni();
 
-       /*
-        * TODO: When these functions are used to call private methods
-        * and constructors, the method ID must be derived from the
-        * real class of obj, not from one of its superclasses.
-        */
        va_start(args, methodID);
-       result = (jboolean) vm_call_method_this_v(methodID, this, args);
+       vm_call_method_this_v(methodID, this, args, NULL);
        va_end(args);
-
-       return result;
 }
 
-static jobject vm_jni_call_object_method(struct vm_jni_env *env, jobject this,
-                                        jmethodID methodID, ...)
-{
-       va_list args;
-       jobject result;
-
-       enter_vm_from_jni();
-
-       /*
-        * TODO: When these functions are used to call private methods
-        * and constructors, the method ID must be derived from the
-        * real class of obj, not from one of its superclasses.
-        */
-       va_start(args, methodID);
-       result = (jobject) vm_call_method_this_v(methodID, this, args);
-       va_end(args);
+/*
+ * TODO: When these functions are used to call private methods and
+ * constructors, the method ID must be derived from the real class of
+ * obj, not from one of its superclasses.
+ */
+#define DECLARE_CALL_XXX_METHOD(type, symbol)                          \
+       static j ## type vm_jni_call_ ## type ## _method                \
+       (struct vm_jni_env *env, jobject this, jmethodID methodID, ...) \
+       {                                                               \
+               va_list args;                                           \
+               union jvalue result;                                    \
+                                                                       \
+               enter_vm_from_jni();                                    \
+                                                                       \
+               va_start(args, methodID);                               \
+               vm_call_method_this_v(methodID, this, args, &result);   \
+               va_end(args);                                           \
+                                                                       \
+               return result.symbol;                                   \
+       }
 
-       return result;
-}
+DECLARE_CALL_XXX_METHOD(boolean, z);
+DECLARE_CALL_XXX_METHOD(byte, b);
+DECLARE_CALL_XXX_METHOD(char, c);
+DECLARE_CALL_XXX_METHOD(short, s);
+DECLARE_CALL_XXX_METHOD(int, i);
+DECLARE_CALL_XXX_METHOD(long, j);
+DECLARE_CALL_XXX_METHOD(float, f);
+DECLARE_CALL_XXX_METHOD(double, d);
+DECLARE_CALL_XXX_METHOD(object, l);
 
 static jfieldID
 vm_jni_get_static_field_id(struct vm_jni_env *env, jclass clazz,
@@ -766,39 +744,6 @@ DEFINE_SET_STATIC_FIELD(vm_jni_set_static_long_field, 
jlong, static_field_set_lo
 DEFINE_SET_STATIC_FIELD(vm_jni_set_static_float_field, jfloat, 
static_field_set_float);
 DEFINE_SET_STATIC_FIELD(vm_jni_set_static_double_field, jdouble, 
static_field_set_double);
 
-static jboolean
-vm_jni_call_static_boolean_method(struct vm_jni_env *env, jclass clazz,
-                                 jmethodID methodID, ...)
-{
-       va_list args;
-       jboolean result;
-
-       enter_vm_from_jni();
-
-       va_start(args, methodID);
-       result = (jboolean) vm_call_method_v(methodID, args);
-       va_end(args);
-
-       return result;
-}
-
-static void vm_jni_call_void_method(struct vm_jni_env *env, jobject this,
-                                   jmethodID methodID, ...)
-{
-       va_list args;
-
-       enter_vm_from_jni();
-
-       /*
-        * TODO: When these functions are used to call private methods
-        * and constructors, the method ID must be derived from the
-        * real class of obj, not from one of its superclasses.
-        */
-       va_start(args, methodID);
-       vm_call_method_this_v(methodID, this, args);
-       va_end(args);
-}
-
 static jobject
 vm_jni_new_object_array(struct vm_jni_env *env, jsize size,
                        jclass element_class, jobject initial_element)
@@ -945,7 +890,7 @@ vm_jni_new_object_a(struct vm_jni_env *env, jclass clazz, 
jmethodID method,
        packed_args[0] = (unsigned long) result;
        pack_args(method, packed_args + 1, args);
 
-       vm_call_method_this_a(method, result, packed_args);
+       vm_call_method_this_a(method, result, packed_args, NULL);
 
        return result;
 }
@@ -1080,15 +1025,15 @@ void *vm_jni_native_interface[] = {
        NULL, /* CallBooleanMethodA */
 
        /* 40 */
-       NULL, /* CallByteMethod */
+       vm_jni_call_byte_method,
        NULL, /* CallByteMethodV */
        NULL, /* CallByteMethodA */
-       NULL, /* CallCharMethod */
+       vm_jni_call_char_method,
        NULL, /* CallCharMethodV */
 
        /* 45 */
        NULL, /* CallCharMethodA */
-       NULL, /* CallShortMethod */
+       vm_jni_call_short_method,
        NULL, /* CallShortMethodV */
        NULL, /* CallShortMethodA */
        vm_jni_call_int_method,
@@ -1096,15 +1041,15 @@ void *vm_jni_native_interface[] = {
        /* 50 */
        NULL, /* CallIntMethodV */
        NULL, /* CallIntMethodA */
-       NULL, /* CallLongMethod */
+       vm_jni_call_long_method,
        NULL, /* CallLongMethodV */
        NULL, /* CallLongMethodA */
 
        /* 55 */
-       NULL, /* CallFloatMethod */
+       vm_jni_call_float_method,
        NULL, /* CallFloatMethodV */
        NULL, /* CallFloatMethodA */
-       NULL, /* CallDoubleMethod */
+       vm_jni_call_double_method,
        NULL, /* CallDoubleMethodV */
 
        /* 60 */
@@ -1188,36 +1133,36 @@ void *vm_jni_native_interface[] = {
        vm_jni_call_static_object_method_v,
        NULL, /* CallStaticObjectMethodA */
        vm_jni_call_static_boolean_method,
-       NULL, /* CallStaticBooleanMethodV */
+       vm_jni_call_static_boolean_method_v,
        NULL, /* CallStaticBooleanMethodA */
 
        /* 120 */
        vm_jni_call_static_byte_method,
        vm_jni_call_static_byte_method_v,
        NULL, /* CallStaticByteMethodA */
-       NULL, /* CallStaticCharMethod */
-       NULL, /* CallStaticCharMethodV */
+       vm_jni_call_static_char_method,
+       vm_jni_call_static_char_method_v,
 
        /* 125 */
        NULL, /* CallStaticCharMethodA */
-       NULL, /* CallStaticShortMethod */
+       vm_jni_call_static_short_method,
        vm_jni_call_static_short_method_v,
        NULL, /* CallStaticShortMethodA */
-       NULL, /* CallStaticIntMethod */
+       vm_jni_call_static_int_method,
 
        /* 130 */
-       NULL, /* CallStaticIntMethodV */
+       vm_jni_call_static_int_method_v,
        NULL, /* CallStaticIntMethodA */
-       NULL, /* CallStaticLongMethod */
-       NULL, /* CallStaticLongMethodV */
+       vm_jni_call_static_long_method,
+       vm_jni_call_static_long_method_v,
        NULL, /* CallStaticLongMethodA */
 
        /* 135 */
-       NULL, /* CallStaticFloatMethod */
-       NULL, /* CallStaticFloatMethodV */
+       vm_jni_call_static_float_method,
+       vm_jni_call_static_float_method_v,
        NULL, /* CallStaticFloatMethodA */
-       NULL, /* CallStaticDoubleMethod */
-       NULL, /* CallStaticDoubleMethodV */
+       vm_jni_call_static_double_method,
+       vm_jni_call_static_double_method_v,
 
        /* 140 */
        NULL, /* CallStaticDoubleMethodA */
diff --git a/vm/reflection.c b/vm/reflection.c
index 4828ac5..790dce8 100644
--- a/vm/reflection.c
+++ b/vm/reflection.c
@@ -455,7 +455,7 @@ native_constructor_construct_native(struct vm_object *this,
        if (marshall_call_arguments(vmm, args + 1, args_array))
                return NULL;
 
-       vm_call_method_a(vmm, args);
+       vm_call_method_a(vmm, args, NULL);
        return result;
 }
 
@@ -629,9 +629,10 @@ jint native_field_get_modifiers_internal(struct vm_object 
*this)
 }
 
 static int unwrap(void *field_ptr, enum vm_type type,
-                               struct vm_object *value)
+                 struct vm_object *value)
 {
        unsigned long args[] = { (unsigned long) value };
+       union jvalue result;
 
        switch (type) {
        case J_REFERENCE:
@@ -646,12 +647,12 @@ static int unwrap(void *field_ptr, enum vm_type type,
                 * We can handle those as int because these values are
                 * returned by ireturn anyway.
                 */
-               *(long *) field_ptr = 
vm_call_method_this_a(vm_java_lang_Number_intValue,
-                                                           value, args);
+               vm_call_method_this_a(vm_java_lang_Number_intValue, value, 
args, &result);
+               *(long *) field_ptr = result.i;
                return 0;
        case J_FLOAT:
-               *(jfloat *) field_ptr = (jfloat) 
vm_call_method_this_a(vm_java_lang_Number_floatValue,
-                                                                      value, 
args);
+               vm_call_method_this_a(vm_java_lang_Number_floatValue, value, 
args, &result);
+               *(jfloat *) field_ptr = result.f;
                return 0;
        case J_LONG:
        case J_DOUBLE:
@@ -741,23 +742,27 @@ call_virtual_method(struct vm_method *vmm, struct 
vm_object *o,
                    struct vm_object *args_array)
 {
        unsigned long args[vmm->args_count];
+       union jvalue result;
 
        args[0] = (unsigned long) o;
        if (marshall_call_arguments(vmm, args + 1, args_array))
                return NULL;
 
-       return (struct vm_object *) vm_call_method_this_a(vmm, o, args);
+       vm_call_method_this_a(vmm, o, args, &result);
+       return result.l;
 }
 
 static struct vm_object *
 call_static_method(struct vm_method *vmm, struct vm_object *args_array)
 {
        unsigned long args[vmm->args_count];
+       union jvalue result;
 
        if (marshall_call_arguments(vmm, args, args_array))
                return NULL;
 
-       return (struct vm_object *) vm_call_method_a(vmm, args);
+       vm_call_method_a(vmm, args, &result);
+       return result.l;
 }
 
 jint native_method_get_modifiers_internal(struct vm_object *this)
-- 
1.6.0.4


------------------------------------------------------------------------------
Come build with us! The BlackBerry(R) Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay 
ahead of the curve. Join us from November 9 - 12, 2009. Register now!
http://p.sf.net/sfu/devconference
_______________________________________________
Jatovm-devel mailing list
Jatovm-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jatovm-devel

Reply via email to