* src/vmcore/linker.c (build_display): Removed superfluous recursion; return
[cacao.git] / src / vm / exceptions.c
index 79dca438c8ca953ade9307b6a5c90e75786e8f3b..d258329c1f8c538ffe476884da8e0f4d2ecfd09a 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/exceptions.c - exception related functions
 
-   Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
-   C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
-   E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
-   J. Wenninger, Institut f. Computersprachen - TU Wien
+   Copyright (C) 1996-2005, 2006, 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
@@ -22,8 +20,6 @@
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   $Id: exceptions.c 8056 2007-06-10 14:49:57Z michi $
-
 */
 
 
@@ -33,7 +29,6 @@
 #include <string.h>
 #include <stdarg.h>
 #include <stdlib.h>
-#include <unistd.h>
 #include <sys/mman.h>
 
 #include "vm/types.h"
 #include "mm/memory.h"
 
 #include "native/jni.h"
+#include "native/llni.h"
 #include "native/native.h"
+
 #include "native/include/java_lang_String.h"
+#include "native/include/java_lang_Thread.h"
 #include "native/include/java_lang_Throwable.h"
 
 #include "threads/lock-common.h"
-#include "threads/threads-common.h"
+#include "threads/thread.h"
 
-#include "toolbox/logging.h"
 #include "toolbox/util.h"
 
 #include "vm/builtin.h"
 #include "vm/vm.h"
 
 #include "vm/jit/asmpart.h"
-#include "vm/jit/disass.h"
 #include "vm/jit/jit.h"
 #include "vm/jit/methodheader.h"
+#include "vm/jit/patcher-common.h"
+#include "vm/jit/show.h"
 #include "vm/jit/stacktrace.h"
+#include "vm/jit/trace.h"
 
 #include "vmcore/class.h"
 #include "vmcore/loader.h"
+#include "vmcore/method.h"
 #include "vmcore/options.h"
+#include "vmcore/system.h"
 
 #if defined(ENABLE_VMLOG)
 #include <vmlog_cacao.h>
 /* for raising exceptions from native methods *********************************/
 
 #if !defined(ENABLE_THREADS)
-java_objectheader *_no_threads_exceptionptr = NULL;
+java_object_t *_no_threads_exceptionptr = NULL;
 #endif
 
 
-/* init_system_exceptions ******************************************************
+/* exceptions_get_exception ****************************************************
 
-   Load and link exceptions used in the system.
+   Returns the current exception pointer of the current thread.
 
 *******************************************************************************/
 
-bool exceptions_init(void)
+java_handle_t *exceptions_get_exception(void)
 {
-       int pagesize;
-
-       /* mmap a memory page at address 0x0, so our hardware-exceptions
-          work. */
+       java_object_t *o;
+       java_handle_t *e;
+#if defined(ENABLE_THREADS)
+       threadobject  *t;
 
-       pagesize = getpagesize();
+       t = THREADOBJECT;
+#endif
 
-       (void) memory_mmap_anon(NULL, pagesize, PROT_NONE, MAP_PRIVATE | MAP_FIXED);
+       /* Get the exception. */
 
-       /* check if we get into trouble with our hardware-exceptions */
+       LLNI_CRITICAL_START;
 
-       if (OFFSET(java_bytearray, data) <= EXCEPTION_HARDWARE_PATCHER)
-               vm_abort("signal_init: array-data offset is less or equal the maximum hardware-exception displacement: %d <= %d", OFFSET(java_bytearray, data), EXCEPTION_HARDWARE_PATCHER);
+#if defined(ENABLE_THREADS)
+       o = t->_exceptionptr;
+#else
+       o = _no_threads_exceptionptr;
+#endif
 
-       /* java/lang/Throwable */
+       e = LLNI_WRAP(o);
 
-       if (!(class_java_lang_Throwable =
-                 load_class_bootstrap(utf_java_lang_Throwable)) ||
-               !link_class(class_java_lang_Throwable))
-               return false;
+       LLNI_CRITICAL_END;
 
-       /* java/lang/Error */
+       /* Return the exception. */
 
-       if (!(class_java_lang_Error = load_class_bootstrap(utf_java_lang_Error)) ||
-               !link_class(class_java_lang_Error))
-               return false;
+       return e;
+}
 
-#if defined(ENABLE_JAVASE)
-       /* java/lang/LinkageError */
 
-       if (!(class_java_lang_LinkageError =
-                 load_class_bootstrap(utf_java_lang_LinkageError)) ||
-               !link_class(class_java_lang_LinkageError))
-               return false;
-#endif
+/* exceptions_set_exception ****************************************************
 
-       /* java/lang/NoClassDefFoundError */
+   Sets the exception pointer of the current thread.
 
-       if (!(class_java_lang_NoClassDefFoundError =
-                 load_class_bootstrap(utf_java_lang_NoClassDefFoundError)) ||
-               !link_class(class_java_lang_NoClassDefFoundError))
-               return false;
+*******************************************************************************/
 
-       /* java/lang/OutOfMemoryError */
+void exceptions_set_exception(java_handle_t *e)
+{
+       threadobject  *t;
+       java_object_t *o;
 
-       if (!(class_java_lang_OutOfMemoryError =
-                 load_class_bootstrap(utf_java_lang_OutOfMemoryError)) ||
-               !link_class(class_java_lang_OutOfMemoryError))
-               return false;
+#if defined(ENABLE_THREADS)
+       t = THREADOBJECT;
+#else
+       t = NULL;
+#endif
 
-       /* java/lang/VirtualMachineError */
+       /* Set the exception. */
 
-       if (!(class_java_lang_VirtualMachineError =
-                 load_class_bootstrap(utf_java_lang_VirtualMachineError)) ||
-               !link_class(class_java_lang_VirtualMachineError))
-               return false;
+       LLNI_CRITICAL_START;
 
+       o = LLNI_UNWRAP(e);
 
-       /* java/lang/Exception */
+#if !defined(NDEBUG)
+       if (opt_DebugExceptions) {
+               printf("[exceptions_set_exception  : t=%p, o=%p, class=",
+                          (void *) t, (void *) o);
+               class_print(o->vftbl->clazz);
+               printf("]\n");
+       }
+#endif
 
-       if (!(class_java_lang_Exception =
-                 load_class_bootstrap(utf_java_lang_Exception)) ||
-               !link_class(class_java_lang_Exception))
-               return false;
+#if defined(ENABLE_THREADS)
+       t->_exceptionptr = o;
+#else
+       _no_threads_exceptionptr = o;
+#endif
 
-       /* java/lang/ClassCastException */
+       LLNI_CRITICAL_END;
+}
 
-       if (!(class_java_lang_ClassCastException =
-                 load_class_bootstrap(utf_java_lang_ClassCastException)) ||
-               !link_class(class_java_lang_ClassCastException))
-               return false;
 
-       /* java/lang/ClassNotFoundException */
+/* exceptions_clear_exception **************************************************
 
-       if (!(class_java_lang_ClassNotFoundException =
-                 load_class_bootstrap(utf_java_lang_ClassNotFoundException)) ||
-               !link_class(class_java_lang_ClassNotFoundException))
-               return false;
+   Clears the current exception pointer of the current thread.
 
-       /* java/lang/NullPointerException */
+*******************************************************************************/
 
-       if (!(class_java_lang_NullPointerException =
-                 load_class_bootstrap(utf_java_lang_NullPointerException)) ||
-               !link_class(class_java_lang_NullPointerException))
-               return false;
+void exceptions_clear_exception(void)
+{
+       threadobject *t;
 
+#if defined(ENABLE_THREADS)
+       t = THREADOBJECT;
+#else
+       t = NULL;
+#endif
 
-#if defined(WITH_CLASSPATH_GNU)
-       /* java/lang/VMThrowable */
+       /* Set the exception. */
 
-       if (!(class_java_lang_VMThrowable =
-                 load_class_bootstrap(utf_java_lang_VMThrowable)) ||
-               !link_class(class_java_lang_VMThrowable))
-               return false;
+#if !defined(NDEBUG)
+       if (opt_DebugExceptions) {
+               printf("[exceptions_clear_exception: t=%p]\n", (void *) t);
+       }
 #endif
 
-       return true;
+#if defined(ENABLE_THREADS)
+       t->_exceptionptr = NULL;
+#else
+       _no_threads_exceptionptr = NULL;
+#endif
 }
 
 
-/* exceptions_new_class ********************************************************
-
-   Creates an exception object from the given class and initalizes it.
+/* exceptions_get_and_clear_exception ******************************************
 
-   IN:
-      class....class pointer
+   Gets the exception pointer of the current thread and clears it.
+   This function may return NULL.
 
 *******************************************************************************/
 
-static java_objectheader *exceptions_new_class(classinfo *c)
+java_handle_t *exceptions_get_and_clear_exception(void)
 {
-       java_objectheader *o;
+       java_handle_t *o;
 
-       o = native_new_and_init(c);
+       /* Get the exception... */
 
-       if (o == NULL)
-               return *exceptionptr;
+       o = exceptions_get_exception();
+
+       /* ...and clear the exception if it is set. */
+
+       if (o != NULL)
+               exceptions_clear_exception();
+
+       /* return the exception */
 
        return o;
 }
 
 
-/* exceptions_new_utf **********************************************************
+/* exceptions_abort ************************************************************
 
-   Creates an exception object with the given name and initalizes it.
+   Prints exception to be thrown and aborts.
 
    IN:
-      classname....class name in UTF-8
+      classname....class name
+      message......exception message
 
 *******************************************************************************/
 
-static java_objectheader *exceptions_new_utf(utf *classname)
+static void exceptions_abort(utf *classname, utf *message)
 {
-       classinfo         *c;
-       java_objectheader *o;
+       log_println("exception thrown while VM is initializing: ");
 
-       c = load_class_bootstrap(classname);
+       log_start();
+       utf_display_printable_ascii_classname(classname);
 
-       if (c == NULL)
-               return *exceptionptr;
+       if (message != NULL) {
+               log_print(": ");
+               utf_display_printable_ascii_classname(message);
+       }
 
-       o = exceptions_new_class(c);
+       log_finish();
 
-       return o;
+       vm_abort("Aborting...");
 }
 
 
-/* exceptions_throw_class ******************************************************
+/* exceptions_new_class_utf ****************************************************
 
-   Creates an exception object from the given class, initalizes and
-   throws it.
+   Creates an exception object with the given class and initalizes it
+   with the given utf message.
 
    IN:
-      class....class pointer
+      c ......... exception class
+         message ... the message as an utf *
+
+   RETURN VALUE:
+     an exception pointer (in any case -- either it is the newly
+     created exception, or an exception thrown while trying to create
+     it).
 
 *******************************************************************************/
 
-static void exceptions_throw_class(classinfo *c)
+static java_handle_t *exceptions_new_class_utf(classinfo *c, utf *message)
 {
-       java_objectheader *o;
+       java_handle_t *s;
+       java_handle_t *o;
+
+       if (vm_initializing) {
+               /* This can happen when global class variables are used which
+                  are not initialized yet. */
+
+               if (c == NULL)
+                       exceptions_abort(NULL, message);
+               else
+                       exceptions_abort(c->name, message);
+       }
+
+       s = javastring_new(message);
 
-       o = exceptions_new_class(c);
+       if (s == NULL)
+               return exceptions_get_exception();
+
+       o = native_new_and_init_string(c, s);
 
        if (o == NULL)
-               return;
+               return exceptions_get_exception();
 
-       *exceptionptr = o;
+       return o;
 }
 
 
-/* exceptions_throw_utf ********************************************************
+/* exceptions_new_utf **********************************************************
 
-   Creates an exception object with the given name, initalizes and
-   throws it.
+   Creates an exception object with the given name and initalizes it.
 
    IN:
       classname....class name in UTF-8
 
 *******************************************************************************/
 
-static void exceptions_throw_utf(utf *classname)
+static java_handle_t *exceptions_new_utf(utf *classname)
 {
-       classinfo *c;
+       classinfo     *c;
+       java_handle_t *o;
+
+       if (vm_initializing)
+               exceptions_abort(classname, NULL);
 
        c = load_class_bootstrap(classname);
 
        if (c == NULL)
-               return;
+               return exceptions_get_exception();
 
-       exceptions_throw_class(c);
+       o = native_new_and_init(c);
+
+       if (o == NULL)
+               return exceptions_get_exception();
+
+       return o;
 }
 
 
-/* exceptions_throw_utf_throwable **********************************************
+/* exceptions_new_utf_javastring ***********************************************
 
    Creates an exception object with the given name and initalizes it
-   with the given java/lang/Throwable exception.
+   with the given java/lang/String message.
 
    IN:
       classname....class name in UTF-8
-         cause........the given Throwable
+         message......the message as a java.lang.String
+
+   RETURN VALUE:
+      an exception pointer (in any case -- either it is the newly created
+         exception, or an exception thrown while trying to create it).
 
 *******************************************************************************/
 
-static void exceptions_throw_utf_throwable(utf *classname,
-                                                                                  java_objectheader *cause)
+static java_handle_t *exceptions_new_utf_javastring(utf *classname,
+                                                                                                       java_handle_t *message)
 {
-       java_objectheader *o;
-       classinfo         *c;
+       java_handle_t *o;
+       classinfo     *c;
    
+       if (vm_initializing)
+               exceptions_abort(classname, NULL);
+
        c = load_class_bootstrap(classname);
 
        if (c == NULL)
-               return;
+               return exceptions_get_exception();
 
-       o = native_new_and_init_throwable(c, cause);
+       o = native_new_and_init_string(c, message);
 
        if (o == NULL)
-               return;
+               return exceptions_get_exception();
 
-       *exceptionptr = o;
+       return o;
 }
 
 
-/* exceptions_throw_utf_exception **********************************************
+/* exceptions_new_utf_utf ******************************************************
 
    Creates an exception object with the given name and initalizes it
-   with the given java/lang/Exception exception.
+   with the given utf message.
 
    IN:
       classname....class name in UTF-8
-         exception....the given Exception
+         message......the message as an utf *
+
+   RETURN VALUE:
+      an exception pointer (in any case -- either it is the newly created
+         exception, or an exception thrown while trying to create it).
 
 *******************************************************************************/
 
-static void exceptions_throw_utf_exception(utf *classname,
-                                                                                  java_objectheader *exception)
+static java_handle_t *exceptions_new_utf_utf(utf *classname, utf *message)
 {
-       java_objectheader *o;
-       classinfo         *c;
-   
+       classinfo     *c;
+       java_handle_t *o;
+
+       if (vm_initializing)
+               exceptions_abort(classname, message);
+
        c = load_class_bootstrap(classname);
 
        if (c == NULL)
-               return;
+               return exceptions_get_exception();
+
+       o = exceptions_new_class_utf(c, message);
+
+       return o;
+}
+
+
+/* exceptions_throw_class_utf **************************************************
+
+   Creates an exception object with the given class, initalizes and
+   throws it with the given utf message.
 
-       o = native_new_and_init_exception(c, exception);
+   IN:
+      c ......... exception class
+         message ... the message as an utf *
+
+*******************************************************************************/
+
+static void exceptions_throw_class_utf(classinfo *c, utf *message)
+{
+       java_handle_t *o;
+
+       o = exceptions_new_class_utf(c, message);
+
+       exceptions_set_exception(o);
+}
+
+
+/* exceptions_throw_utf ********************************************************
+
+   Creates an exception object with the given name, initalizes and
+   throws it.
+
+   IN:
+      classname....class name in UTF-8
+
+*******************************************************************************/
+
+static void exceptions_throw_utf(utf *classname)
+{
+       java_handle_t *o;
+
+       o = exceptions_new_utf(classname);
 
        if (o == NULL)
                return;
 
-       *exceptionptr = o;
+       exceptions_set_exception(o);
 }
 
 
-/* exceptions_new_utf_javastring ***********************************************
+/* exceptions_throw_utf_throwable **********************************************
 
    Creates an exception object with the given name and initalizes it
-   with the given java/lang/String message.
+   with the given java/lang/Throwable exception.
 
    IN:
       classname....class name in UTF-8
-         message......the message as a java.lang.String
-
-   RETURN VALUE:
-      an exception pointer (in any case -- either it is the newly created
-         exception, or an exception thrown while trying to create it).
+         cause........the given Throwable
 
 *******************************************************************************/
 
-static java_objectheader *exceptions_new_utf_javastring(utf *classname,
-                                                                                                               java_objectheader *message)
+static void exceptions_throw_utf_throwable(utf *classname,
+                                                                                  java_handle_t *cause)
 {
-       java_objectheader *o;
-       classinfo         *c;
-   
+       classinfo           *c;
+       java_handle_t       *o;
+       methodinfo          *m;
+       java_lang_Throwable *object;
+
+       if (vm_initializing)
+               exceptions_abort(classname, NULL);
+
+       object = (java_lang_Throwable *) cause;
+
        c = load_class_bootstrap(classname);
 
        if (c == NULL)
-               return *exceptionptr;
+               return;
 
-       o = native_new_and_init_string(c, message);
+       /* create object */
 
+       o = builtin_new(c);
+       
        if (o == NULL)
-               return *exceptionptr;
+               return;
 
-       return o;
+       /* call initializer */
+
+       m = class_resolveclassmethod(c,
+                                                                utf_init,
+                                                                utf_java_lang_Throwable__void,
+                                                                NULL,
+                                                                true);
+                                                     
+       if (m == NULL)
+               return;
+
+       (void) vm_call_method(m, o, cause);
+
+       exceptions_set_exception(o);
 }
 
 
-/* exceptions_new_class_utf ****************************************************
+/* exceptions_throw_utf_exception **********************************************
 
-   Creates an exception object of the given class and initalizes it.
+   Creates an exception object with the given name and initalizes it
+   with the given java/lang/Exception exception.
 
    IN:
-      c..........class pointer
-      message....the message as UTF-8 string
+      classname....class name in UTF-8
+         exception....the given Exception
 
 *******************************************************************************/
 
-static java_objectheader *exceptions_new_class_utf(classinfo *c, utf *message)
+static void exceptions_throw_utf_exception(utf *classname,
+                                                                                  java_handle_t *exception)
 {
-       java_objectheader *o;
-       java_objectheader *s;
+       classinfo     *c;
+       java_handle_t *o;
+       methodinfo    *m;
 
-       s = javastring_new(message);
+       if (vm_initializing)
+               exceptions_abort(classname, NULL);
 
-       if (s == NULL)
-               return *exceptionptr;
+       c = load_class_bootstrap(classname);
 
-       o = native_new_and_init_string(c, s);
+       if (c == NULL)
+               return;
+
+       /* create object */
 
+       o = builtin_new(c);
+       
        if (o == NULL)
-               return *exceptionptr;
+               return;
 
-       return o;
+       /* call initializer */
+
+       m = class_resolveclassmethod(c,
+                                                                utf_init,
+                                                                utf_java_lang_Exception__V,
+                                                                NULL,
+                                                                true);
+                                                     
+       if (m == NULL)
+               return;
+
+       (void) vm_call_method(m, o, exception);
+
+       exceptions_set_exception(o);
 }
 
 
-/* exceptions_new_utf_utf ******************************************************
+/* exceptions_throw_utf_cause **************************************************
 
    Creates an exception object with the given name and initalizes it
-   with the given utf message.
+   with the given java/lang/Throwable exception with initCause.
 
    IN:
       classname....class name in UTF-8
-         message......the message as an utf *
-
-   RETURN VALUE:
-      an exception pointer (in any case -- either it is the newly created
-         exception, or an exception thrown while trying to create it).
+         cause........the given Throwable
 
 *******************************************************************************/
 
-static java_objectheader *exceptions_new_utf_utf(utf *classname, utf *message)
+static void exceptions_throw_utf_cause(utf *classname, java_handle_t *cause)
 {
-       classinfo         *c;
-       java_objectheader *o;
+       classinfo           *c;
+       java_handle_t       *o;
+       methodinfo          *m;
+       java_lang_String    *s;
+       java_lang_Throwable *object;
+
+       if (vm_initializing)
+               exceptions_abort(classname, NULL);
+
+       object = (java_lang_Throwable *) cause;
 
        c = load_class_bootstrap(classname);
 
        if (c == NULL)
-               return *exceptionptr;
+               return;
 
-       o = exceptions_new_class_utf(c, message);
+       /* create object */
 
-       return o;
-}
+       o = builtin_new(c);
+       
+       if (o == NULL)
+               return;
 
+       /* call initializer */
 
-/* exceptions_throw_class_utf **************************************************
+       m = class_resolveclassmethod(c,
+                                                                utf_init,
+                                                                utf_java_lang_String__void,
+                                                                NULL,
+                                                                true);
+                                                     
+       if (m == NULL)
+               return;
 
-   Creates an exception object of the given class, initalizes and
-   throws it with the given utf message.
+       LLNI_field_get_ref(object, detailMessage, s);
 
-   IN:
-      c..........class pointer
-         message....the message as an UTF-8
+       (void) vm_call_method(m, o, s);
 
-*******************************************************************************/
+       /* call initCause */
 
-static void exceptions_throw_class_utf(classinfo *c, utf *message)
-{
-       *exceptionptr = exceptions_new_class_utf(c, message);
+       m = class_resolveclassmethod(c,
+                                                                utf_initCause,
+                                                                utf_java_lang_Throwable__java_lang_Throwable,
+                                                                NULL,
+                                                                true);
+
+       if (m == NULL)
+               return;
+
+       (void) vm_call_method(m, o, cause);
+
+       exceptions_set_exception(o);
 }
 
 
@@ -469,7 +622,11 @@ static void exceptions_throw_class_utf(classinfo *c, utf *message)
 
 static void exceptions_throw_utf_utf(utf *classname, utf *message)
 {
-       *exceptionptr = exceptions_new_utf_utf(classname, message);
+       java_handle_t *o;
+
+       o = exceptions_new_utf_utf(classname, message);
+
+       exceptions_set_exception(o);
 }
 
 
@@ -479,9 +636,9 @@ static void exceptions_throw_utf_utf(utf *classname, utf *message)
 
 *******************************************************************************/
 
-java_objectheader *exceptions_new_abstractmethoderror(void)
+java_handle_t *exceptions_new_abstractmethoderror(void)
 {
-       java_objectheader *o;
+       java_handle_t *o;
 
        o = exceptions_new_utf(utf_java_lang_AbstractMethodError);
 
@@ -496,11 +653,11 @@ java_objectheader *exceptions_new_abstractmethoderror(void)
 *******************************************************************************/
 
 #if defined(ENABLE_JAVAME_CLDC1_1)
-static java_objectheader *exceptions_new_error(utf *message)
+static java_handle_t *exceptions_new_error(utf *message)
 {
-       java_objectheader *o;
+       java_handle_t *o;
 
-       o = exceptions_new_class_utf(class_java_lang_Error, message);
+       o = exceptions_new_utf_utf(utf_java_lang_Error, message);
 
        return o;
 }
@@ -514,14 +671,15 @@ static java_objectheader *exceptions_new_error(utf *message)
 
 *******************************************************************************/
 
-java_objectheader *exceptions_asm_new_abstractmethoderror(u1 *sp, u1 *ra)
+java_object_t *exceptions_asm_new_abstractmethoderror(u1 *sp, u1 *ra)
 {
-       stackframeinfo     sfi;
-       java_objectheader *e;
+       stackframeinfo_t  sfi;
+       java_handle_t    *e;
+       java_object_t    *o;
 
-       /* create the stackframeinfo (XPC is equal to RA) */
+       /* Fill and add a stackframeinfo (XPC is equal to RA). */
 
-       stacktrace_create_extern_stackframeinfo(&sfi, NULL, sp, ra, ra);
+       stacktrace_stackframeinfo_add(&sfi, NULL, sp, ra, ra);
 
        /* create the exception */
 
@@ -531,11 +689,16 @@ java_objectheader *exceptions_asm_new_abstractmethoderror(u1 *sp, u1 *ra)
        e = exceptions_new_error(utf_java_lang_AbstractMethodError);
 #endif
 
-       /* remove the stackframeinfo */
+       /* Remove the stackframeinfo. */
 
-       stacktrace_remove_stackframeinfo(&sfi);
+       stacktrace_stackframeinfo_remove(&sfi);
 
-       return e;
+       /* unwrap the exception */
+       /* ATTENTION: do the this _after_ the stackframeinfo was removed */
+
+       o = LLNI_UNWRAP(e);
+
+       return o;
 }
 
 
@@ -545,9 +708,9 @@ java_objectheader *exceptions_asm_new_abstractmethoderror(u1 *sp, u1 *ra)
 
 *******************************************************************************/
 
-java_objectheader *exceptions_new_arraystoreexception(void)
+java_handle_t *exceptions_new_arraystoreexception(void)
 {
-       java_objectheader *o;
+       java_handle_t *o;
 
        o = exceptions_new_utf(utf_java_lang_ArrayStoreException);
 
@@ -657,9 +820,7 @@ void exceptions_throw_classformaterror(classinfo *c, const char *message, ...)
 *******************************************************************************/
 
 void exceptions_throw_classnotfoundexception(utf *name)
-{
-       /* we use class here, as this one is rather frequent */
-
+{      
        exceptions_throw_class_utf(class_java_lang_ClassNotFoundException, name);
 }
 
@@ -675,10 +836,20 @@ void exceptions_throw_classnotfoundexception(utf *name)
 
 void exceptions_throw_noclassdeffounderror(utf *name)
 {
-       if (vm_initializing)
-               vm_abort("java.lang.NoClassDefFoundError: %s", name->text);
+       exceptions_throw_utf_utf(utf_java_lang_NoClassDefFoundError, name);
+}
+
+
+/* exceptions_throw_noclassdeffounderror_cause *********************************
+
+   Generates and throws a java.lang.NoClassDefFoundError with the
+   given cause.
 
-       exceptions_throw_class_utf(class_java_lang_NoClassDefFoundError, name);
+*******************************************************************************/
+
+void exceptions_throw_noclassdeffounderror_cause(java_handle_t *cause)
+{
+       exceptions_throw_utf_cause(utf_java_lang_NoClassDefFoundError, cause);
 }
 
 
@@ -687,8 +858,6 @@ void exceptions_throw_noclassdeffounderror(utf *name)
    Generates and throws a java.lang.NoClassDefFoundError with a
    specific message:
 
-
-
    IN:
       name.........name of the class not found as a utf *
 
@@ -718,51 +887,6 @@ void exceptions_throw_noclassdeffounderror_wrong_name(classinfo *c, utf *name)
 }
 
 
-/* classnotfoundexception_to_noclassdeffounderror ******************************
-
-   Check the *exceptionptr for a ClassNotFoundException. If it is one,
-   convert it to a NoClassDefFoundError.
-
-*******************************************************************************/
-
-void classnotfoundexception_to_noclassdeffounderror(void)
-{
-       java_objectheader   *xptr;
-       java_objectheader   *cause;
-       java_lang_Throwable *t;
-       java_objectheader   *s;
-
-       /* get the cause */
-
-       cause = *exceptionptr;
-
-       /* convert ClassNotFoundException's to NoClassDefFoundError's */
-
-       if (builtin_instanceof(cause, class_java_lang_ClassNotFoundException)) {
-               /* clear exception, because we are calling jit code again */
-
-               *exceptionptr = NULL;
-
-               /* create new error */
-
-               t = (java_lang_Throwable *) cause;
-               s = (java_objectheader *) t->detailMessage;
-
-               xptr = exceptions_new_utf_javastring(utf_java_lang_NoClassDefFoundError,
-                                                                                        s);
-
-               /* we had an exception while creating the error */
-
-               if (*exceptionptr)
-                       return;
-
-               /* set new exception */
-
-               *exceptionptr = xptr;
-       }
-}
-
-
 /* exceptions_throw_exceptionininitializererror ********************************
 
    Generates and throws a java.lang.ExceptionInInitializerError for
@@ -773,7 +897,7 @@ void classnotfoundexception_to_noclassdeffounderror(void)
 
 *******************************************************************************/
 
-void exceptions_throw_exceptionininitializererror(java_objectheader *cause)
+void exceptions_throw_exceptionininitializererror(java_handle_t *cause)
 {
        exceptions_throw_utf_throwable(utf_java_lang_ExceptionInInitializerError,
                                                                   cause);
@@ -888,39 +1012,35 @@ void exceptions_throw_internalerror(const char *message, ...)
 
 void exceptions_throw_linkageerror(const char *message, classinfo *c)
 {
-       java_objectheader *o;
-       char              *msg;
-       s4                 msglen;
+       utf  *u;
+       char *msg;
+       int   len;
 
        /* calculate exception message length */
 
-       msglen = strlen(message) + 1;
+       len = strlen(message) + 1;
 
        if (c != NULL)
-               msglen += utf_bytes(c->name);
+               len += utf_bytes(c->name);
                
        /* allocate memory */
 
-       msg = MNEW(char, msglen);
+       msg = MNEW(char, len);
 
        /* generate message */
 
-       strcpy(msg,message);
+       strcpy(msg, message);
 
        if (c != NULL)
                utf_cat_classname(msg, c->name);
 
-       o = native_new_and_init_string(class_java_lang_LinkageError,
-                                                                  javastring_new_from_utf_string(msg));
+       u = utf_new_char(msg);
 
        /* free memory */
 
-       MFREE(msg, char, msglen);
-
-       if (o == NULL)
-               return;
+       MFREE(msg, char, len);
 
-       *exceptionptr = o;
+       exceptions_throw_utf_utf(utf_java_lang_LinkageError, u);
 }
 
 
@@ -1008,7 +1128,7 @@ void exceptions_throw_nosuchmethoderror(classinfo *c, utf *name, utf *desc)
 #if defined(ENABLE_JAVASE)
        exceptions_throw_utf_utf(utf_java_lang_NoSuchMethodError, u);
 #else
-       exceptions_throw_class_utf(class_java_lang_Error, u);
+       exceptions_throw_utf_utf(utf_java_lang_Error, u);
 #endif
 }
 
@@ -1021,7 +1141,7 @@ void exceptions_throw_nosuchmethoderror(classinfo *c, utf *name, utf *desc)
 
 void exceptions_throw_outofmemoryerror(void)
 {
-       exceptions_throw_class(class_java_lang_OutOfMemoryError);
+       exceptions_throw_utf(utf_java_lang_OutOfMemoryError);
 }
 
 
@@ -1040,7 +1160,7 @@ void exceptions_throw_unsatisfiedlinkerror(utf *name)
 #if defined(ENABLE_JAVASE)
        exceptions_throw_utf_utf(utf_java_lang_UnsatisfiedLinkError, name);
 #else
-       exceptions_throw_class_utf(class_java_lang_Error, name);
+       exceptions_throw_utf_utf(utf_java_lang_Error, name);
 #endif
 }
 
@@ -1114,7 +1234,7 @@ void exceptions_throw_verifyerror(methodinfo *m, const char *message, ...)
 
        if (m != NULL)
                msglen =
-                       strlen("(class: ") + utf_bytes(m->class->name) +
+                       strlen("(class: ") + utf_bytes(m->clazz->name) +
                        strlen(", method: ") + utf_bytes(m->name) +
                        strlen(" signature: ") + utf_bytes(m->descriptor) +
                        strlen(") ") + strlen("0");
@@ -1131,7 +1251,7 @@ void exceptions_throw_verifyerror(methodinfo *m, const char *message, ...)
 
        if (m != NULL) {
                strcpy(msg, "(class: ");
-               utf_cat_classname(msg, m->class->name);
+               utf_cat_classname(msg, m->clazz->name);
                strcat(msg, ", method: ");
                utf_cat(msg, m->name);
                strcat(msg, " signature: ");
@@ -1181,7 +1301,7 @@ void exceptions_throw_verifyerror_for_stack(methodinfo *m, int type)
        msglen = 0;
 
        if (m != NULL)
-               msglen = strlen("(class: ") + utf_bytes(m->class->name) +
+               msglen = strlen("(class: ") + utf_bytes(m->clazz->name) +
                        strlen(", method: ") + utf_bytes(m->name) +
                        strlen(" signature: ") + utf_bytes(m->descriptor) +
                        strlen(") Expecting to find longest-------typename on stack") 
@@ -1195,7 +1315,7 @@ void exceptions_throw_verifyerror_for_stack(methodinfo *m, int type)
 
        if (m != NULL) {
                strcpy(msg, "(class: ");
-               utf_cat_classname(msg, m->class->name);
+               utf_cat_classname(msg, m->clazz->name);
                strcat(msg, ", method: ");
                utf_cat(msg, m->name);
                strcat(msg, " signature: ");
@@ -1239,9 +1359,9 @@ void exceptions_throw_verifyerror_for_stack(methodinfo *m, int type)
 
 *******************************************************************************/
 
-java_objectheader *exceptions_new_arithmeticexception(void)
+java_handle_t *exceptions_new_arithmeticexception(void)
 {
-       java_objectheader *o;
+       java_handle_t *o;
 
        o = exceptions_new_utf_utf(utf_java_lang_ArithmeticException,
                                                           utf_division_by_zero);
@@ -1257,11 +1377,11 @@ java_objectheader *exceptions_new_arithmeticexception(void)
 
 *******************************************************************************/
 
-java_objectheader *exceptions_new_arrayindexoutofboundsexception(s4 index)
+java_handle_t *exceptions_new_arrayindexoutofboundsexception(s4 index)
 {
-       java_objectheader *o;
-       methodinfo        *m;
-       java_objectheader *s;
+       java_handle_t *o;
+       methodinfo    *m;
+       java_handle_t *s;
 
        /* convert the index into a String, like Sun does */
 
@@ -1272,18 +1392,18 @@ java_objectheader *exceptions_new_arrayindexoutofboundsexception(s4 index)
                                                                 true);
 
        if (m == NULL)
-               return *exceptionptr;
+               return exceptions_get_exception();
 
        s = vm_call_method(m, NULL, index);
 
        if (s == NULL)
-               return *exceptionptr;
+               return exceptions_get_exception();
 
        o = exceptions_new_utf_javastring(utf_java_lang_ArrayIndexOutOfBoundsException,
                                                                          s);
 
        if (o == NULL)
-               return *exceptionptr;
+               return exceptions_get_exception();
 
        return o;
 }
@@ -1311,7 +1431,6 @@ void exceptions_throw_arrayindexoutofboundsexception(void)
 void exceptions_throw_arraystoreexception(void)
 {
        exceptions_throw_utf(utf_java_lang_ArrayStoreException);
-/*     e = native_new_and_init(class_java_lang_ArrayStoreException); */
 }
 
 
@@ -1321,14 +1440,17 @@ void exceptions_throw_arraystoreexception(void)
 
 *******************************************************************************/
 
-java_objectheader *exceptions_new_classcastexception(java_objectheader *o)
+java_handle_t *exceptions_new_classcastexception(java_handle_t *o)
 {
-       java_objectheader *e;
-       utf               *classname;
+       java_handle_t *e;
+       classinfo     *c;
+       utf           *classname;
 
-       classname = o->vftbl->class->name;
+       LLNI_class_get(o, c);
 
-       e = exceptions_new_class_utf(class_java_lang_ClassCastException, classname);
+       classname = c->name;
+
+       e = exceptions_new_utf_utf(utf_java_lang_ClassCastException, classname);
 
        return e;
 }
@@ -1419,7 +1541,7 @@ void exceptions_throw_interruptedexception(void)
 
 *******************************************************************************/
 
-void exceptions_throw_invocationtargetexception(java_objectheader *cause)
+void exceptions_throw_invocationtargetexception(java_handle_t *cause)
 {
        exceptions_throw_utf_throwable(utf_java_lang_reflect_InvocationTargetException,
                                                                   cause);
@@ -1445,11 +1567,11 @@ void exceptions_throw_negativearraysizeexception(void)
 
 *******************************************************************************/
 
-java_objectheader *exceptions_new_nullpointerexception(void)
+java_handle_t *exceptions_new_nullpointerexception(void)
 {
-       java_objectheader *o;
+       java_handle_t *o;
 
-       o = exceptions_new_class(class_java_lang_NullPointerException);
+       o = exceptions_new_utf(utf_java_lang_NullPointerException);
 
        return o;
 }
@@ -1464,7 +1586,7 @@ java_objectheader *exceptions_new_nullpointerexception(void)
 
 void exceptions_throw_nullpointerexception(void)
 {
-       exceptions_throw_class(class_java_lang_NullPointerException);
+       exceptions_throw_utf(utf_java_lang_NullPointerException);
 }
 
 
@@ -1474,7 +1596,7 @@ void exceptions_throw_nullpointerexception(void)
 
 *******************************************************************************/
 
-void exceptions_throw_privilegedactionexception(java_objectheader *exception)
+void exceptions_throw_privilegedactionexception(java_handle_t *exception)
 {
        exceptions_throw_utf_exception(utf_java_security_PrivilegedActionException,
                                                                   exception);
@@ -1494,48 +1616,6 @@ void exceptions_throw_stringindexoutofboundsexception(void)
 }
 
 
-/* exceptions_get_exception ****************************************************
-
-   Returns the current exception pointer of the current thread.
-
-*******************************************************************************/
-
-java_objectheader *exceptions_get_exception(void)
-{
-       /* return the exception */
-
-       return *exceptionptr;
-}
-
-
-/* exceptions_set_exception ****************************************************
-
-   Sets the exception pointer of the current thread.
-
-*******************************************************************************/
-
-void exceptions_set_exception(java_objectheader *o)
-{
-       /* set the exception */
-
-       *exceptionptr = o;
-}
-
-
-/* exceptions_clear_exception **************************************************
-
-   Clears the current exception pointer of the current thread.
-
-*******************************************************************************/
-
-void exceptions_clear_exception(void)
-{
-       /* and clear the exception */
-
-       *exceptionptr = NULL;
-}
-
-
 /* exceptions_fillinstacktrace *************************************************
 
    Calls the fillInStackTrace-method of the currently thrown
@@ -1543,28 +1623,28 @@ void exceptions_clear_exception(void)
 
 *******************************************************************************/
 
-java_objectheader *exceptions_fillinstacktrace(void)
+java_handle_t *exceptions_fillinstacktrace(void)
 {
-       java_objectheader *o;
-       methodinfo        *m;
+       java_handle_t *o;
+       classinfo     *c;
+       methodinfo    *m;
 
        /* get exception */
 
-       o = *exceptionptr;
-       assert(o);
-
-       /* clear exception */
+       o = exceptions_get_and_clear_exception();
 
-       *exceptionptr = NULL;
+       assert(o);
 
        /* resolve methodinfo pointer from exception object */
 
+       LLNI_class_get(o, c);
+
 #if defined(ENABLE_JAVASE)
-       m = class_resolvemethod(o->vftbl->class,
+       m = class_resolvemethod(c,
                                                        utf_fillInStackTrace,
                                                        utf_void__java_lang_Throwable);
 #elif defined(ENABLE_JAVAME_CLDC1_1)
-       m = class_resolvemethod(o->vftbl->class,
+       m = class_resolvemethod(c,
                                                        utf_fillInStackTrace,
                                                        utf_void__void);
 #else
@@ -1581,114 +1661,6 @@ java_objectheader *exceptions_fillinstacktrace(void)
 }
 
 
-/* exceptions_get_and_clear_exception ******************************************
-
-   Gets the exception pointer of the current thread and clears it.
-   This function may return NULL.
-
-*******************************************************************************/
-
-java_objectheader *exceptions_get_and_clear_exception(void)
-{
-       java_objectheader **p;
-       java_objectheader  *e;
-
-       /* get the pointer of the exception pointer */
-
-       p = exceptionptr;
-
-       /* get the exception */
-
-       e = *p;
-
-       /* and clear the exception */
-
-       *p = NULL;
-
-       /* return the exception */
-
-       return e;
-}
-
-
-/* exceptions_new_hardware_exception *******************************************
-
-   Creates the correct exception for a hardware-exception thrown and
-   caught by a signal handler.
-
-*******************************************************************************/
-
-java_objectheader *exceptions_new_hardware_exception(u1 *pv, u1 *sp, u1 *ra, u1 *xpc, s4 type, ptrint val)
-{
-       stackframeinfo     sfi;
-       java_objectheader *e;
-       java_objectheader *o;
-       s4                 index;
-
-       /* create stackframeinfo */
-
-       stacktrace_create_extern_stackframeinfo(&sfi, pv, sp, ra, xpc);
-
-       switch (type) {
-       case EXCEPTION_HARDWARE_NULLPOINTER:
-               e = exceptions_new_nullpointerexception();
-               break;
-
-       case EXCEPTION_HARDWARE_ARITHMETIC:
-               e = exceptions_new_arithmeticexception();
-               break;
-
-       case EXCEPTION_HARDWARE_ARRAYINDEXOUTOFBOUNDS:
-               index = (s4) val;
-               e = exceptions_new_arrayindexoutofboundsexception(index);
-               break;
-
-       case EXCEPTION_HARDWARE_CLASSCAST:
-               o = (java_objectheader *) val;
-               e = exceptions_new_classcastexception(o);
-               break;
-
-       case EXCEPTION_HARDWARE_EXCEPTION:
-               e = exceptions_fillinstacktrace();
-               break;
-
-       default:
-               /* let's try to get a backtrace */
-
-               codegen_get_pv_from_pc(xpc);
-
-               /* if that does not work, print more debug info */
-
-               log_println("exceptions_new_hardware_exception: unknown exception type %d", type);
-
-#if SIZEOF_VOID_P == 8
-               log_println("PC=0x%016lx", xpc);
-#else
-               log_println("PC=0x%08x", xpc);
-#endif
-
-#if defined(ENABLE_DISASSEMBLER)
-               log_println("machine instruction at PC:");
-               disassinstr(xpc);
-#endif
-
-               vm_abort("Exiting...");
-
-               /* keep compiler happy */
-
-               e = NULL;
-       }
-
-       /* remove stackframeinfo */
-
-       stacktrace_remove_stackframeinfo(&sfi);
-
-       /* return the exception object */
-
-       return e;
-}
-
-
 /* exceptions_handle_exception *************************************************
 
    Try to find an exception handler for the given exception and return it.
@@ -1708,69 +1680,78 @@ java_objectheader *exceptions_new_hardware_exception(u1 *pv, u1 *sp, u1 *ra, u1
 *******************************************************************************/
 
 #if defined(ENABLE_JIT)
-u1 *exceptions_handle_exception(java_objectheader *xptr, u1 *xpc, u1 *pv, u1 *sp)
+void *exceptions_handle_exception(java_object_t *xptro, void *xpc, void *pv, void *sp)
 {
-       methodinfo            *m;
-       codeinfo              *code;
-       s4                     issync;
-       dseg_exception_entry  *ex;
-       s4                     exceptiontablelength;
-       s4                     i;
-       classref_or_classinfo  cr;
-       classinfo             *c;
+       stackframeinfo_t        sfi;
+       java_handle_t          *xptr;
+       methodinfo             *m;
+       codeinfo               *code;
+       exceptiontable_t       *et;
+       exceptiontable_entry_t *ete;
+       s4                      i;
+       classref_or_classinfo   cr;
+       classinfo              *c;
 #if defined(ENABLE_THREADS)
-       java_objectheader     *o;
+       java_object_t          *o;
 #endif
+       void                   *result;
 
 #ifdef __S390__
        /* Addresses are 31 bit integers */
-#      define ADDR_MASK(x) (u1 *)((u4)(x) & 0x7FFFFFFF)
+#      define ADDR_MASK(x) (void *) ((uintptr_t) (x) & 0x7FFFFFFF)
 #else
 #      define ADDR_MASK(x) (x)
 #endif
 
-       xpc = ADDR_MASK(xpc);
+       xptr = LLNI_WRAP(xptro);
+       xpc  = ADDR_MASK(xpc);
+
+       /* Fill and add a stackframeinfo (XPC is equal to RA). */
+
+       stacktrace_stackframeinfo_add(&sfi, pv, sp, xpc, xpc);
+
+       result = NULL;
 
-       /* get info from the method header */
+       /* Get the codeinfo for the current method. */
 
-       code                 = *((codeinfo **)            (pv + CodeinfoPointer));
-       issync               = *((s4 *)                   (pv + IsSync));
-       ex                   =   (dseg_exception_entry *) (pv + ExTableStart);
-       exceptiontablelength = *((s4 *)                   (pv + ExTableSize));
+       code = code_get_codeinfo_for_pv(pv);
 
        /* Get the methodinfo pointer from the codeinfo pointer. For
-          asm_vm_call_method the codeinfo pointer is NULL. */
+          asm_vm_call_method the codeinfo pointer is NULL and we simply
+          can return the proper exception handler. */
 
-       m = (code == NULL) ? NULL : code->m;
+       if (code == NULL) {
+               result = (void *) (uintptr_t) &asm_vm_call_method_exception_handler;
+               goto exceptions_handle_exception_return;
+       }
+
+       m = code->m;
 
 #if !defined(NDEBUG)
        /* print exception trace */
 
-       if (opt_verbose || opt_verbosecall || opt_verboseexception)
-               builtin_trace_exception(xptr, m, xpc, 1);
-#endif
+       if (opt_TraceExceptions)
+               trace_exception(LLNI_DIRECT(xptr), m, xpc);
 
-#if defined(ENABLE_VMLOG)
+# if defined(ENABLE_VMLOG)
        vmlog_cacao_throw(xptr);
+# endif
 #endif
 
-       for (i = 0; i < exceptiontablelength; i++) {
-               /* ATTENTION: keep this here, as we need to decrement the
-           pointer before the loop executes! */
+       /* Get the exception table. */
 
-               ex--;
+       et = code->exceptiontable;
 
-               /* If the start and end PC is NULL, this means we have the
-                  special case of asm_vm_call_method.  So, just return the
-                  proper exception handler. */
+       if (et != NULL) {
+       /* Iterate over all exception table entries. */
 
-               if ((ex->startpc == NULL) && (ex->endpc == NULL))
-                       return (u1 *) (ptrint) &asm_vm_call_method_exception_handler;
+       ete = et->entries;
 
+       for (i = 0; i < et->length; i++, ete++) {
                /* is the xpc is the current catch range */
 
-               if ((ADDR_MASK(ex->startpc) <= xpc) && (xpc < ADDR_MASK(ex->endpc))) {
-                       cr = ex->catchtype;
+               if ((ADDR_MASK(ete->startpc) <= xpc) && (xpc < ADDR_MASK(ete->endpc))) {
+                       cr = ete->catchtype;
 
                        /* NULL catches everything */
 
@@ -1778,59 +1759,62 @@ u1 *exceptions_handle_exception(java_objectheader *xptr, u1 *xpc, u1 *pv, u1 *sp
 #if !defined(NDEBUG)
                                /* Print stacktrace of exception when caught. */
 
-#if defined(ENABLE_VMLOG)
+# if defined(ENABLE_VMLOG)
                                vmlog_cacao_catch(xptr);
-#endif
+# endif
 
-                               if (opt_verboseexception) {
+                               if (opt_TraceExceptions) {
                                        exceptions_print_exception(xptr);
-                                       stacktrace_print_trace(xptr);
+                                       stacktrace_print_exception(xptr);
                                }
 #endif
 
-                               return ex->handlerpc;
+                               result = ete->handlerpc;
+                               goto exceptions_handle_exception_return;
                        }
 
                        /* resolve or load/link the exception class */
 
                        if (IS_CLASSREF(cr)) {
                                /* The exception class reference is unresolved. */
-                               /* We have to do _eager_ resolving here. While the class of */
-                               /* the exception object is guaranteed to be loaded, it may  */
-                               /* well have been loaded by a different loader than the     */
-                               /* defining loader of m's class, which is the one we must   */
-                               /* use to resolve the catch class. Thus lazy resolving      */
-                               /* might fail, even if the result of the resolution would   */
-                               /* be an already loaded class.                              */
+                               /* We have to do _eager_ resolving here. While the
+                                  class of the exception object is guaranteed to be
+                                  loaded, it may well have been loaded by a different
+                                  loader than the defining loader of m's class, which
+                                  is the one we must use to resolve the catch
+                                  class. Thus lazy resolving might fail, even if the
+                                  result of the resolution would be an already loaded
+                                  class. */
 
                                c = resolve_classref_eager(cr.ref);
 
                                if (c == NULL) {
                                        /* Exception resolving the exception class, argh! */
-                                       return NULL;
+                                       goto exceptions_handle_exception_return;
                                }
 
-                               /* Ok, we resolved it. Enter it in the table, so we don't */
-                               /* have to do this again.                                 */
-                               /* XXX this write should be atomic. Is it?                */
+                               /* Ok, we resolved it. Enter it in the table, so we
+                                  don't have to do this again. */
+                               /* XXX this write should be atomic. Is it? */
 
-                               ex->catchtype.cls = c;
-                       } else {
+                               ete->catchtype.cls = c;
+                       }
+                       else {
                                c = cr.cls;
 
                                /* XXX I don't think this case can ever happen. -Edwin */
                                if (!(c->state & CLASS_LOADED))
                                        /* use the methods' classloader */
                                        if (!load_class_from_classloader(c->name,
-                                                                                                        m->class->classloader))
-                                               return NULL;
+                                                                                                        m->clazz->classloader))
+                                               goto exceptions_handle_exception_return;
 
-                               /* XXX I think, if it is not linked, we can be sure that     */
-                               /* the exception object is no (indirect) instance of it, no? */
-                               /* -Edwin                                                    */
+                               /* XXX I think, if it is not linked, we can be sure
+                                  that the exception object is no (indirect) instance
+                                  of it, no?  -Edwin  */
                                if (!(c->state & CLASS_LINKED))
                                        if (!link_class(c))
-                                               return NULL;
+                                               goto exceptions_handle_exception_return;
                        }
 
                        /* is the thrown exception an instance of the catch class? */
@@ -1839,47 +1823,71 @@ u1 *exceptions_handle_exception(java_objectheader *xptr, u1 *xpc, u1 *pv, u1 *sp
 #if !defined(NDEBUG)
                                /* Print stacktrace of exception when caught. */
 
-#if defined(ENABLE_VMLOG)
+# if defined(ENABLE_VMLOG)
                                vmlog_cacao_catch(xptr);
-#endif
+# endif
 
-                               if (opt_verboseexception) {
+                               if (opt_TraceExceptions) {
                                        exceptions_print_exception(xptr);
-                                       stacktrace_print_trace(xptr);
+                                       stacktrace_print_exception(xptr);
                                }
 #endif
 
-                               return ex->handlerpc;
+                               result = ete->handlerpc;
+                               goto exceptions_handle_exception_return;
                        }
                }
        }
+       }
 
 #if defined(ENABLE_THREADS)
-       /* is this method synchronized? */
+       /* Is this method realization synchronized? */
 
-       if (issync) {
-               /* get synchronization object */
+       if (code_is_synchronized(code)) {
+               /* Get synchronization object. */
 
-# if defined(__MIPS__) && (SIZEOF_VOID_P == 4)
-               /* XXX change this if we ever want to use 4-byte stackslots */
-               o = *((java_objectheader **) (sp + issync - 8));
-# else
-               o = *((java_objectheader **) (sp + issync - SIZEOF_VOID_P));
-#endif
+               o = *((java_object_t **) (((uintptr_t) sp) + code->synchronizedoffset));
 
                assert(o != NULL);
 
-               lock_monitor_exit(o);
+               lock_monitor_exit(LLNI_QUICKWRAP(o));
        }
 #endif
 
        /* none of the exceptions catch this one */
 
-#if defined(ENABLE_VMLOG)
+#if !defined(NDEBUG)
+# if defined(ENABLE_VMLOG)
        vmlog_cacao_unwnd_method(m);
-#endif
+# endif
+
+# if defined(ENABLE_DEBUG_FILTER)
+       if (show_filters_test_verbosecall_exit(m)) {
+# endif
+
+       /* outdent the log message */
+
+       if (opt_verbosecall) {
+               if (TRACEJAVACALLINDENT)
+                       TRACEJAVACALLINDENT--;
+               else
+                       log_text("exceptions_handle_exception: WARNING: unmatched unindent");
+       }
+
+# if defined(ENABLE_DEBUG_FILTER)
+       }
+# endif
+#endif /* !defined(NDEBUG) */
+
+       result = NULL;
+
+exceptions_handle_exception_return:
+
+       /* Remove the stackframeinfo. */
 
-       return NULL;
+       stacktrace_stackframeinfo_remove(&sfi);
+
+       return result;
 }
 #endif /* defined(ENABLE_JIT) */
 
@@ -1891,12 +1899,14 @@ u1 *exceptions_handle_exception(java_objectheader *xptr, u1 *xpc, u1 *pv, u1 *sp
 
 *******************************************************************************/
 
-void exceptions_print_exception(java_objectheader *xptr)
+void exceptions_print_exception(java_handle_t *xptr)
 {
        java_lang_Throwable   *t;
 #if defined(ENABLE_JAVASE)
        java_lang_Throwable   *cause;
 #endif
+       java_lang_String      *s;
+       classinfo             *c;
        utf                   *u;
 
        t = (java_lang_Throwable *) xptr;
@@ -1907,15 +1917,18 @@ void exceptions_print_exception(java_objectheader *xptr)
        }
 
 #if defined(ENABLE_JAVASE)
-       cause = t->cause;
+       LLNI_field_get_ref(t, cause, cause);
 #endif
 
        /* print the root exception */
 
-       utf_display_printable_ascii_classname(t->header.vftbl->class->name);
+       LLNI_class_get(t, c);
+       utf_display_printable_ascii_classname(c->name);
 
-       if (t->detailMessage != NULL) {
-               u = javastring_toutf((java_objectheader *) t->detailMessage, false);
+       LLNI_field_get_ref(t, detailMessage, s);
+
+       if (s != NULL) {
+               u = javastring_toutf((java_handle_t *) s, false);
 
                printf(": ");
                utf_display_printable_ascii(u);
@@ -1928,11 +1941,14 @@ void exceptions_print_exception(java_objectheader *xptr)
 
        if ((cause != NULL) && (cause != t)) {
                printf("Caused by: ");
-               utf_display_printable_ascii_classname(cause->header.vftbl->class->name);
+               
+               LLNI_class_get(cause, c);
+               utf_display_printable_ascii_classname(c->name);
 
-               if (cause->detailMessage != NULL) {
-                       u = javastring_toutf((java_objectheader *) cause->detailMessage,
-                                                                false);
+               LLNI_field_get_ref(cause, detailMessage, s);
+
+               if (s != NULL) {
+                       u = javastring_toutf((java_handle_t *) s, false);
 
                        printf(": ");
                        utf_display_printable_ascii(u);
@@ -1953,11 +1969,11 @@ void exceptions_print_exception(java_objectheader *xptr)
 
 void exceptions_print_current_exception(void)
 {
-       java_objectheader *xptr;
+       java_handle_t *o;
 
-       xptr = *exceptionptr;
+       o = exceptions_get_exception();
 
-       exceptions_print_exception(xptr);
+       exceptions_print_exception(o);
 }
 
 
@@ -1973,65 +1989,104 @@ void exceptions_print_current_exception(void)
 
 void exceptions_print_stacktrace(void)
 {
-       java_objectheader *oxptr;
-       java_objectheader *xptr;
-       classinfo         *c;
-       methodinfo        *m;
+       java_handle_t    *e;
+       java_handle_t    *ne;
+       classinfo        *c;
+       methodinfo       *m;
 
-       /* get original exception */
+#if defined(ENABLE_THREADS)
+       threadobject     *t;
+       java_lang_Thread *to;
+#endif
 
-       oxptr = *exceptionptr;
+       /* Get and clear exception because we are calling Java code
+          again. */
 
-       if (oxptr == NULL)
-               vm_abort("exceptions_print_stacktrace: no exception thrown");
+       e = exceptions_get_and_clear_exception();
 
-       /* clear exception, because we are calling jit code again */
+       if (e == NULL)
+               return;
 
-       *exceptionptr = NULL;
+#if 0
+       /* FIXME Enable me. */
+       if (builtin_instanceof(e, class_java_lang_ThreadDeath)) {
+               /* Don't print anything if we are being killed. */
+       }
+       else
+#endif
+       {
+               /* Get the exception class. */
 
-       c = oxptr->vftbl->class;
+               LLNI_class_get(e, c);
 
-       /* find the printStackTrace() method */
+               /* Find the printStackTrace() method. */
 
-       m = class_resolveclassmethod(c,
-                                                                utf_printStackTrace,
-                                                                utf_void__void,
-                                                                class_java_lang_Object,
-                                                                false);
+               m = class_resolveclassmethod(c,
+                                                                        utf_printStackTrace,
+                                                                        utf_void__void,
+                                                                        class_java_lang_Object,
+                                                                        false);
 
-       if (m == NULL)
-               vm_abort("exceptions_print_stacktrace: printStackTrace()V not found");
+               if (m == NULL)
+                       vm_abort("exceptions_print_stacktrace: printStackTrace()V not found");
 
-       /* print compatibility message */
+               /* Print message. */
 
-       fprintf(stderr, "Exception in thread \"main\" ");
+               fprintf(stderr, "Exception ");
 
-       /* print the stacktrace */
+#if defined(ENABLE_THREADS)
+               /* Print thread name.  We get the thread here explicitly as we
+                  need it afterwards. */
 
-       (void) vm_call_method(m, oxptr);
+               t  = thread_get_current();
+               to = (java_lang_Thread *) thread_get_object(t);
 
-       /* This normally means, we are EXTREMLY out of memory or
-          have a serious problem while printStackTrace. But may
-          be another exception, so print it. */
+               if (to != NULL) {
+                       fprintf(stderr, "in thread \"");
+                       thread_fprint_name(t, stderr);
+                       fprintf(stderr, "\" ");
+               }
+#endif
 
-       xptr = *exceptionptr;
+               /* Print the stacktrace. */
 
-       if (xptr != NULL) {
-               fprintf(stderr, "Exception while printStackTrace(): ");
+               if (builtin_instanceof(e, class_java_lang_Throwable)) {
+                       (void) vm_call_method(m, e);
 
-               /* now print original exception */
+                       /* If this happens we are EXTREMLY out of memory or have a
+                          serious problem while printStackTrace.  But may be
+                          another exception, so print it. */
 
-               exceptions_print_exception(xptr);
-               stacktrace_print_trace(xptr);
+                       ne = exceptions_get_exception();
 
-               /* now print original exception */
+                       if (ne != NULL) {
+                               fprintf(stderr, "Exception while printStackTrace(): ");
 
-               fprintf(stderr, "Original exception was: ");
-               exceptions_print_exception(oxptr);
-               stacktrace_print_trace(oxptr);
-       }
+                               /* Print the current exception. */
+
+                               exceptions_print_exception(ne);
+                               stacktrace_print_exception(ne);
 
-       fflush(stderr);
+                               /* Now print the original exception. */
+
+                               fprintf(stderr, "Original exception was: ");
+                               exceptions_print_exception(e);
+                               stacktrace_print_exception(e);
+                       }
+               }
+               else {
+                       fprintf(stderr, ". Uncaught exception of type ");
+#if !defined(NDEBUG)
+                       /* FIXME This prints to stdout. */
+                       class_print(c);
+#else
+                       fprintf(stderr, "UNKNOWN");
+#endif
+                       fprintf(stderr, ".");
+               }
+
+               fflush(stderr);
+       }
 }