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