Signed-off-by: Tomek Grabiec <[email protected]>
---
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
[email protected]
https://lists.sourceforge.net/lists/listinfo/jatovm-devel