These functions are necessary to implement JNI interface functions for calling java methods.
Signed-off-by: Tomek Grabiec <tgrab...@gmail.com> --- Makefile | 3 +- arch/x86/include/arch/call.h | 31 ++++++++++++++ include/vm/call.h | 13 ++++++ vm/call.c | 93 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 139 insertions(+), 1 deletions(-) create mode 100644 arch/x86/include/arch/call.h create mode 100644 include/vm/call.h create mode 100644 vm/call.c diff --git a/Makefile b/Makefile index 7239e30..579afa6 100644 --- a/Makefile +++ b/Makefile @@ -119,7 +119,8 @@ VM_OBJS = \ vm/preload.o \ vm/fault-inject.o \ vm/jni.o \ - vm/jni-interface.o + vm/jni-interface.o \ + vm/call.o LIB_OBJS = \ lib/bitset.o \ diff --git a/arch/x86/include/arch/call.h b/arch/x86/include/arch/call.h new file mode 100644 index 0000000..a9037ec --- /dev/null +++ b/arch/x86/include/arch/call.h @@ -0,0 +1,31 @@ +#ifndef __X86_CALL_H +#define __X86_CALL_H + +#ifdef CONFIG_X86_32 +/** + * This calls a function (@target) with call arguments copied from + * @args array. The array contains @args_count elements of machine + * word size. The call result will be stored in @result. + */ +#define native_call(target, args, args_count, result) { \ + __asm__ volatile ( \ + "movl %2, %%esi \n" \ + "movl %1, %%ecx \n" \ + "subl %%ecx, %%esp \n" \ + "movl %%esp, %%edi \n" \ + "cld \n" \ + "rep movsb \n" \ + "movl %%ecx, %%esi \n" \ + "call *%3 \n" \ + "addl %%esi, %%esp \n" \ + "movl %%eax, %0 \n" \ + : "=r" (result) \ + : "r" (sizeof(long) * args_count), "r"(args), "m"(target) \ + : "%ecx", "%esi", "%eax", "cc", "memory" \ + ); \ + } +#else + #error NOT IMPLEMENTED +#endif + +#endif /* __X86_CALL_H */ diff --git a/include/vm/call.h b/include/vm/call.h new file mode 100644 index 0000000..c1ed6bd --- /dev/null +++ b/include/vm/call.h @@ -0,0 +1,13 @@ +#ifndef JATO_VM_CALL_H +#define JATO_VM_CALL_H + +#include <stdarg.h> +#include <stdint.h> + +struct vm_method; +struct vm_object; + +unsigned long vm_call_method(struct vm_method *method, ...); +unsigned long vm_call_method_v(struct vm_method *method, va_list args); + +#endif diff --git a/vm/call.c b/vm/call.c new file mode 100644 index 0000000..83c0bb4 --- /dev/null +++ b/vm/call.c @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2008 Tomasz Grabiec + * + * This file is released under the GPL version 2 with the following + * clarification and special exception: + * + * Linking this library statically or dynamically with other modules is + * making a combined work based on this library. Thus, the terms and + * conditions of the GNU General Public License cover the whole + * combination. + * + * As a special exception, the copyright holders of this library give you + * permission to link this library with independent modules to produce an + * executable, regardless of the license terms of these independent + * modules, and to copy and distribute the resulting executable under terms + * of your choice, provided that you also meet, for each linked independent + * module, the terms and conditions of the license of that module. An + * independent module is a module which is not derived from or based on + * this library. If you modify this library, you may extend this exception + * to your version of the library, but you are not obligated to do so. If + * you do not wish to do so, delete this exception statement from your + * version. + * + * Please refer to the file LICENSE for details. + */ + +#include <stdlib.h> +#include <stdarg.h> +#include <stdio.h> + +#include "arch/call.h" + +#include "vm/call.h" +#include "vm/class.h" +#include "vm/jni.h" +#include "vm/method.h" +#include "vm/object.h" + +static unsigned long +vm_call_method_a(struct vm_method *method, unsigned long *args) +{ + unsigned long result; + + void (*trampoline)(void) = vm_method_trampoline_ptr(method); + + native_call(trampoline, args, method->args_count, result); + + return result; +} + + +static unsigned long +vm_call_jni_method_v(struct vm_method *method, va_list args) +{ + unsigned long args_array[method->args_count]; + int i; + + i = 0; + args_array[i++] = (unsigned long)vm_jni_get_jni_env(); + + if (vm_method_is_static(method)) + args_array[i++] = (unsigned long)method->class->object; + + while (i < method->args_count) + args_array[i++] = va_arg(args, long); + + return vm_call_method_a(method, args_array); +} + +unsigned long vm_call_method_v(struct vm_method *method, va_list args) +{ + unsigned long args_array[method->args_count]; + + if (vm_method_is_jni(method)) + return vm_call_jni_method_v(method, args); + + for (int i = 0; i < method->args_count; i++) + args_array[i] = va_arg(args, unsigned long); + + return vm_call_method_a(method, args_array); +} + +unsigned long vm_call_method(struct vm_method *method, ...) +{ + unsigned long result; + va_list args; + + va_start(args, method); + result = vm_call_method_v(method, args); + va_end(args); + + return result; +} -- 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