The ->args_count is now correctly set for JNI methods
to include the JNI environment pointer (for all JNI methods)
and a class object pointer (for static JNI methods).

Argument passing for JNI methods is now done in convert_args()
to let JNI arguments to be passed in registers like for
other methods.

Signed-off-by: Tomek Grabiec <tgrab...@gmail.com>
---
 include/vm/method.h |    2 +-
 jit/args.c          |   37 ++++++++++++++++++++++++++++++++++
 jit/invoke-bc.c     |   55 ++++++++++++++------------------------------------
 jit/trace-jit.c     |    2 +-
 vm/method.c         |   36 ++++++++++++++++++--------------
 5 files changed, 75 insertions(+), 57 deletions(-)

diff --git a/include/vm/method.h b/include/vm/method.h
index 18626b8..c05c94c 100644
--- a/include/vm/method.h
+++ b/include/vm/method.h
@@ -84,7 +84,7 @@ static inline bool method_is_virtual(struct vm_method *vmm)
                | CAFEBABE_METHOD_ACC_PRIVATE)) == 0;
 }
 
-static inline bool vm_method_is_jni_method(struct vm_method *vmm)
+static inline bool vm_method_is_jni(struct vm_method *vmm)
 {
        return vmm->method->access_flags & CAFEBABE_METHOD_ACC_NATIVE
                && !vmm->vm_native_ptr;
diff --git a/jit/args.c b/jit/args.c
index 27d00bf..3122e66 100644
--- a/jit/args.c
+++ b/jit/args.c
@@ -33,6 +33,7 @@
 
 #include "vm/method.h"
 #include "vm/stack.h"
+#include "vm/jni.h"
 
 struct expression *
 insert_arg(struct expression *root,
@@ -75,11 +76,47 @@ struct expression *convert_args(struct stack *mimic_stack,
        if (err)
                return NULL;
 
+       if (vm_method_is_jni(method)) {
+               if (vm_method_is_static(method))
+                       --nr_args;
+
+               --nr_args;
+       }
+
        for (i = 0; i < nr_args; i++) {
                struct expression *expr = stack_pop(mimic_stack);
                args_list = insert_arg(args_list, expr, &args_state, method);
        }
 
+       if (vm_method_is_jni(method)) {
+               struct expression *jni_env_expr;
+
+               if (vm_method_is_static(method)) {
+                       struct expression *class_expr;
+
+                       class_expr = value_expr(J_REFERENCE,
+                                       (unsigned long) method->class->object);
+
+                       if (!class_expr) {
+                               expr_put(args_list);
+                               return NULL;
+                       }
+
+                       args_list = insert_arg(args_list, class_expr,
+                                              &args_state, method);
+               }
+
+               jni_env_expr = value_expr(J_REFERENCE,
+                                         (unsigned long)vm_jni_get_jni_env());
+               if (!jni_env_expr) {
+                       expr_put(args_list);
+                       return NULL;
+               }
+
+               args_list = insert_arg(args_list, jni_env_expr, &args_state,
+                                      method);
+       }
+
        args_finish(&args_state);
 
   out:
diff --git a/jit/invoke-bc.c b/jit/invoke-bc.c
index 7441c64..016d1ce 100644
--- a/jit/invoke-bc.c
+++ b/jit/invoke-bc.c
@@ -23,6 +23,7 @@
 
 #include <string.h>
 #include <errno.h>
+#include <stdio.h>
 
 int convert_xreturn(struct parse_context *ctx)
 {
@@ -133,6 +134,17 @@ static void null_check_first_arg(struct expression *arg)
                null_check_first_arg(to_expr(arg->args_right));
 }
 
+/* Replaces second argument with null check expression on that argument */
+static void null_check_second_arg(struct expression *arg)
+{
+       assert(expr_type(arg) != EXPR_ARG);
+
+       if (expr_type(to_expr(arg->args_right)) == EXPR_ARG)
+               null_check_first_arg(to_expr(arg->args_left));
+
+       null_check_second_arg(to_expr(arg->args_right));
+}
+
 int convert_invokeinterface(struct parse_context *ctx)
 {
        struct vm_method *invoke_target;
@@ -206,14 +218,6 @@ int convert_invokevirtual(struct parse_context *ctx)
        return err;
 }
 
-static void append_arg(struct expression *expr, struct expression *arg)
-{
-       struct expression *args_list;
-
-       args_list = insert_arg(to_expr(expr->args_list), arg, NULL, NULL);
-       expr->args_list = &args_list->node;
-}
-
 int convert_invokespecial(struct parse_context *ctx)
 {
        struct vm_method *invoke_target;
@@ -236,18 +240,10 @@ int convert_invokespecial(struct parse_context *ctx)
        if (err)
                goto failed;
 
-       null_check_first_arg(to_expr(expr->args_list));
-
-       if (vm_method_is_jni_method(invoke_target)) {
-               struct expression *jni_env_expr;
-
-               jni_env_expr = value_expr(J_REFERENCE,
-                       (unsigned long)vm_jni_get_jni_env());
-               if (!jni_env_expr)
-                       goto failed;
-
-               append_arg(expr, jni_env_expr);
-       }
+       if (vm_method_is_jni(invoke_target))
+               null_check_second_arg(to_expr(expr->args_list));
+       else
+               null_check_first_arg(to_expr(expr->args_list));
 
        err = insert_invoke_expr(ctx, expr);
        if (err)
@@ -281,25 +277,6 @@ int convert_invokestatic(struct parse_context *ctx)
        if (err)
                goto failed;
 
-       if (vm_method_is_jni_method(invoke_target)) {
-               struct expression *jni_env_expr;
-               struct expression *class_expr;
-
-               class_expr = value_expr(J_REFERENCE,
-                       (unsigned long)invoke_target->class->object);
-               if (!class_expr)
-                       goto failed;
-
-               append_arg(expr, class_expr);
-
-               jni_env_expr = value_expr(J_REFERENCE,
-                       (unsigned long)vm_jni_get_jni_env());
-               if (!jni_env_expr)
-                       goto failed;
-
-               append_arg(expr, jni_env_expr);
-       }
-
        err = insert_invoke_expr(ctx, expr);
        if (err)
                goto failed;
diff --git a/jit/trace-jit.c b/jit/trace-jit.c
index 2ea9c13..3e649a6 100644
--- a/jit/trace-jit.c
+++ b/jit/trace-jit.c
@@ -326,7 +326,7 @@ static void trace_invoke_args(struct vm_method *vmm,
        const char *type_str;
        int arg_index;
 
-       if (vm_method_is_jni_method(vmm))
+       if (vm_method_is_jni(vmm))
                arg_index += 2;
 
        arg_index = 0;
diff --git a/vm/method.c b/vm/method.c
index 5727475..1c4befa 100644
--- a/vm/method.c
+++ b/vm/method.c
@@ -73,6 +73,20 @@ int vm_method_init(struct vm_method *vmm,
        if (!vm_method_is_static(vmm))
                ++vmm->args_count;
 
+       vmm->vm_native_ptr = NULL;
+
+       if (vm_method_is_native(vmm)) {
+               vmm->vm_native_ptr =
+                       vm_lookup_native(vmm->class->name, vmm->name);
+
+               if (vm_method_is_jni(vmm)) {
+                       if (vm_method_is_static(vmm))
+                               ++vmm->args_count;
+
+                       ++vmm->args_count;
+               }
+       }
+
        /*
         * Note: We can return here because the rest of the function deals
         * with loading attributes which native and abstract methods don't have.
@@ -136,24 +150,14 @@ int vm_method_prepare_jit(struct vm_method *vmm)
                return -1;
        }
 
-       if (!vm_method_is_native(vmm))
-               goto link_later;
-
-       vmm->vm_native_ptr = NULL;
-
-       void *native_ptr = vm_lookup_native(vmm->class->name, vmm->name);
-       if (native_ptr) {
-               vmm->vm_native_ptr = native_ptr;
-
-               if (add_cu_mapping((unsigned long)native_ptr,
-                                  vmm->compilation_unit))
-               {
-                       NOT_IMPLEMENTED;
-                       return -1;
-               }
+       if (vmm->vm_native_ptr &&
+           add_cu_mapping((unsigned long)vmm->vm_native_ptr,
+                          vmm->compilation_unit))
+       {
+               NOT_IMPLEMENTED;
+               return -1;
        }
 
-link_later:
        vmm->trampoline = build_jit_trampoline(vmm->compilation_unit);
        if (!vmm->trampoline) {
                NOT_IMPLEMENTED;
-- 
1.6.0.6


------------------------------------------------------------------------------
Enter the BlackBerry Developer Challenge  
This is your chance to win up to $100,000 in prizes! For a limited time, 
vendors submitting new applications to BlackBerry App World(TM) will have
the opportunity to enter the BlackBerry Developer Challenge. See full prize  
details at: http://p.sf.net/sfu/Challenge
_______________________________________________
Jatovm-devel mailing list
Jatovm-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jatovm-devel

Reply via email to