Signed-off-by: Tomek Grabiec <tgrab...@gmail.com> --- include/vm/call.h | 4 ++ include/vm/reflection.h | 6 +++ vm/call.c | 24 +++++++++---- vm/jato.c | 1 + vm/reflection.c | 93 +++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 121 insertions(+), 7 deletions(-)
diff --git a/include/vm/call.h b/include/vm/call.h index 71531db..c6e6f39 100644 --- a/include/vm/call.h +++ b/include/vm/call.h @@ -13,6 +13,10 @@ 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); #define DECLARE_VM_CALL_METHOD(type, suffix) \ static inline type \ diff --git a/include/vm/reflection.h b/include/vm/reflection.h index 6894387..198268d 100644 --- a/include/vm/reflection.h +++ b/include/vm/reflection.h @@ -28,4 +28,10 @@ struct vm_object *native_vmclass_get_interfaces(struct vm_object *clazz); struct vm_object *native_vmclass_get_superclass(struct vm_object *clazz); struct vm_object *native_field_get(struct vm_object *this, struct vm_object *o); +struct vm_object * +native_method_invokenative(struct vm_object *method, struct vm_object *o, + struct vm_object *args, + struct vm_object *declaringClass, + jint slot); + #endif /* __JATO_VM_REFLECTION_H */ diff --git a/vm/call.c b/vm/call.c index c286ac8..419e13d 100644 --- a/vm/call.c +++ b/vm/call.c @@ -39,11 +39,10 @@ #include "vm/stack-trace.h" static unsigned long -vm_call_method_a(struct vm_method *method, unsigned long *args) +call_method_a(struct vm_method *method, void *target, unsigned long *args) { struct vm_object *exception; unsigned long result; - void *target; /* * XXX: We cannot call JIT code with exception signalled @@ -55,13 +54,10 @@ vm_call_method_a(struct vm_method *method, unsigned long *args) clear_exception(); if (vm_method_is_vm_native(method)) { - target = vm_method_native_ptr(method); vm_native_call(target, args, method->args_count, result); goto out; } - target = vm_method_call_ptr(method); - native_call(target, args, method->args_count, result); out: @@ -78,7 +74,21 @@ unsigned long vm_call_method_v(struct vm_method *method, va_list 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); + void *target = vm_method_call_ptr(method); + return call_method_a(method, target, args_array); +} + +unsigned long vm_call_method_this_a(struct vm_method *method, + struct vm_object *this, + unsigned long *args) +{ + void *target = this->class->vtable.native_ptr[method->virtual_index]; + return call_method_a(method, target, args); +} + +unsigned long vm_call_method_a(struct vm_method *method, unsigned long *args) +{ + return call_method_a(method, vm_method_call_ptr(method), args); } unsigned long vm_call_method_this_v(struct vm_method *method, @@ -92,5 +102,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_a(method, args_array); + return vm_call_method_this_a(method, this, args_array); } diff --git a/vm/jato.c b/vm/jato.c index 33f7f90..e18cf62 100644 --- a/vm/jato.c +++ b/vm/jato.c @@ -785,6 +785,7 @@ static struct vm_native natives[] = { DEFINE_NATIVE("java/lang/reflect/Constructor", "constructNative", &native_constructor_construct_native), DEFINE_NATIVE("java/lang/reflect/Field", "get", &native_field_get), DEFINE_NATIVE("java/lang/reflect/Method", "getParameterTypes", &native_method_get_parameter_types), + DEFINE_NATIVE("java/lang/reflect/Method", "invokeNative", &native_method_invokenative), DEFINE_NATIVE("jato/internal/VM", "enableFault", &native_vm_enable_fault), DEFINE_NATIVE("jato/internal/VM", "disableFault", &native_vm_disable_fault), }; diff --git a/vm/reflection.c b/vm/reflection.c index be9a97f..c84eb49 100644 --- a/vm/reflection.c +++ b/vm/reflection.c @@ -549,3 +549,96 @@ struct vm_object *native_field_get(struct vm_object *this, struct vm_object *o) return encapsulate_value(value_p, type); } + +static int marshall_call_arguments(struct vm_method *vmm, unsigned long *args, + struct vm_object *args_array) +{ + enum vm_type type; + const char *type_str; + char *type_name; + int args_array_idx; + int idx; + + type_str = vmm->type; + idx = 0; + args_array_idx = 0; + + if (args_array == NULL) + return 0; + + while ((type_str = parse_method_args(type_str, &type, &type_name))) { + struct vm_object *arg; + + arg = array_get_field_ptr(args_array, args_array_idx++); + + if (type == J_REFERENCE) + *(jobject *) &args[idx++] = arg; + else { + /* XXX: marshalling of primitive types not + implemented yet. */ + error("primitive type marshalling not implemented"); + } + } + + return 0; +} + +static struct vm_object * +call_virtual_method(struct vm_method *vmm, struct vm_object *o, + struct vm_object *args_array) +{ + unsigned long args[vmm->args_count]; + + if (marshall_call_arguments(vmm, args, args_array)) + return NULL; + + return (struct vm_object *) vm_call_method_this_a(vmm, o, args); +} + +static struct vm_object * +call_static_method(struct vm_method *vmm, struct vm_object *args_array) +{ + unsigned long args[vmm->args_count]; + + if (marshall_call_arguments(vmm, args, args_array)) + return NULL; + + return (struct vm_object *) vm_call_method_a(vmm, args); +} + +struct vm_object * +native_method_invokenative(struct vm_object *method, struct vm_object *o, + struct vm_object *args, + struct vm_object *declaringClass, + jint slot) +{ + struct vm_method *vmm; + struct vm_class *vmc; + + vmc = to_vmclass(declaringClass); + if (!vmc) + return NULL; + + if (slot < 0 || slot >= vmc->class->methods_count) + goto throw_illegal; + + vmm = &vmc->methods[slot]; + + if (vm_method_is_static(vmm)) { + return call_static_method(vmm, args); + } + + if (!o) { + signal_new_exception(vm_java_lang_NullPointerException, NULL); + return NULL; + } + + if (!vm_object_is_instance_of(o, vmc)) + goto throw_illegal; + + return call_virtual_method(vmm, o, args); + + throw_illegal: + signal_new_exception(vm_java_lang_IllegalArgumentException, NULL); + return NULL; +} -- 1.6.0.6 ------------------------------------------------------------------------------ Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day trial. Simplify your report design, integration and deployment - and focus on what you do best, core application coding. Discover what's new with Crystal Reports now. http://p.sf.net/sfu/bobj-july _______________________________________________ Jatovm-devel mailing list Jatovm-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/jatovm-devel