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

Reply via email to