Merged revisions 7501-7598 via svnmerge from
[cacao.git] / src / vm / exceptions.c
index 73465f1d69dbb9f3d9436eab5859d6c01aaf8a2a..6754a62beaa76b2034589bb217a5e32f632b066a 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/exceptions.c - exception related functions
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   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
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Christian Thalinger
-
-   Changes: Edwin Steiner
-
-   $Id: exceptions.c 6212 2006-12-18 16:27:09Z twisti $
+   $Id: exceptions.c 7596 2007-03-28 21:05:53Z twisti $
 
 */
 
 
 #include "vm/types.h"
 
+#include "md-abi.h"
+
 #include "mm/memory.h"
+
+#include "native/jni.h"
 #include "native/native.h"
 #include "native/include/java_lang_String.h"
 #include "native/include/java_lang_Throwable.h"
+
+#if defined(ENABLE_THREADS)
+# include "threads/native/threads.h"
+#else
+# include "threads/none/threads.h"
+#endif
+
 #include "toolbox/logging.h"
 #include "toolbox/util.h"
-#include "vm/class.h"
+
+#include "vm/builtin.h"
 #include "vm/exceptions.h"
 #include "vm/global.h"
-#include "vm/loader.h"
-#include "vm/options.h"
 #include "vm/stringlocal.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/stacktrace.h"
+
+#include "vmcore/class.h"
+#include "vmcore/loader.h"
+#include "vmcore/options.h"
 
 
 /* for raising exceptions from native methods *********************************/
@@ -82,34 +93,20 @@ bool exceptions_init(void)
                !link_class(class_java_lang_Throwable))
                return false;
 
-
-       /* java/lang/VMThrowable */
-
-       if (!(class_java_lang_VMThrowable =
-                 load_class_bootstrap(utf_java_lang_VMThrowable)) ||
-               !link_class(class_java_lang_VMThrowable))
-               return false;
-
-
        /* java/lang/Error */
 
        if (!(class_java_lang_Error = load_class_bootstrap(utf_java_lang_Error)) ||
                !link_class(class_java_lang_Error))
                return false;
 
-       /* java/lang/AbstractMethodError */
-
-       if (!(class_java_lang_AbstractMethodError =
-                 load_class_bootstrap(utf_java_lang_AbstractMethodError)) ||
-               !link_class(class_java_lang_AbstractMethodError))
-               return false;
-
+#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
 
        /* java/lang/NoClassDefFoundError */
 
@@ -118,13 +115,6 @@ bool exceptions_init(void)
                !link_class(class_java_lang_NoClassDefFoundError))
                return false;
 
-       /* java/lang/NoSuchMethodError */
-
-       if (!(class_java_lang_NoSuchMethodError =
-                 load_class_bootstrap(utf_java_lang_NoSuchMethodError)) ||
-               !link_class(class_java_lang_NoSuchMethodError))
-               return false;
-
        /* java/lang/OutOfMemoryError */
 
        if (!(class_java_lang_OutOfMemoryError =
@@ -132,6 +122,13 @@ bool exceptions_init(void)
                !link_class(class_java_lang_OutOfMemoryError))
                return false;
 
+       /* java/lang/VirtualMachineError */
+
+       if (!(class_java_lang_VirtualMachineError =
+                 load_class_bootstrap(utf_java_lang_VirtualMachineError)) ||
+               !link_class(class_java_lang_VirtualMachineError))
+               return false;
+
 
        /* java/lang/Exception */
 
@@ -154,20 +151,6 @@ bool exceptions_init(void)
                !link_class(class_java_lang_ClassNotFoundException))
                return false;
 
-       /* java/lang/IllegalArgumentException */
-
-       if (!(class_java_lang_IllegalArgumentException =
-                 load_class_bootstrap(utf_java_lang_IllegalArgumentException)) ||
-               !link_class(class_java_lang_IllegalArgumentException))
-               return false;
-
-       /* java/lang/IllegalMonitorStateException */
-
-       if (!(class_java_lang_IllegalMonitorStateException =
-                 load_class_bootstrap(utf_java_lang_IllegalMonitorStateException)) ||
-               !link_class(class_java_lang_IllegalMonitorStateException))
-               return false;
-
        /* java/lang/NullPointerException */
 
        if (!(class_java_lang_NullPointerException =
@@ -176,160 +159,151 @@ bool exceptions_init(void)
                return false;
 
 
+#if defined(WITH_CLASSPATH_GNU)
+       /* java/lang/VMThrowable */
+
+       if (!(class_java_lang_VMThrowable =
+                 load_class_bootstrap(utf_java_lang_VMThrowable)) ||
+               !link_class(class_java_lang_VMThrowable))
+               return false;
+#endif
+
        return true;
 }
 
 
-static void throw_exception_exit_intern(bool doexit)
-{
-       java_objectheader *xptr;
-       classinfo *c;
-       methodinfo *pss;
-
-       xptr = *exceptionptr;
+/* exceptions_new_class ********************************************************
 
-       if (xptr) {
-               /* clear exception, because we are calling jit code again */
-               *exceptionptr = NULL;
+   Creates an exception object from the given class and initalizes it.
 
-               c = xptr->vftbl->class;
+   IN:
+      class....class pointer
 
-               pss = class_resolveclassmethod(c,
-                                                                          utf_printStackTrace,
-                                                                          utf_void__void,
-                                                                          class_java_lang_Object,
-                                                                          false);
+*******************************************************************************/
 
-               /* print the stacktrace */
+static java_objectheader *exceptions_new_class(classinfo *c)
+{
+       java_objectheader *o;
 
-               if (pss) {
-                       (void) vm_call_method(pss, xptr);
+       o = native_new_and_init(c);
 
-                       /* 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 (o == NULL)
+               return *exceptionptr;
 
-                       if (*exceptionptr) {
-                               java_lang_Throwable *t;
+       return o;
+}
 
-                               t = (java_lang_Throwable *) *exceptionptr;
 
-                               fprintf(stderr, "Exception while printStackTrace(): ");
-                               utf_fprint_printable_ascii_classname(stderr, t->header.vftbl->class->name);
+/* exceptions_new_utf **********************************************************
 
-                               if (t->detailMessage) {
-                                       char *buf;
+   Creates an exception object with the given name and initalizes it.
 
-                                       buf = javastring_tochar((java_objectheader *) t->detailMessage);
-                                       fprintf(stderr, ": %s", buf);
-                                       MFREE(buf, char, strlen(buf));
-                               }
-                                       
-                               fprintf(stderr, "\n");
-                       }
+   IN:
+      classname....class name in UTF-8
 
-               } else {
-                       utf_fprint_printable_ascii_classname(stderr, c->name);
-                       fprintf(stderr, ": printStackTrace()V not found!\n");
-               }
+*******************************************************************************/
 
-               fflush(stderr);
+static java_objectheader *exceptions_new_utf(utf *classname)
+{
+       classinfo         *c;
+       java_objectheader *o;
 
-               /* good bye! */
+       c = load_class_bootstrap(classname);
 
-               if (doexit)
-                       exit(1);
-       }
-}
+       if (c == NULL)
+               return *exceptionptr;
 
+       o = exceptions_new_class(c);
 
-void throw_exception(void)
-{
-       throw_exception_exit_intern(false);
+       return o;
 }
 
 
-void throw_exception_exit(void)
-{
-       throw_exception_exit_intern(true);
-}
-
+/* exceptions_throw_class ******************************************************
 
-void throw_main_exception(void)
-{
-       fprintf(stderr, "Exception in thread \"main\" ");
-       fflush(stderr);
+   Creates an exception object from the given class, initalizes and
+   throws it.
 
-       throw_exception_exit_intern(false);
-}
+   IN:
+      class....class pointer
 
+*******************************************************************************/
 
-void throw_main_exception_exit(void)
+static void exceptions_throw_class(classinfo *c)
 {
-       fprintf(stderr, "Exception in thread \"main\" ");
-       fflush(stderr);
-
-       throw_exception_exit_intern(true);
-}
+       java_objectheader *o;
 
+       o = exceptions_new_class(c);
 
-void throw_cacao_exception_exit(const char *exception, const char *message, ...)
-{
-       s4 i;
-       char *tmp;
-       s4 len;
-       va_list ap;
+       if (o == NULL)
+               return;
 
-       len = strlen(exception);
-       tmp = MNEW(char, len + 1);
-       strncpy(tmp, exception, len);
-       tmp[len] = '\0';
+       *exceptionptr = o;
+}
 
-       /* convert to classname */
 
-       for (i = len - 1; i >= 0; i--)
-               if (tmp[i] == '/') tmp[i] = '.';
+/* exceptions_throw_utf ********************************************************
 
-       fprintf(stderr, "Exception in thread \"main\" %s", tmp);
+   Creates an exception object with the given name, initalizes and
+   throws it.
 
-       MFREE(tmp, char, len);
+   IN:
+      classname....class name in UTF-8
 
-       if (strlen(message) > 0) {
-               fprintf(stderr, ": ");
+*******************************************************************************/
 
-               va_start(ap, message);
-               vfprintf(stderr, message, ap);
-               va_end(ap);
-       }
+static void exceptions_throw_utf(utf *classname)
+{
+       classinfo *c;
 
-       fprintf(stderr, "\n");
-       fflush(stderr);
+       c = load_class_bootstrap(classname);
 
-       /* good bye! */
+       if (c == NULL)
+               return;
 
-       exit(1);
+       exceptions_throw_class(c);
 }
 
 
-/* exceptions_throw_outofmemory_exit *******************************************
+/* exceptions_throw_utf_throwable **********************************************
 
-   Just print an: java.lang.InternalError: Out of memory
+   Creates an exception object with the given name and initalizes it
+   with the given java/lang/Throwable exception.
+
+   IN:
+      classname....class name in UTF-8
+         cause........the given Throwable
 
 *******************************************************************************/
 
-void exceptions_throw_outofmemory_exit(void)
+static void exceptions_throw_utf_throwable(utf *classname,
+                                                                                  java_objectheader *cause)
 {
-       throw_cacao_exception_exit(string_java_lang_InternalError,
-                                                          "Out of memory");
+       java_objectheader *o;
+       classinfo         *c;
+   
+       c = load_class_bootstrap(classname);
+
+       if (c == NULL)
+               return;
+
+       o = native_new_and_init_throwable(c, cause);
+
+       if (o == NULL)
+               return;
+
+       *exceptionptr = o;
 }
 
 
-/* new_exception ***************************************************************
+/* exceptions_new_utf_javastring ***********************************************
 
-   Creates an exception object with the given name and initalizes it.
+   Creates an exception object with the given name and initalizes it
+   with the given java/lang/String message.
 
    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
@@ -337,59 +311,63 @@ void exceptions_throw_outofmemory_exit(void)
 
 *******************************************************************************/
 
-java_objectheader *new_exception(const char *classname)
+static java_objectheader *exceptions_new_utf_javastring(utf *classname,
+                                                                                                               java_objectheader *message)
 {
        java_objectheader *o;
        classinfo         *c;
+   
+       c = load_class_bootstrap(classname);
 
-       if (!(c = load_class_bootstrap(utf_new_char(classname))))
+       if (c == NULL)
                return *exceptionptr;
 
-       o = native_new_and_init(c);
+       o = native_new_and_init_string(c, message);
 
-       if (!o)
+       if (o == NULL)
                return *exceptionptr;
 
        return o;
 }
 
 
-/* new_exception_message *******************************************************
+/* exceptions_new_class_utf ****************************************************
 
-   Creates an exception object with the given name and initalizes it
-   with the given char message.
+   Creates an exception object of the given class and initalizes it.
 
    IN:
-      classname....class name in UTF-8
-         message......message in UTF-8
-
-   RETURN VALUE:
-      an exception pointer (in any case -- either it is the newly created
-         exception, or an exception thrown while trying to create it).
+      c..........class pointer
+      message....the message as UTF-8 string
 
 *******************************************************************************/
 
-java_objectheader *new_exception_message(const char *classname,
-                                                                                const char *message)
+static java_objectheader *exceptions_new_class_utf(classinfo *c, utf *message)
 {
-       java_lang_String *s;
+       java_objectheader *o;
+       java_objectheader *s;
 
-       s = javastring_new_from_utf_string(message);
-       if (!s)
+       s = javastring_new(message);
+
+       if (s == NULL)
+               return *exceptionptr;
+
+       o = native_new_and_init_string(c, s);
+
+       if (o == NULL)
                return *exceptionptr;
 
-       return new_exception_javastring(classname, s);
+       return o;
 }
 
 
-/* new_exception_throwable *****************************************************
+/* exceptions_new_utf_utf ******************************************************
 
    Creates an exception object with the given name and initalizes it
-   with the given java/lang/Throwable exception.
+   with the given utf message.
 
    IN:
       classname....class name in UTF-8
-         throwable....the given Throwable
+         message......the message as an utf *
 
    RETURN VALUE:
       an exception pointer (in any case -- either it is the newly created
@@ -397,32 +375,30 @@ java_objectheader *new_exception_message(const char *classname,
 
 *******************************************************************************/
 
-java_objectheader *new_exception_throwable(const char *classname,
-                                                                                  java_lang_Throwable *throwable)
+static java_objectheader *exceptions_new_utf_utf(utf *classname, utf *message)
 {
-       java_objectheader *o;
        classinfo         *c;
-   
-       if (!(c = load_class_bootstrap(utf_new_char(classname))))
-               return *exceptionptr;
+       java_objectheader *o;
 
-       o = native_new_and_init_throwable(c, throwable);
+       c = load_class_bootstrap(classname);
 
-       if (!o)
+       if (c == NULL)
                return *exceptionptr;
 
+       o = exceptions_new_class_utf(c, message);
+
        return o;
 }
 
 
-/* new_exception_utfmessage ****************************************************
+/* new_exception_message *******************************************************
 
    Creates an exception object with the given name and initalizes it
-   with the given utf message.
+   with the given char message.
 
    IN:
       classname....class name in UTF-8
-         message......the message as an utf *
+         message......message in UTF-8
 
    RETURN VALUE:
       an exception pointer (in any case -- either it is the newly created
@@ -430,48 +406,54 @@ java_objectheader *new_exception_throwable(const char *classname,
 
 *******************************************************************************/
 
-java_objectheader *new_exception_utfmessage(const char *classname, utf *message)
+static java_objectheader *new_exception_message(const char *classname,
+                                                                                               const char *message)
 {
-       java_lang_String *s;
+       java_objectheader *o;
+       java_objectheader *s;
 
-       s = javastring_new(message);
-       if (!s)
+       s = javastring_new_from_utf_string(message);
+
+       if (s == NULL)
                return *exceptionptr;
 
-       return new_exception_javastring(classname, s);
+       o = exceptions_new_utf_javastring(classname, s);
+
+       return o;
 }
 
 
-/* new_exception_javastring ****************************************************
+/* exceptions_throw_class_utf **************************************************
 
-   Creates an exception object with the given name and initalizes it
-   with the given java/lang/String message.
+   Creates an exception object of the given class, initalizes and
+   throws it with the given utf message.
 
    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).
+      c..........class pointer
+         message....the message as an UTF-8
 
 *******************************************************************************/
 
-java_objectheader *new_exception_javastring(const char *classname,
-                                                                                       java_lang_String *message)
+static void exceptions_throw_class_utf(classinfo *c, utf *message)
 {
-       java_objectheader *o;
-       classinfo         *c;
-   
-       if (!(c = load_class_bootstrap(utf_new_char(classname))))
-               return *exceptionptr;
+       *exceptionptr = exceptions_new_class_utf(c, message);
+}
 
-       o = native_new_and_init_string(c, message);
 
-       if (!o)
-               return *exceptionptr;
+/* exceptions_throw_utf_utf ****************************************************
 
-       return o;
+   Creates an exception object with the given name, initalizes and
+   throws it with the given utf message.
+
+   IN:
+      classname....class name in UTF-8
+         message......the message as an utf *
+
+*******************************************************************************/
+
+static void exceptions_throw_utf_utf(utf *classname, utf *message)
+{
+       *exceptionptr = exceptions_new_utf_utf(classname, message);
 }
 
 
@@ -507,7 +489,7 @@ java_objectheader *new_exception_int(const char *classname, s4 i)
 }
 
 
-/* exceptions_new_abstractmethoderror ******************************************
+/* exceptions_new_abstractmethoderror ****************************************
 
    Generates a java.lang.AbstractMethodError for the VM.
 
@@ -515,15 +497,30 @@ java_objectheader *new_exception_int(const char *classname, s4 i)
 
 java_objectheader *exceptions_new_abstractmethoderror(void)
 {
-       java_objectheader *e;
+       java_objectheader *o;
 
-       e = native_new_and_init(class_java_lang_AbstractMethodError);
+       o = exceptions_new_utf(utf_java_lang_AbstractMethodError);
 
-       if (e == NULL)
-               return *exceptionptr;
+       return o;
+}
 
-       return e;
+
+/* exceptions_new_error ********************************************************
+
+   Generates a java.lang.Error for the VM.
+
+*******************************************************************************/
+
+#if defined(ENABLE_JAVAME_CLDC1_1)
+static java_objectheader *exceptions_new_error(utf *message)
+{
+       java_objectheader *o;
+
+       o = exceptions_new_class_utf(class_java_lang_Error, message);
+
+       return o;
 }
+#endif
 
 
 /* exceptions_asm_new_abstractmethoderror **************************************
@@ -544,7 +541,11 @@ java_objectheader *exceptions_asm_new_abstractmethoderror(u1 *sp, u1 *ra)
 
        /* create the exception */
 
+#if defined(ENABLE_JAVASE)
        e = exceptions_new_abstractmethoderror();
+#else
+       e = exceptions_new_error(utf_java_lang_AbstractMethodError);
+#endif
 
        /* remove the stackframeinfo */
 
@@ -554,33 +555,84 @@ java_objectheader *exceptions_asm_new_abstractmethoderror(u1 *sp, u1 *ra)
 }
 
 
+/* exceptions_new_arraystoreexception ******************************************
+
+   Generates a java.lang.ArrayStoreException for the VM.
+
+*******************************************************************************/
+
+java_objectheader *exceptions_new_arraystoreexception(void)
+{
+       java_objectheader *o;
+
+       o = exceptions_new_utf(utf_java_lang_ArrayStoreException);
+
+       return o;
+}
+
+
 /* exceptions_throw_abstractmethoderror ****************************************
 
-   Generates a java.lang.AbstractMethodError for the VM and throws it.
+   Generates and throws a java.lang.AbstractMethodError for the VM.
 
 *******************************************************************************/
 
 void exceptions_throw_abstractmethoderror(void)
 {
-       *exceptionptr = exceptions_new_abstractmethoderror();
+       exceptions_throw_utf(utf_java_lang_AbstractMethodError);
 }
 
 
-/* new_classformaterror ********************************************************
+/* exceptions_throw_classcircularityerror **************************************
 
-   generates a java.lang.ClassFormatError for the classloader
+   Generates and throws a java.lang.ClassCircularityError for the
+   classloader.
 
    IN:
       c............the class in which the error was found
-         message......UTF-8 format 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).
+*******************************************************************************/
+
+void exceptions_throw_classcircularityerror(classinfo *c)
+{
+       java_objectheader *o;
+       char              *msg;
+       s4                 msglen;
+
+       /* calculate message length */
+
+       msglen = utf_bytes(c->name) + strlen("0");
+
+       /* allocate a buffer */
+
+       msg = MNEW(char, msglen);
+
+       /* print message into allocated buffer */
+
+       utf_copy_classname(msg, c->name);
+
+       o = new_exception_message(utf_java_lang_ClassCircularityError, msg);
+
+       MFREE(msg, char, msglen);
+
+       if (o == NULL)
+               return;
+
+       *exceptionptr = o;
+}
+
+
+/* exceptions_throw_classformaterror *******************************************
+
+   Generates and throws a java.lang.ClassFormatError for the VM.
+
+   IN:
+      c............the class in which the error was found
+         message......UTF-8 format string
 
 *******************************************************************************/
 
-java_objectheader *new_classformaterror(classinfo *c, const char *message, ...)
+void exceptions_throw_classformaterror(classinfo *c, const char *message, ...)
 {
        java_objectheader *o;
        char              *msg;
@@ -591,14 +643,14 @@ java_objectheader *new_classformaterror(classinfo *c, const char *message, ...)
 
        msglen = 0;
 
-       if (c)
+       if (c != NULL)
                msglen += utf_bytes(c->name) + strlen(" (");
 
        va_start(ap, message);
        msglen += get_variable_message_length(message, ap);
        va_end(ap);
 
-       if (c)
+       if (c != NULL)
                msglen += strlen(")");
 
        msglen += strlen("0");
@@ -609,7 +661,7 @@ java_objectheader *new_classformaterror(classinfo *c, const char *message, ...)
 
        /* print message into allocated buffer */
 
-       if (c) {
+       if (c != NULL) {
                utf_copy_classname(msg, c->name);
                strcat(msg, " (");
        }
@@ -618,100 +670,86 @@ java_objectheader *new_classformaterror(classinfo *c, const char *message, ...)
        vsprintf(msg + strlen(msg), message, ap);
        va_end(ap);
 
-       if (c)
+       if (c != NULL)
                strcat(msg, ")");
 
-       o = new_exception_message(string_java_lang_ClassFormatError, msg);
+       o = new_exception_message(utf_java_lang_ClassFormatError, msg);
 
        MFREE(msg, char, msglen);
 
-       return o;
+       *exceptionptr = o;
 }
 
 
-/* exceptions_throw_classformaterror *******************************************
+/* exceptions_throw_classnotfoundexception *************************************
 
-   Generate a java.lang.ClassFormatError for the VM system and throw it.
+   Generates and throws a java.lang.ClassNotFoundException for the
+   VM.
 
    IN:
-      c............the class in which the error was found
-         message......UTF-8 format 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).
+      name.........name of the class not found as a utf *
 
 *******************************************************************************/
 
-void exceptions_throw_classformaterror(classinfo *c, const char *message, ...)
+void exceptions_throw_classnotfoundexception(utf *name)
 {
-       va_list ap;
+       /* we use class here, as this one is rather frequent */
 
-       va_start(ap, message);
-       *exceptionptr = new_classformaterror(c, message, ap);
-       va_end(ap);
+       exceptions_throw_class_utf(class_java_lang_ClassNotFoundException, name);
 }
 
 
-/* new_classnotfoundexception **************************************************
+/* exceptions_throw_noclassdeffounderror ***************************************
 
-   Generates a java.lang.ClassNotFoundException for the classloader.
+   Generates and throws a java.lang.NoClassDefFoundError.
 
    IN:
       name.........name of the class not found as a 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).
-
 *******************************************************************************/
 
-java_objectheader *new_classnotfoundexception(utf *name)
+void exceptions_throw_noclassdeffounderror(utf *name)
 {
-       java_objectheader *o;
-       java_lang_String  *s;
+       if (vm_initializing)
+               vm_abort("java.lang.NoClassDefFoundError: %s", name->text);
 
-       s = javastring_new(name);
-       if (!s)
-               return *exceptionptr;
+       exceptions_throw_class_utf(class_java_lang_NoClassDefFoundError, name);
+}
 
-       o = native_new_and_init_string(class_java_lang_ClassNotFoundException, s);
 
-       if (!o)
-               return *exceptionptr;
-
-       return o;
-}
+/* exceptions_throw_noclassdeffounderror_wrong_name ****************************
 
+   Generates and throws a java.lang.NoClassDefFoundError with a
+   specific message:
 
-/* new_noclassdeffounderror ****************************************************
 
-   Generates a java.lang.NoClassDefFoundError
 
    IN:
       name.........name of the class not found as a 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).
-
 *******************************************************************************/
 
-java_objectheader *new_noclassdeffounderror(utf *name)
+void exceptions_throw_noclassdeffounderror_wrong_name(classinfo *c, utf *name)
 {
-       java_objectheader *o;
-       java_lang_String  *s;
+       char *msg;
+       s4    msglen;
+       utf  *u;
 
-       s = javastring_new(name);
-       if (!s)
-               return *exceptionptr;
+       msglen = utf_bytes(c->name) + strlen(" (wrong name: ") +
+               utf_bytes(name) + strlen(")") + strlen("0");
 
-       o = native_new_and_init_string(class_java_lang_NoClassDefFoundError, s);
+       msg = MNEW(char, msglen);
 
-       if (!o)
-               return *exceptionptr;
+       utf_copy_classname(msg, c->name);
+       strcat(msg, " (wrong name: ");
+       utf_cat_classname(msg, name);
+       strcat(msg, ")");
 
-       return o;
+       u = utf_new_char(msg);
+
+       MFREE(msg, char, msglen);
+
+       exceptions_throw_noclassdeffounderror(u);
 }
 
 
@@ -724,8 +762,10 @@ java_objectheader *new_noclassdeffounderror(utf *name)
 
 void classnotfoundexception_to_noclassdeffounderror(void)
 {
-       java_objectheader *xptr;
-       java_objectheader *cause;
+       java_objectheader   *xptr;
+       java_objectheader   *cause;
+       java_lang_Throwable *t;
+       java_lang_String    *s;
 
        /* get the cause */
 
@@ -740,9 +780,10 @@ void classnotfoundexception_to_noclassdeffounderror(void)
 
                /* create new error */
 
-               xptr =
-                       new_exception_javastring(string_java_lang_NoClassDefFoundError,
-                                       ((java_lang_Throwable *) cause)->detailMessage);
+               t = (java_lang_Throwable *) cause;
+               s = t->detailMessage;
+
+               xptr = exceptions_new_utf_javastring(utf_java_lang_NoClassDefFoundError, s);
 
                /* we had an exception while creating the error */
 
@@ -756,57 +797,79 @@ void classnotfoundexception_to_noclassdeffounderror(void)
 }
 
 
-/* new_internalerror ***********************************************************
+/* exceptions_throw_exceptionininitializererror ********************************
 
-   Generates a java.lang.InternalError for the VM.
+   Generates and throws a java.lang.ExceptionInInitializerError for
+   the VM.
 
    IN:
-      message......UTF-8 message format string
+      cause......cause exception object
+
+*******************************************************************************/
+
+void exceptions_throw_exceptionininitializererror(java_objectheader *cause)
+{
+       exceptions_throw_utf_throwable(utf_java_lang_ExceptionInInitializerError,
+                                                                  cause);
+}
 
-   RETURN VALUE:
-      an exception pointer (in any case -- either it is the newly created
-         exception, or an exception thrown while trying to create it).
+
+/* exceptions_throw_incompatibleclasschangeerror *******************************
+
+   Generates and throws a java.lang.IncompatibleClassChangeError for
+   the VM.
+
+   IN:
+      message......UTF-8 message format string
 
 *******************************************************************************/
 
-java_objectheader *new_internalerror(const char *message, ...)
+void exceptions_throw_incompatibleclasschangeerror(classinfo *c, const char *message)
 {
        java_objectheader *o;
-       va_list            ap;
        char              *msg;
        s4                 msglen;
 
        /* calculate exception message length */
 
-       va_start(ap, message);
-       msglen = get_variable_message_length(message, ap);
-       va_end(ap);
+       msglen = utf_bytes(c->name) + strlen(message) + strlen("0");
 
        /* allocate memory */
 
        msg = MNEW(char, msglen);
 
-       /* generate message */
-
-       va_start(ap, message);
-       vsprintf(msg, message, ap);
-       va_end(ap);
-
-       /* create exception object */
+       utf_copy_classname(msg, c->name);
+       strcat(msg, message);
 
-       o = new_exception_message(string_java_lang_InternalError, msg);
+       o = native_new_and_init_string(utf_java_lang_IncompatibleClassChangeError,
+                                                                  javastring_new_from_utf_string(msg));
 
        /* free memory */
 
        MFREE(msg, char, msglen);
 
-       return o;
+       if (o == NULL)
+               return;
+
+       *exceptionptr = o;
+}
+
+
+/* exceptions_throw_instantiationerror *****************************************
+
+   Generates and throws a java.lang.InstantiationError for the VM.
+
+*******************************************************************************/
+
+void exceptions_throw_instantiationerror(classinfo *c)
+{
+       exceptions_throw_utf_utf(utf_java_lang_InstantiationError, c->name);
 }
 
 
 /* exceptions_throw_internalerror **********************************************
 
-   Generates a java.lang.InternalError for the VM.
+   Generates and throws a java.lang.InternalError for the VM.
 
    IN:
       message......UTF-8 message format string
@@ -815,31 +878,54 @@ java_objectheader *new_internalerror(const char *message, ...)
 
 void exceptions_throw_internalerror(const char *message, ...)
 {
-       va_list ap;
+       java_objectheader *o;
+       va_list            ap;
+       char              *msg;
+       s4                 msglen;
+
+       /* calculate exception message length */
+
+       va_start(ap, message);
+       msglen = get_variable_message_length(message, ap);
+       va_end(ap);
+
+       /* allocate memory */
+
+       msg = MNEW(char, msglen);
+
+       /* generate message */
 
        va_start(ap, message);
-       *exceptionptr = new_internalerror(message, ap);
+       vsprintf(msg, message, ap);
        va_end(ap);
+
+       /* create exception object */
+
+       o = new_exception_message(utf_java_lang_InternalError, msg);
+
+       /* free memory */
+
+       MFREE(msg, char, msglen);
+
+       if (o == NULL)
+               return;
+
+       *exceptionptr = o;
 }
 
 
-/* exceptions_new_linkageerror *************************************************
+/* exceptions_throw_linkageerror ***********************************************
 
-   Generates a java.lang.LinkageError with an error message.
+   Generates and throws java.lang.LinkageError with an error message.
 
    IN:
       message......UTF-8 message
          c............class related to the error. If this is != NULL
                       the name of c is appended to the error message.
 
-   RETURN VALUE:
-      an exception pointer (in any case -- either it is the newly created
-         exception, or an exception thrown while trying to create it).
-
 *******************************************************************************/
 
-java_objectheader *exceptions_new_linkageerror(const char *message,
-                                                                                          classinfo *c)
+void exceptions_throw_linkageerror(const char *message, classinfo *c)
 {
        java_objectheader *o;
        char              *msg;
@@ -848,9 +934,9 @@ java_objectheader *exceptions_new_linkageerror(const char *message,
        /* calculate exception message length */
 
        msglen = strlen(message) + 1;
-       if (c) {
+
+       if (c != NULL)
                msglen += utf_bytes(c->name);
-       }
                
        /* allocate memory */
 
@@ -859,9 +945,9 @@ java_objectheader *exceptions_new_linkageerror(const char *message,
        /* generate message */
 
        strcpy(msg,message);
-       if (c) {
+
+       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));
@@ -870,34 +956,71 @@ java_objectheader *exceptions_new_linkageerror(const char *message,
 
        MFREE(msg, char, msglen);
 
-       if (!o)
-               return *exceptionptr;
+       if (o == NULL)
+               return;
 
-       return o;
+       *exceptionptr = o;
 }
 
 
-/* exceptions_new_nosuchmethoderror ********************************************
+/* exceptions_throw_nosuchfielderror *******************************************
 
-   Generates a java.lang.NoSuchMethodError with an error message.
+   Generates and throws a java.lang.NoSuchFieldError with an error
+   message.
+
+   IN:
+      c............class in which the field was not found
+         name.........name of the field
+
+*******************************************************************************/
+
+void exceptions_throw_nosuchfielderror(classinfo *c, utf *name)
+{
+       char *msg;
+       s4    msglen;
+       utf  *u;
+
+       /* calculate exception message length */
+
+       msglen = utf_bytes(c->name) + strlen(".") + utf_bytes(name) + strlen("0");
+
+       /* allocate memory */
+
+       msg = MNEW(char, msglen);
+
+       /* generate message */
+
+       utf_copy_classname(msg, c->name);
+       strcat(msg, ".");
+       utf_cat(msg, name);
+
+       u = utf_new_char(msg);
+
+       /* free memory */
+
+       MFREE(msg, char, msglen);
+
+       exceptions_throw_utf_utf(utf_java_lang_NoSuchFieldError, u);
+}
+
+
+/* exceptions_throw_nosuchmethoderror ******************************************
+
+   Generates and throws a java.lang.NoSuchMethodError with an error
+   message.
 
    IN:
       c............class in which the method was not found
          name.........name of the method
          desc.........descriptor of the method
 
-   RETURN VALUE:
-      an exception pointer (in any case -- either it is the newly created
-         exception, or an exception thrown while trying to create it).
-
 *******************************************************************************/
 
-java_objectheader *exceptions_new_nosuchmethoderror(classinfo *c,
-                                                                                                       utf *name, utf *desc)
+void exceptions_throw_nosuchmethoderror(classinfo *c, utf *name, utf *desc)
 {
-       java_objectheader *o;
-       char              *msg;
-       s4                 msglen;
+       char *msg;
+       s4    msglen;
+       utf  *u;
 
        /* calculate exception message length */
 
@@ -915,65 +1038,71 @@ java_objectheader *exceptions_new_nosuchmethoderror(classinfo *c,
        utf_cat(msg, name);
        utf_cat(msg, desc);
 
-       o = native_new_and_init_string(class_java_lang_NoSuchMethodError,
-                                                                  javastring_new_from_utf_string(msg));
+       u = utf_new_char(msg);
 
        /* free memory */
 
        MFREE(msg, char, msglen);
 
-       if (!o)
-               return *exceptionptr;
+       exceptions_throw_utf_utf(utf_java_lang_NoSuchMethodError, u);
+}
 
-       return o;
+
+/* exceptions_throw_outofmemoryerror *******************************************
+
+   Generates and throws an java.lang.OutOfMemoryError for the VM.
+
+*******************************************************************************/
+
+void exceptions_throw_outofmemoryerror(void)
+{
+       exceptions_throw_class(class_java_lang_OutOfMemoryError);
 }
 
 
-/* exceptions_throw_nosuchmethoderror ******************************************
+/* exceptions_throw_unsatisfiedlinkerror ***************************************
 
-   Generates a java.lang.NoSuchMethodError with an error message.
+   Generates and throws a java.lang.UnsatisfiedLinkError for the
+   classloader.
 
    IN:
-      c............class in which the method was not found
-         name.........name of the method
-         desc.........descriptor of the method
+         name......UTF-8 name string
 
 *******************************************************************************/
 
-void exceptions_throw_nosuchmethoderror(classinfo *c, utf *name, utf *desc)
+void exceptions_throw_unsatisfiedlinkerror(utf *name)
 {
-       *exceptionptr = exceptions_new_nosuchmethoderror(c, name, desc);
+#if defined(ENABLE_JAVASE)
+       exceptions_throw_utf_utf(utf_java_lang_UnsatisfiedLinkError, name);
+#else
+       exceptions_throw_class_utf(class_java_lang_Error, name);
+#endif
 }
 
 
-/* new_unsupportedclassversionerror ********************************************
+/* exceptions_throw_unsupportedclassversionerror *******************************
 
-   Generate a java.lang.UnsupportedClassVersionError for the classloader
+   Generates and throws a java.lang.UnsupportedClassVersionError for
+   the classloader.
 
    IN:
-      c............class in which the method was not found
-         message......UTF-8 format 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).
+      c............class in which the method was not found
+         message......UTF-8 format string
 
 *******************************************************************************/
 
-java_objectheader *new_unsupportedclassversionerror(classinfo *c, const char *message, ...)
+void exceptions_throw_unsupportedclassversionerror(classinfo *c, u4 ma, u4 mi)
 {
        java_objectheader *o;
-       va_list            ap;
        char              *msg;
     s4                 msglen;
 
        /* calculate exception message length */
 
-       msglen = utf_bytes(c->name) + strlen(" (") + strlen(")") + strlen("0");
-
-       va_start(ap, message);
-       msglen += get_variable_message_length(message, ap);
-       va_end(ap);
+       msglen =
+               utf_bytes(c->name) +
+               strlen(" (Unsupported major.minor version 00.0)") +
+               strlen("0");
 
        /* allocate memory */
 
@@ -982,57 +1111,48 @@ java_objectheader *new_unsupportedclassversionerror(classinfo *c, const char *me
        /* generate message */
 
        utf_copy_classname(msg, c->name);
-       strcat(msg, " (");
-
-       va_start(ap, message);
-       vsprintf(msg + strlen(msg), message, ap);
-       va_end(ap);
-
-       strcat(msg, ")");
+       sprintf(msg + strlen(msg), " (Unsupported major.minor version %d.%d)",
+                       ma, mi);
 
        /* create exception object */
 
-       o = new_exception_message(string_java_lang_UnsupportedClassVersionError,
-                                                         msg);
+       o = new_exception_message(utf_java_lang_UnsupportedClassVersionError, msg);
 
        /* free memory */
 
        MFREE(msg, char, msglen);
 
-       return o;
+       if (o == NULL)
+               return;
+
+       *exceptionptr = o;
 }
 
 
-/* exceptions_new_verifyerror **************************************************
+/* exceptions_throw_verifyerror ************************************************
 
-   Generates a java.lang.VerifyError for the JIT compiler.
+   Generates and throws a java.lang.VerifyError for the JIT compiler.
 
    IN:
       m............method in which the error was found
          message......UTF-8 format 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).
-
 *******************************************************************************/
 
-java_objectheader *exceptions_new_verifyerror(methodinfo *m,
-                                                                                         const char *message, ...)
+void exceptions_throw_verifyerror(methodinfo *m, const char *message, ...)
 {
        java_objectheader *o;
        va_list            ap;
        char              *msg;
        s4                 msglen;
 
-       useinlining = false; /* at least until sure inlining works with exceptions*/
-
        /* calculate exception message length */
 
        msglen = 0;
 
-       if (m)
-               msglen = strlen("(class: ") + utf_bytes(m->class->name) +
+       if (m != NULL)
+               msglen =
+                       strlen("(class: ") + utf_bytes(m->class->name) +
                        strlen(", method: ") + utf_bytes(m->name) +
                        strlen(" signature: ") + utf_bytes(m->descriptor) +
                        strlen(") ") + strlen("0");
@@ -1047,7 +1167,7 @@ java_objectheader *exceptions_new_verifyerror(methodinfo *m,
 
        /* generate message */
 
-       if (m) {
+       if (m != NULL) {
                strcpy(msg, "(class: ");
                utf_cat_classname(msg, m->class->name);
                strcat(msg, ", method: ");
@@ -1063,25 +1183,13 @@ java_objectheader *exceptions_new_verifyerror(methodinfo *m,
 
        /* create exception object */
 
-       o = new_exception_message(string_java_lang_VerifyError, msg);
+       o = new_exception_message(utf_java_lang_VerifyError, msg);
 
        /* free memory */
 
        MFREE(msg, char, msglen);
 
-       return o;
-}
-
-
-/* exceptions_throw_verifyerror ************************************************
-
-   Throws a java.lang.VerifyError for the VM system.
-
-*******************************************************************************/
-
-void exceptions_throw_verifyerror(methodinfo *m, const char *message, ...)
-{
-       *exceptionptr = exceptions_new_verifyerror(m, message);
+       *exceptionptr = o;
 }
 
 
@@ -1151,7 +1259,7 @@ void exceptions_throw_verifyerror_for_stack(methodinfo *m,int type)
 
        /* create exception object */
 
-       o = new_exception_message(string_java_lang_VerifyError, msg);
+       o = new_exception_message(utf_java_lang_VerifyError, msg);
 
        /* free memory */
 
@@ -1161,23 +1269,22 @@ void exceptions_throw_verifyerror_for_stack(methodinfo *m,int type)
 }
 
 
-/* new_arithmeticexception *****************************************************
+/* exceptions_new_arithmeticexception ******************************************
 
-   Generates a java.lang.ArithmeticException for the jit compiler.
+   Generates a java.lang.ArithmeticException for the JIT compiler.
 
 *******************************************************************************/
 
-java_objectheader *new_arithmeticexception(void)
+java_objectheader *exceptions_new_arithmeticexception(void)
 {
-       java_objectheader *e;
+       java_objectheader *o;
 
-       e = new_exception_message(string_java_lang_ArithmeticException,
-                                                         string_java_lang_ArithmeticException_message);
+       o = new_exception_message(utf_java_lang_ArithmeticException, "/ by zero");
 
-       if (!e)
+       if (o == NULL)
                return *exceptionptr;
 
-       return e;
+       return o;
 }
 
 
@@ -1188,12 +1295,11 @@ java_objectheader *new_arithmeticexception(void)
 
 *******************************************************************************/
 
-java_objectheader *new_arrayindexoutofboundsexception(s4 index)
+java_objectheader *exceptions_new_arrayindexoutofboundsexception(s4 index)
 {
-       java_objectheader *e;
-       methodinfo        *m;
        java_objectheader *o;
-       java_lang_String  *s;
+       methodinfo        *m;
+       java_objectheader *s;
 
        /* convert the index into a String, like Sun does */
 
@@ -1206,73 +1312,44 @@ java_objectheader *new_arrayindexoutofboundsexception(s4 index)
        if (m == NULL)
                return *exceptionptr;
 
-       o = vm_call_method(m, NULL, index);
-
-       s = (java_lang_String *) o;
+       s = vm_call_method(m, NULL, index);
 
        if (s == NULL)
                return *exceptionptr;
 
-       e = new_exception_javastring(string_java_lang_ArrayIndexOutOfBoundsException,
-                                                                s);
+       o = exceptions_new_utf_javastring(utf_java_lang_ArrayIndexOutOfBoundsException,
+                                                                         s);
 
-       if (e == NULL)
+       if (o == NULL)
                return *exceptionptr;
 
-       return e;
+       return o;
 }
 
 
 /* exceptions_throw_arrayindexoutofboundsexception *****************************
 
-   Generates a java.lang.ArrayIndexOutOfBoundsException for the VM
-   system.
+   Generates and throws a java.lang.ArrayIndexOutOfBoundsException for
+   the VM.
 
 *******************************************************************************/
 
 void exceptions_throw_arrayindexoutofboundsexception(void)
 {
-       java_objectheader *e;
-
-       e = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
-
-       if (!e)
-               return;
-
-       *exceptionptr = e;
-}
-
-
-/* exceptions_new_arraystoreexception ******************************************
-
-   Generates a java.lang.ArrayStoreException for the VM compiler.
-
-*******************************************************************************/
-
-java_objectheader *exceptions_new_arraystoreexception(void)
-{
-       java_objectheader *e;
-
-       e = new_exception(string_java_lang_ArrayStoreException);
-/*     e = native_new_and_init(class_java_lang_ArrayStoreException); */
-
-       if (!e)
-               return *exceptionptr;
-
-       return e;
+       exceptions_throw_utf(utf_java_lang_ArrayIndexOutOfBoundsException);
 }
 
 
 /* exceptions_throw_arraystoreexception ****************************************
 
-   Generates a java.lang.ArrayStoreException for the VM system and
-   throw it in the VM system.
+   Generates and throws a java.lang.ArrayStoreException for the VM.
 
 *******************************************************************************/
 
 void exceptions_throw_arraystoreexception(void)
 {
-       *exceptionptr = exceptions_new_arraystoreexception();
+       exceptions_throw_utf(utf_java_lang_ArrayStoreException);
+/*     e = native_new_and_init(class_java_lang_ArrayStoreException); */
 }
 
 
@@ -1301,99 +1378,110 @@ java_objectheader *exceptions_new_classcastexception(java_objectheader *o)
 }
 
 
-/* exceptions_new_illegalargumentexception *************************************
+/* exceptions_throw_clonenotsupportedexception *********************************
 
-   Generates a java.lang.IllegalArgumentException for the VM system.
+   Generates and throws a java.lang.CloneNotSupportedException for the
+   VM.
 
 *******************************************************************************/
 
-java_objectheader *new_illegalargumentexception(void)
+void exceptions_throw_clonenotsupportedexception(void)
 {
-       java_objectheader *e;
+       exceptions_throw_utf(utf_java_lang_CloneNotSupportedException);
+}
 
-       e = native_new_and_init(class_java_lang_IllegalArgumentException);
 
-       if (!e)
-               return *exceptionptr;
+/* exceptions_throw_illegalaccessexception *************************************
 
-       return e;
+   Generates and throws a java.lang.IllegalAccessException for the VM.
+
+*******************************************************************************/
+
+void exceptions_throw_illegalaccessexception(classinfo *c)
+{
+       /* XXX handle argument */
+
+       exceptions_throw_utf(utf_java_lang_IllegalAccessException);
 }
 
 
 /* exceptions_throw_illegalargumentexception ***********************************
 
-   Generates a java.lang.IllegalArgumentException for the VM system
-   and throw it in the VM system.
+   Generates and throws a java.lang.IllegalArgumentException for the
+   VM.
 
 *******************************************************************************/
 
 void exceptions_throw_illegalargumentexception(void)
 {
-       *exceptionptr = new_illegalargumentexception();
+       exceptions_throw_utf(utf_java_lang_IllegalArgumentException);
 }
 
 
-/* exceptions_new_illegalmonitorstateexception *********************************
+/* exceptions_throw_illegalmonitorstateexception *******************************
 
-   Generates a java.lang.IllegalMonitorStateException for the VM
-   thread system.
+   Generates and throws a java.lang.IllegalMonitorStateException for
+   the VM.
 
 *******************************************************************************/
 
-java_objectheader *exceptions_new_illegalmonitorstateexception(void)
+void exceptions_throw_illegalmonitorstateexception(void)
 {
-       java_objectheader *e;
-
-       e = native_new_and_init(class_java_lang_IllegalMonitorStateException);
-
-       if (e == NULL)
-               return *exceptionptr;
-
-       return e;
+       exceptions_throw_utf(utf_java_lang_IllegalMonitorStateException);
 }
 
 
-/* exceptions_throw_illegalmonitorstateexception *******************************
+/* exceptions_throw_instantiationexception *************************************
 
-   Generates a java.lang.IllegalMonitorStateException for the VM
-   system and throw it in the VM system.
+   Generates and throws a java.lang.InstantiationException for the VM.
 
 *******************************************************************************/
 
-void exceptions_throw_illegalmonitorstateexception(void)
+void exceptions_throw_instantiationexception(classinfo *c)
 {
-       *exceptionptr = exceptions_new_illegalmonitorstateexception();
+       exceptions_throw_utf_utf(utf_java_lang_InstantiationException, c->name);
 }
 
 
-/* exceptions_new_negativearraysizeexception ***********************************
+/* exceptions_throw_interruptedexception ***************************************
 
-   Generates a java.lang.NegativeArraySizeException for the VM system.
+   Generates and throws a java.lang.InterruptedException for the VM.
 
 *******************************************************************************/
 
-java_objectheader *new_negativearraysizeexception(void)
+void exceptions_throw_interruptedexception(void)
 {
-       java_objectheader *e;
+       exceptions_throw_utf(utf_java_lang_InterruptedException);
+}
 
-       e = new_exception(string_java_lang_NegativeArraySizeException);
 
-       if (!e)
-               return *exceptionptr;
+/* exceptions_throw_invocationtargetexception **********************************
 
-       return e;
+   Generates and throws a java.lang.reflect.InvocationTargetException
+   for the VM.
+
+   IN:
+      cause......cause exception object
+
+*******************************************************************************/
+
+void exceptions_throw_invocationtargetexception(java_objectheader *cause)
+{
+       exceptions_throw_utf_throwable(utf_java_lang_reflect_InvocationTargetException,
+                                                                  cause);
 }
 
 
 /* exceptions_throw_negativearraysizeexception *********************************
 
-   Generates a java.lang.NegativeArraySizeException for the VM system.
+   Generates and throws a java.lang.NegativeArraySizeException for the
+   VM.
 
 *******************************************************************************/
 
 void exceptions_throw_negativearraysizeexception(void)
 {
-       *exceptionptr = new_negativearraysizeexception();
+       exceptions_throw_utf(utf_java_lang_NegativeArraySizeException);
 }
 
 
@@ -1405,14 +1493,11 @@ void exceptions_throw_negativearraysizeexception(void)
 
 java_objectheader *exceptions_new_nullpointerexception(void)
 {
-       java_objectheader *e;
-
-       e = native_new_and_init(class_java_lang_NullPointerException);
+       java_objectheader *o;
 
-       if (e == NULL)
-               return *exceptionptr;
+       o = exceptions_new_class(class_java_lang_NullPointerException);
 
-       return e;
+       return o;
 }
 
 
@@ -1425,40 +1510,99 @@ java_objectheader *exceptions_new_nullpointerexception(void)
 
 void exceptions_throw_nullpointerexception(void)
 {
-       *exceptionptr = exceptions_new_nullpointerexception();
+       exceptions_throw_class(class_java_lang_NullPointerException);
 }
 
 
-/* exceptions_new_stringindexoutofboundsexception ******************************
+/* exceptions_throw_stringindexoutofboundsexception ****************************
 
-   Generates a java.lang.StringIndexOutOfBoundsException for the VM
-   system.
+   Generates and throws a java.lang.StringIndexOutOfBoundsException
+   for the VM.
 
 *******************************************************************************/
 
-java_objectheader *exceptions_new_stringindexoutofboundsexception(void)
+void exceptions_throw_stringindexoutofboundsexception(void)
 {
-       java_objectheader *e;
+       exceptions_throw_utf(utf_java_lang_StringIndexOutOfBoundsException);
+}
 
-       e = new_exception(string_java_lang_StringIndexOutOfBoundsException);
 
-       if (e == NULL)
-               return *exceptionptr;
+/* exceptions_get_exception ****************************************************
 
-       return e;
+   Returns the current exception pointer of the current thread.
+
+*******************************************************************************/
+
+java_objectheader *exceptions_get_exception(void)
+{
+       /* return the exception */
+
+       return *exceptionptr;
 }
 
 
-/* exceptions_throw_stringindexoutofboundsexception ****************************
+/* exceptions_set_exception ****************************************************
 
-   Throws a java.lang.StringIndexOutOfBoundsException for the VM
-   system.
+   Sets the exception pointer of the current thread.
 
 *******************************************************************************/
 
-void exceptions_throw_stringindexoutofboundsexception(void)
+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
+   exception.
+
+*******************************************************************************/
+
+java_objectheader *exceptions_fillinstacktrace(void)
 {
-       *exceptionptr = exceptions_new_stringindexoutofboundsexception();
+       java_objectheader *e;
+       methodinfo        *m;
+
+       /* get exception */
+
+       e = *exceptionptr;
+       assert(e);
+
+       /* clear exception */
+
+       *exceptionptr = NULL;
+
+       /* resolve methodinfo pointer from exception object */
+
+       m = class_resolvemethod(e->vftbl->class,
+                                                       utf_fillInStackTrace,
+                                                       utf_void__java_lang_Throwable);
+
+       /* call function */
+
+       (void) vm_call_method(m, e);
+
+       /* return exception object */
+
+       return e;
 }
 
 
@@ -1492,6 +1636,80 @@ java_objectheader *exceptions_get_and_clear_exception(void)
 }
 
 
+/* 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...");
+       }
+
+       /* 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.
@@ -1525,6 +1743,15 @@ u1 *exceptions_handle_exception(java_objectheader *xptr, u1 *xpc, u1 *pv, u1 *sp
        java_objectheader     *o;
 #endif
 
+#ifdef __S390__
+       /* Addresses are 31 bit integers */
+#      define ADDR_MASK(x) (u1 *)((u4)(x) & 0x7FFFFFFF)
+#else
+#      define ADDR_MASK(x) (x)
+#endif
+
+       xpc = ADDR_MASK(xpc);
+
        /* get info from the method header */
 
        code                 = *((codeinfo **)            (pv + CodeinfoPointer));
@@ -1559,7 +1786,7 @@ u1 *exceptions_handle_exception(java_objectheader *xptr, u1 *xpc, u1 *pv, u1 *sp
 
                /* is the xpc is the current catch range */
 
-               if ((ex->startpc <= xpc) && (xpc < ex->endpc)) {
+               if ((ADDR_MASK(ex->startpc) <= xpc) && (xpc < ADDR_MASK(ex->endpc))) {
                        cr = ex->catchtype;
 
                        /* NULL catches everything */
@@ -1672,7 +1899,9 @@ u1 *exceptions_handle_exception(java_objectheader *xptr, u1 *xpc, u1 *pv, u1 *sp
 void exceptions_print_exception(java_objectheader *xptr)
 {
        java_lang_Throwable   *t;
+#if defined(ENABLE_JAVASE)
        java_lang_Throwable   *cause;
+#endif
        utf                   *u;
 
        t = (java_lang_Throwable *) xptr;
@@ -1682,13 +1911,15 @@ void exceptions_print_exception(java_objectheader *xptr)
                return;
        }
 
+#if defined(ENABLE_JAVASE)
        cause = t->cause;
+#endif
 
        /* print the root exception */
 
        utf_display_printable_ascii_classname(t->header.vftbl->class->name);
 
-       if (t->detailMessage) {
+       if (t->detailMessage != NULL) {
                u = javastring_toutf(t->detailMessage, false);
 
                printf(": ");
@@ -1697,6 +1928,7 @@ void exceptions_print_exception(java_objectheader *xptr)
 
        putc('\n', stdout);
 
+#if defined(ENABLE_JAVASE)
        /* print the cause if available */
 
        if ((cause != NULL) && (cause != t)) {
@@ -1712,6 +1944,98 @@ void exceptions_print_exception(java_objectheader *xptr)
 
                putc('\n', stdout);
        }
+#endif
+}
+
+
+/* exceptions_print_current_exception ******************************************
+
+   Prints the current pending exception, the detail message and the
+   cause, if available, with CACAO internal functions to stdout.
+
+*******************************************************************************/
+
+void exceptions_print_current_exception(void)
+{
+       java_objectheader *xptr;
+
+       xptr = *exceptionptr;
+
+       exceptions_print_exception(xptr);
+}
+
+
+/* exceptions_print_stacktrace *************************************************
+
+   Prints a pending exception with Throwable.printStackTrace().  If
+   there happens an exception during printStackTrace(), we print the
+   thrown exception and the original one.
+
+   NOTE: This function calls Java code.
+
+*******************************************************************************/
+
+void exceptions_print_stacktrace(void)
+{
+       java_objectheader *oxptr;
+       java_objectheader *xptr;
+       classinfo         *c;
+       methodinfo        *m;
+
+       /* get original exception */
+
+       oxptr = *exceptionptr;
+
+       if (oxptr == NULL)
+               vm_abort("exceptions_print_stacktrace: no exception thrown");
+
+       /* clear exception, because we are calling jit code again */
+
+       *exceptionptr = NULL;
+
+       c = oxptr->vftbl->class;
+
+       /* find the printStackTrace() method */
+
+       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");
+
+       /* print compatibility message */
+
+       fprintf(stderr, "Exception in thread \"main\" ");
+
+       /* print the stacktrace */
+
+       (void) vm_call_method(m, oxptr);
+
+       /* This normally means, we are EXTREMLY out of memory or
+          have a serious problem while printStackTrace. But may
+          be another exception, so print it. */
+
+       xptr = *exceptionptr;
+
+       if (xptr != NULL) {
+               fprintf(stderr, "Exception while printStackTrace(): ");
+
+               /* now print original exception */
+
+               exceptions_print_exception(xptr);
+               stacktrace_print_trace(xptr);
+
+               /* now print original exception */
+
+               fprintf(stderr, "Original exception was: ");
+               exceptions_print_exception(oxptr);
+               stacktrace_print_trace(oxptr);
+       }
+
+       fflush(stderr);
 }