Signed-off-by: Tomek Grabiec <tgrab...@gmail.com>
---
 arch/x86/call.c                              |   50 ++++++++++++++++++++++++++
 include/vm/types.h                           |    5 +++
 regression/java/lang/reflect/MethodTest.java |    5 +++
 runtime/reflection.c                         |    4 ++-
 4 files changed, 63 insertions(+), 1 deletions(-)

diff --git a/arch/x86/call.c b/arch/x86/call.c
index 389b1a6..064bfdf 100644
--- a/arch/x86/call.c
+++ b/arch/x86/call.c
@@ -83,6 +83,54 @@ static void native_call_eax(struct vm_method *method, void 
*target,
         : "%ecx", "%edi", "cc", "memory");
 }
 
+static void native_call_long(struct vm_method *method, void *target,
+                            unsigned long *args, union jvalue *result)
+{
+       __asm__ volatile
+               (
+        "movl %%ebx, %%ecx \n"
+        "shl $2, %%ebx \n"
+        "subl %%ebx, %%esp \n"
+        "movl %%esp, %%edi \n"
+        "cld \n"
+        "rep movsd \n"
+        "mov %%ebx, %%esi \n"
+
+        "test %4, %4 \n"
+        "jz 1f \n"
+
+        "pushl %%esp \n"
+        "pushl %2 \n"
+        "call vm_enter_vm_native \n"
+        "addl $8, %%esp \n"
+        "test %%eax, %%eax \n"
+        "jnz 2f \n"
+
+        "call *%2 \n"
+        "movl %3, %%edi \n"
+        "movl %%eax, (%%edi) \n"
+        "movl %%edx, 4(%%edi) \n"
+
+        "call vm_leave_vm_native \n"
+        "jmp 2f \n"
+"1: \n"
+        "call *%2 \n"
+        "movl %3, %%edi \n"
+        "movl %%eax, (%%edi) \n"
+        "movl %%edx, 4(%%edi) \n"
+
+"2: \n"
+
+        "addl %%esi, %%esp \n"
+        :
+        : "b" (method->args_count),
+          "S" (args),
+          "m" (target),
+          "m" (result),
+          "r" (vm_method_is_vm_native(method))
+        : "%ecx", "%edi", "cc", "memory");
+}
+
 /**
  * This calls a function with call arguments copied from @args
  * array. The array contains @args_count elements of machine word
@@ -121,6 +169,8 @@ void native_call(struct vm_method *method, void *target,
                result->i = (jint) result->z;
                break;
        case J_LONG:
+               native_call_long(method, target, args, result);
+               break;
        case J_DOUBLE:
        case J_FLOAT:
                error("not implemented");
diff --git a/include/vm/types.h b/include/vm/types.h
index 1f3350b..2b21e2a 100644
--- a/include/vm/types.h
+++ b/include/vm/types.h
@@ -81,4 +81,9 @@ static inline enum vm_type mimic_stack_type(enum vm_type type)
        }
 }
 
+static inline int get_arg_size(enum vm_type type)
+{
+       return get_vmtype_size(type) / sizeof(unsigned long);
+}
+
 #endif
diff --git a/regression/java/lang/reflect/MethodTest.java 
b/regression/java/lang/reflect/MethodTest.java
index 14dbaa5..2bfbb55 100644
--- a/regression/java/lang/reflect/MethodTest.java
+++ b/regression/java/lang/reflect/MethodTest.java
@@ -51,6 +51,10 @@ public class MethodTest extends TestCase {
       public static int intIncrement(int x) {
           return x + 1;
       }
+
+      public static long longIncrement(long x) {
+          return x + 1;
+      }
     }
 
     public static Object invoke(String name, Class arg_class, Object arg) {
@@ -64,6 +68,7 @@ public class MethodTest extends TestCase {
 
     public static void testMethodReflectionInvoke() {
         assertObjectEquals(Integer.valueOf(2), invoke("intIncrement", 
int.class, Integer.valueOf(1)));
+        assertObjectEquals(Long.valueOf(0xdeadbeefcafebabfl), 
invoke("longIncrement", long.class, Long.valueOf(0xdeadbeefcafebabel)));
     }
 
     public static void main(String[] args) throws Exception {
diff --git a/runtime/reflection.c b/runtime/reflection.c
index 3d67aba..7aa927b 100644
--- a/runtime/reflection.c
+++ b/runtime/reflection.c
@@ -747,8 +747,10 @@ static int marshall_call_arguments(struct vm_method *vmm, 
unsigned long *args,
                struct vm_object *arg_obj;
 
                arg_obj = array_get_field_ptr(args_array, args_array_idx++);
-               if (unwrap(&args[idx++], arg->type_info.vm_type, arg_obj))
+               if (unwrap(&args[idx], arg->type_info.vm_type, arg_obj))
                        return -1;
+
+               idx += get_arg_size(arg->type_info.vm_type);
        }
 
        return 0;
-- 
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