Some exception classes have dedicated constructors for setting
exception's cause. For such classes we shouldn't set the cause with
initCause() bacuuse the cause might be stored somewhere else than
Throwable.cause. See for example java/lang/ExceptionInInitializerError
class.

Signed-off-by: Tomek Grabiec <tgrab...@gmail.com>
---
 jit/exception.c       |   39 +++++++++++++++++++++++++++++++++++----
 test/vm/class-stub.c  |    6 ++++++
 test/vm/object-stub.c |    5 +++++
 3 files changed, 46 insertions(+), 4 deletions(-)

diff --git a/jit/exception.c b/jit/exception.c
index ae1a889..b1deb30 100644
--- a/jit/exception.c
+++ b/jit/exception.c
@@ -107,19 +107,50 @@ int signal_new_exception(struct vm_class *vmc, const char 
*msg)
        return 0;
 }
 
-typedef struct vm_object * (*vm_throwable_init_cause_fn)(struct vm_object *,
-                                                        struct vm_object *);
-
 int signal_new_exception_with_cause(struct vm_class *vmc,
                                    struct vm_object *cause,
                                    const char *msg)
 {
-       struct vm_object *exception = new_exception(vmc, msg);
+       struct vm_object *exception;
+       struct vm_method *init;
+
+       /*
+        * Some exception classes have dedicated constructors for
+        * setting exception's cause. For such classes we shouldn't
+        * set the cause with initCause(). See for example
+        * java/lang/ExceptionInInitializerError class.
+        */
+       init = vm_class_get_method(vmc, "<init>", "(Ljava/lang/Throwable;)V");
+       if (init) {
+               exception = vm_object_alloc(
+                               vm_java_lang_ExceptionInInitializerError);
+               if (!exception) {
+                       NOT_IMPLEMENTED;
+                       return -1;
+               }
+
+               clear_exception();
+
+               vm_call_method(init, exception, cause);
+
+               if (exception_occurred())
+                       return -1;
+
+               signal_exception(exception);
+               return 0;
+       }
 
+       exception = new_exception(vmc, msg);
        if (!exception)
                return -1;
 
+       clear_exception();
+
        vm_call_method(vm_java_lang_Throwable_initCause, exception, cause);
+
+       if (exception_occurred())
+               return -1;
+
        signal_exception(exception);
        return 0;
 }
diff --git a/test/vm/class-stub.c b/test/vm/class-stub.c
index 05645e9..d8a0c29 100644
--- a/test/vm/class-stub.c
+++ b/test/vm/class-stub.c
@@ -45,3 +45,9 @@ bool vm_class_is_assignable_from(const struct vm_class *vmc,
 {
        return false;
 }
+
+struct vm_method *vm_class_get_method(const struct vm_class *vmc,
+       const char *name, const char *type)
+{
+       return NULL;
+}
diff --git a/test/vm/object-stub.c b/test/vm/object-stub.c
index 1b051af..536b1ad 100644
--- a/test/vm/object-stub.c
+++ b/test/vm/object-stub.c
@@ -68,3 +68,8 @@ void array_size_check(int size)
 void multiarray_size_check(int n, ...)
 {
 }
+
+struct vm_object *vm_object_alloc(struct vm_class *class)
+{
+       return NULL;
+}
-- 
1.6.0.6


------------------------------------------------------------------------------
_______________________________________________
Jatovm-devel mailing list
Jatovm-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jatovm-devel

Reply via email to