* renamed CACAO_TYPECHECK to ENABLE_VERIFIER
[cacao.git] / src / vm / exceptions.c
index 65c9a9fbc21a9bad5d0e1d043cc355d51ad6c390..fe963e69072a28ce3d3cb08790197820bcbecd88 100644 (file)
@@ -1,9 +1,9 @@
-/* exceptions.c - exception related functions
+/* src/vm/exceptions.c - exception related functions
 
-   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
-   R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser,
-   M. Probst, S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck,
-   P. Tomsich, J. Wenninger
+   Copyright (C) 1996-2005 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
 
    This file is part of CACAO.
 
@@ -26,7 +26,9 @@
 
    Authors: Christian Thalinger
 
-   $Id: exceptions.c 1480 2004-11-11 14:37:01Z twisti $
+   Changes: Edwin Steiner
+
+   $Id: exceptions.c 3807 2005-11-26 21:51:11Z edwin $
 
 */
 
 #include <string.h>
 #include <stdarg.h>
 #include <stdlib.h>
-#include "asmpart.h"
-#include "global.h"
-#include "loader.h"
-#include "native.h"
-#include "tables.h"
-#include "jit/jit.h"
-#include "toolbox/logging.h"
-#include "toolbox/memory.h"
-#include "nat/java_lang_String.h"
-#include "nat/java_lang_Throwable.h"
-
-
-/* system exception classes required in cacao */
-
-classinfo *class_java_lang_Throwable;
-classinfo *class_java_lang_Exception;
-classinfo *class_java_lang_Error;
-classinfo *class_java_lang_OutOfMemoryError;
-
-
-/* exception/error super class */
-
-char *string_java_lang_Throwable =
-    "java/lang/Throwable";
-
-char *string_java_lang_VMThrowable =
-    "java/lang/VMThrowable";
-
-
-/* specify some exception strings for code generation */
-
-char *string_java_lang_ArithmeticException =
-    "java/lang/ArithmeticException";
-
-char *string_java_lang_ArithmeticException_message =
-    "/ by zero";
-
-char *string_java_lang_ArrayIndexOutOfBoundsException =
-    "java/lang/ArrayIndexOutOfBoundsException";
-
-char *string_java_lang_ArrayStoreException =
-    "java/lang/ArrayStoreException";
-
-char *string_java_lang_ClassCastException =
-    "java/lang/ClassCastException";
-
-char *string_java_lang_ClassNotFoundException =
-       "java/lang/ClassNotFoundException";
-
-char *string_java_lang_CloneNotSupportedException =
-    "java/lang/CloneNotSupportedException";
-
-char *string_java_lang_Exception =
-    "java/lang/Exception";
-
-char *string_java_lang_IllegalArgumentException =
-    "java/lang/IllegalArgumentException";
-
-char *string_java_lang_IllegalMonitorStateException =
-    "java/lang/IllegalMonitorStateException";
-
-char *string_java_lang_IndexOutOfBoundsException =
-    "java/lang/IndexOutOfBoundsException";
-
-char *string_java_lang_InterruptedException =
-    "java/lang/InterruptedException";
 
-char *string_java_lang_NegativeArraySizeException =
-    "java/lang/NegativeArraySizeException";
+#include "config.h"
 
-char *string_java_lang_NoSuchFieldException =
-       "java/lang/NoSuchFieldException";
-
-char *string_java_lang_NoSuchMethodException =
-       "java/lang/NoSuchMethodException";
-
-char *string_java_lang_NullPointerException =
-    "java/lang/NullPointerException";
-
-
-/* specify some error strings for code generation */
-
-char *string_java_lang_AbstractMethodError =
-    "java/lang/AbstractMethodError";
-
-char *string_java_lang_ClassCircularityError =
-    "java/lang/ClassCircularityError";
-
-char *string_java_lang_ClassFormatError =
-    "java/lang/ClassFormatError";
-
-char *string_java_lang_Error =
-    "java/lang/Error";
+#include "mm/memory.h"
+#include "native/native.h"
+#include "native/include/java_lang_String.h"
+#include "native/include/java_lang_Throwable.h"
+#include "toolbox/logging.h"
+#include "toolbox/util.h"
+#include "vm/class.h"
+#include "vm/exceptions.h"
+#include "vm/global.h"
+#include "vm/loader.h"
+#include "vm/options.h"
+#include "vm/stringlocal.h"
+#include "vm/tables.h"
+#include "vm/jit/asmpart.h"
+#include "vm/jit/jit.h"
+
+
+/* for raising exceptions from native methods *********************************/
+
+#if !defined(USE_THREADS) || !defined(NATIVE_THREADS)
+java_objectheader *_no_threads_exceptionptr = NULL;
+#endif
 
-char *string_java_lang_ExceptionInInitializerError =
-    "java/lang/ExceptionInInitializerError";
 
-char *string_java_lang_IncompatibleClassChangeError =
-    "java/lang/IncompatibleClassChangeError";
+/* init_system_exceptions ******************************************************
 
-char *string_java_lang_InternalError =
-    "java/lang/InternalError";
+   Load and link exceptions used in the system.
 
-char *string_java_lang_LinkageError =
-    "java/lang/LinkageError";
+*******************************************************************************/
 
-char *string_java_lang_NoClassDefFoundError =
-    "java/lang/NoClassDefFoundError";
+bool exceptions_init(void)
+{
+       /* java/lang/Throwable */
 
-char *string_java_lang_NoSuchFieldError =
-       "java/lang/NoSuchFieldError";
+       if (!(class_java_lang_Throwable =
+                 load_class_bootstrap(utf_java_lang_Throwable)) ||
+               !link_class(class_java_lang_Throwable))
+               return false;
 
-char *string_java_lang_NoSuchMethodError =
-       "java/lang/NoSuchMethodError";
 
-char *string_java_lang_OutOfMemoryError =
-    "java/lang/OutOfMemoryError";
+       /* java/lang/VMThrowable */
 
-char *string_java_lang_UnsupportedClassVersionError =
-    "java/lang/UnsupportedClassVersionError";
+       if (!(class_java_lang_VMThrowable =
+                 load_class_bootstrap(utf_java_lang_VMThrowable)) ||
+               !link_class(class_java_lang_VMThrowable))
+               return false;
 
-char *string_java_lang_VerifyError =
-    "java/lang/VerifyError";
 
-char *string_java_lang_VirtualMachineError =
-    "java/lang/VirtualMachineError";
+       /* java/lang/Error */
 
+       if (!(class_java_lang_Error = load_class_bootstrap(utf_java_lang_Error)) ||
+               !link_class(class_java_lang_Error))
+               return false;
 
-/* init_system_exceptions *****************************************************
+       /* java/lang/NoClassDefFoundError */
 
-   load, link and compile exceptions used in the system
+       if (!(class_java_lang_NoClassDefFoundError =
+                 load_class_bootstrap(utf_java_lang_NoClassDefFoundError)) ||
+               !link_class(class_java_lang_NoClassDefFoundError))
+               return false;
 
-*******************************************************************************/
+       /* java/lang/LinkageError */
 
-bool init_system_exceptions(void)
-{
-       /* java/lang/Throwable */
+       if (!(class_java_lang_LinkageError =
+                 load_class_bootstrap(utf_java_lang_LinkageError)) ||
+               !link_class(class_java_lang_LinkageError))
+               return false;
 
-       class_java_lang_Throwable =
-               class_new(utf_new_char(string_java_lang_Throwable));
+       /* java/lang/NoSuchMethodError */
 
-       if (!class_load(class_java_lang_Throwable))
+       if (!(class_java_lang_NoSuchMethodError =
+                 load_class_bootstrap(utf_java_lang_NoSuchMethodError)) ||
+               !link_class(class_java_lang_NoSuchMethodError))
                return false;
 
-       if (!class_link(class_java_lang_Throwable))
+       /* java/lang/OutOfMemoryError */
+
+       if (!(class_java_lang_OutOfMemoryError =
+                 load_class_bootstrap(utf_java_lang_OutOfMemoryError)) ||
+               !link_class(class_java_lang_OutOfMemoryError))
                return false;
 
 
        /* java/lang/Exception */
 
-       class_java_lang_Exception =
-               class_new(utf_new_char(string_java_lang_Exception));
-
-       if (!class_load(class_java_lang_Exception))
-               return false;
-
-       if (!class_link(class_java_lang_Exception))
+       if (!(class_java_lang_Exception =
+                 load_class_bootstrap(utf_java_lang_Exception)) ||
+               !link_class(class_java_lang_Exception))
                return false;
 
+       /* java/lang/ClassNotFoundException */
 
-       /* java/lang/Error */
-
-       class_java_lang_Error =
-               class_new(utf_new_char(string_java_lang_Error));
-
-       if (!class_load(class_java_lang_Error))
+       if (!(class_java_lang_ClassNotFoundException =
+                 load_class_bootstrap(utf_java_lang_ClassNotFoundException)) ||
+               !link_class(class_java_lang_ClassNotFoundException))
                return false;
 
-       if (!class_link(class_java_lang_Error))
+       /* 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 */
 
-       /* java/lang/OutOfMemoryError */
+       if (!(class_java_lang_IllegalMonitorStateException =
+                 load_class_bootstrap(utf_java_lang_IllegalMonitorStateException)) ||
+               !link_class(class_java_lang_IllegalMonitorStateException))
+               return false;
 
-       class_java_lang_OutOfMemoryError =
-               class_new(utf_new_char(string_java_lang_OutOfMemoryError));
+       /* java/lang/NullPointerException */
 
-       if (!class_load(class_java_lang_OutOfMemoryError))
+       if (!(class_java_lang_NullPointerException =
+                 load_class_bootstrap(utf_java_lang_NullPointerException)) ||
+               !link_class(class_java_lang_NullPointerException))
                return false;
 
-       if (!class_link(class_java_lang_OutOfMemoryError))
-               return false;
 
        return true;
 }
@@ -236,8 +177,8 @@ static void throw_exception_exit_intern(bool doexit)
                c = xptr->vftbl->class;
 
                pss = class_resolveclassmethod(c,
-                                                                          utf_new_char("printStackTrace"),
-                                                                          utf_new_char("()V"),
+                                                                          utf_printStackTrace,
+                                                                          utf_void__void,
                                                                           class_java_lang_Object,
                                                                           false);
 
@@ -245,10 +186,26 @@ static void throw_exception_exit_intern(bool doexit)
                if (pss) {
                        asm_calljavafunction(pss, xptr, NULL, NULL, NULL);
 
-                       /* this normally means, we are EXTREMLY out of memory, but may be
-                          any other exception */
+                       /* 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 (*exceptionptr) {
-                               utf_fprint_classname(stderr, c->name);
+                               java_lang_Throwable *t;
+
+                               t = (java_lang_Throwable *) *exceptionptr;
+
+                               fprintf(stderr, "Exception while printStackTrace(): ");
+                               utf_fprint_classname(stderr, t->header.vftbl->class->name);
+
+                               if (t->detailMessage) {
+                                       char *buf;
+
+                                       buf = javastring_tochar((java_objectheader *) t->detailMessage);
+                                       fprintf(stderr, ": %s", buf);
+                                       MFREE(buf, char, strlen(buf));
+                               }
+                                       
                                fprintf(stderr, "\n");
                        }
 
@@ -260,26 +217,26 @@ static void throw_exception_exit_intern(bool doexit)
                fflush(stderr);
 
                /* good bye! */
-               if (doexit) {
+
+               if (doexit)
                        exit(1);
-               }
        }
 }
 
 
-void throw_exception()
+void throw_exception(void)
 {
        throw_exception_exit_intern(false);
 }
 
 
-void throw_exception_exit()
+void throw_exception_exit(void)
 {
        throw_exception_exit_intern(true);
 }
 
 
-void throw_main_exception()
+void throw_main_exception(void)
 {
        fprintf(stderr, "Exception in thread \"main\" ");
        fflush(stderr);
@@ -288,7 +245,7 @@ void throw_main_exception()
 }
 
 
-void throw_main_exception_exit()
+void throw_main_exception_exit(void)
 {
        fprintf(stderr, "Exception in thread \"main\" ");
        fflush(stderr);
@@ -297,7 +254,7 @@ void throw_main_exception_exit()
 }
 
 
-void throw_cacao_exception_exit(char *exception, char *message, ...)
+void throw_cacao_exception_exit(const char *exception, const char *message, ...)
 {
        s4 i;
        char *tmp;
@@ -305,15 +262,14 @@ void throw_cacao_exception_exit(char *exception, char *message, ...)
        va_list ap;
 
        len = strlen(exception);
-       tmp = MNEW(char, len+1);
+       tmp = MNEW(char, len + 1);
        strncpy(tmp, exception, len);
-        tmp[len]='\0';
+       tmp[len] = '\0';
 
        /* convert to classname */
 
-       for (i = len - 1; i >= 0; i--) {
+       for (i = len - 1; i >= 0; i--)
                if (tmp[i] == '/') tmp[i] = '.';
-       }
 
        fprintf(stderr, "Exception in thread \"main\" %s", tmp);
 
@@ -323,7 +279,7 @@ void throw_cacao_exception_exit(char *exception, char *message, ...)
                fprintf(stderr, ": ");
 
                va_start(ap, message);
-               fprintf(stderr, message, ap);
+               vfprintf(stderr, message, ap);
                va_end(ap);
        }
 
@@ -331,69 +287,167 @@ void throw_cacao_exception_exit(char *exception, char *message, ...)
        fflush(stderr);
 
        /* good bye! */
+
        exit(1);
 }
 
 
-#if 1
-#define CREATENEW_EXCEPTION(ex) \
-    return ex;
-#else
-#define CREATENEW_EXCEPTION(ex) \
-       java_objectheader *newEx; \
-       java_objectheader *oldexception=*exceptionptr;\
-       *exceptionptr=0;\
-       newEx=ex;\
-       *exceptionptr=oldexception;\
-       return newEx;
-#endif
+/* exceptions_throw_outofmemory_exit *******************************************
 
-java_objectheader *new_exception(char *classname)
+   Just print an: java.lang.InternalError: Out of memory
+
+*******************************************************************************/
+
+void exceptions_throw_outofmemory_exit(void)
+{
+       throw_cacao_exception_exit(string_java_lang_InternalError,
+                                                          "Out of memory");
+}
+
+
+/* new_exception ***************************************************************
+
+   Creates an exception object with the given name and initalizes it.
+
+*******************************************************************************/
+
+java_objectheader *new_exception(const char *classname)
 {
-       classinfo *c = class_new(utf_new_char(classname));
+       java_objectheader *o;
+       classinfo         *c;
+
+       if (!(c = load_class_bootstrap(utf_new_char(classname))))
+               return *exceptionptr;
+
+       o = native_new_and_init(c);
+
+       if (!o)
+               return *exceptionptr;
 
-       CREATENEW_EXCEPTION(native_new_and_init(c));
+       return o;
 }
 
-java_objectheader *new_exception_message(char *classname, char *message)
+
+/* new_exception_message *******************************************************
+
+   Creates an exception object with the given name and initalizes it
+   with the given char message.
+
+*******************************************************************************/
+
+java_objectheader *new_exception_message(const char *classname,
+                                                                                const char *message)
 {
-       classinfo *c = class_new(utf_new_char(classname));
+       java_objectheader *o;
+       classinfo         *c;
+   
+       if (!(c = load_class_bootstrap(utf_new_char(classname))))
+               return *exceptionptr;
+
+       o = native_new_and_init_string(c, javastring_new_char(message));
+
+       if (!o)
+               return *exceptionptr;
 
-       CREATENEW_EXCEPTION(native_new_and_init_string(c, javastring_new_char(message)));
+       return o;
 }
 
 
-java_objectheader *new_exception_throwable(char *classname, java_lang_Throwable *throwable)
+/* new_exception_throwable *****************************************************
+
+   Creates an exception object with the given name and initalizes it
+   with the given java/lang/Throwable exception.
+
+*******************************************************************************/
+
+java_objectheader *new_exception_throwable(const char *classname,
+                                                                                  java_lang_Throwable *throwable)
 {
-       classinfo *c = class_new(utf_new_char(classname));
+       java_objectheader *o;
+       classinfo         *c;
+   
+       if (!(c = load_class_bootstrap(utf_new_char(classname))))
+               return *exceptionptr;
+
+       o = native_new_and_init_throwable(c, throwable);
 
-       CREATENEW_EXCEPTION(native_new_and_init_throwable(c, throwable));
+       if (!o)
+               return *exceptionptr;
+
+       return o;
 }
 
 
-java_objectheader *new_exception_utfmessage(char *classname, utf *message)
+/* new_exception_utfmessage ****************************************************
+
+   Creates an exception object with the given name and initalizes it
+   with the given utf message.
+
+*******************************************************************************/
+
+java_objectheader *new_exception_utfmessage(const char *classname, utf *message)
 {
-       classinfo *c = class_new(utf_new_char(classname));
+       java_objectheader *o;
+       classinfo         *c;
+   
+       if (!(c = load_class_bootstrap(utf_new_char(classname))))
+               return *exceptionptr;
+
+       o = native_new_and_init_string(c, javastring_new(message));
+
+       if (!o)
+               return *exceptionptr;
 
-       CREATENEW_EXCEPTION(native_new_and_init_string(c, javastring_new(message)));
+       return o;
 }
 
 
-java_objectheader *new_exception_javastring(char *classname, java_lang_String *message)
+/* new_exception_javastring ****************************************************
+
+   Creates an exception object with the given name and initalizes it
+   with the given java/lang/String message.
+
+*******************************************************************************/
+
+java_objectheader *new_exception_javastring(const char *classname,
+                                                                                       java_lang_String *message)
 {
-       classinfo *c = class_new(utf_new_char(classname));
+       java_objectheader *o;
+       classinfo         *c;
+   
+       if (!(c = load_class_bootstrap(utf_new_char(classname))))
+               return *exceptionptr;
 
-       CREATENEW_EXCEPTION(native_new_and_init_string(c, message));
+       o = native_new_and_init_string(c, message);
+
+       if (!o)
+               return *exceptionptr;
+
+       return o;
 }
 
 
-java_objectheader *new_exception_int(char *classname, s4 i)
+/* new_exception_int ***********************************************************
+
+   Creates an exception object with the given name and initalizes it
+   with the given int value.
+
+*******************************************************************************/
+
+java_objectheader *new_exception_int(const char *classname, s4 i)
 {
-       classinfo *c;
+       java_objectheader *o;
+       classinfo         *c;
+   
+       if (!(c = load_class_bootstrap(utf_new_char(classname))))
+               return *exceptionptr;
 
-       c = class_new(utf_new_char(classname));
+       o = native_new_and_init_int(c, i);
 
-       CREATENEW_EXCEPTION(native_new_and_init_int(c, i));
+       if (!o)
+               return *exceptionptr;
+
+       return o;
 }
 
 
@@ -403,21 +457,257 @@ java_objectheader *new_exception_int(char *classname, s4 i)
 
 *******************************************************************************/
 
-java_objectheader *new_classformaterror(classinfo *c, char *message, ...)
+java_objectheader *new_classformaterror(classinfo *c, const char *message, ...)
 {
-       char msg[MAXLOGTEXT];
-       va_list ap;
+       java_objectheader *o;
+       char              *msg;
+       s4                 msglen;
+       va_list            ap;
 
-       utf_sprint_classname(msg, c->name);
-       sprintf(msg + strlen(msg), " (");
+       /* calculate message length */
+
+       msglen = 0;
+
+       if (c)
+               msglen += utf_strlen(c->name) + strlen(" (");
+
+       va_start(ap, message);
+       msglen += get_variable_message_length(message, ap);
+       va_end(ap);
+
+       if (c)
+               msglen += strlen(")");
+
+       msglen += strlen("0");
+
+       /* allocate a buffer */
+
+       msg = MNEW(char, msglen);
+
+       /* print message into allocated buffer */
+
+       if (c) {
+               utf_sprint_classname(msg, c->name);
+               strcat(msg, " (");
+       }
 
        va_start(ap, message);
        vsprintf(msg + strlen(msg), message, ap);
        va_end(ap);
 
-       sprintf(msg + strlen(msg), ")");
+       if (c)
+               strcat(msg, ")");
+
+       o = new_exception_message(string_java_lang_ClassFormatError, msg);
+
+       MFREE(msg, char, msglen);
+
+       return o;
+}
+
+
+/* new_classnotfoundexception **************************************************
+
+   Generates a java.lang.ClassNotFoundException for the classloader.
+
+*******************************************************************************/
+
+java_objectheader *new_classnotfoundexception(utf *name)
+{
+       java_objectheader *o;
+
+       o = native_new_and_init_string(class_java_lang_ClassNotFoundException,
+                                                                  javastring_new(name));
+
+       if (!o)
+               return *exceptionptr;
 
-       return new_exception_message(string_java_lang_ClassFormatError, msg);
+       return o;
+}
+
+
+/* new_noclassdeffounderror ****************************************************
+
+   Generates a java.lang.NoClassDefFoundError
+
+*******************************************************************************/
+
+java_objectheader *new_noclassdeffounderror(utf *name)
+{
+       java_objectheader *o;
+
+       o = native_new_and_init_string(class_java_lang_NoClassDefFoundError,
+                                                                  javastring_new(name));
+
+       if (!o)
+               return *exceptionptr;
+
+       return o;
+}
+
+
+/* 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;
+
+       /* 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 */
+
+               xptr =
+                       new_exception_javastring(string_java_lang_NoClassDefFoundError,
+                                       ((java_lang_Throwable *) cause)->detailMessage);
+
+               /* we had an exception while creating the error */
+
+               if (*exceptionptr)
+                       return;
+
+               /* set new exception */
+
+               *exceptionptr = xptr;
+       }
+}
+
+
+/* new_internalerror ***********************************************************
+
+   Generates a java.lang.InternalError for the VM.
+
+*******************************************************************************/
+
+java_objectheader *new_internalerror(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);
+
+       /* allocate memory */
+
+       msg = MNEW(char, msglen);
+
+       /* generate message */
+
+       va_start(ap, message);
+       vsprintf(msg, message, ap);
+       va_end(ap);
+
+       /* create exception object */
+
+       o = new_exception_message(string_java_lang_InternalError, msg);
+
+       /* free memory */
+
+       MFREE(msg, char, msglen);
+
+       return o;
+}
+
+
+/* exceptions_new_linkageerror *************************************************
+
+   Generates a java.lang.LinkageError with an error message.
+   If c != NULL, the name of c is appended to the error message.
+
+*******************************************************************************/
+
+java_objectheader *exceptions_new_linkageerror(const char *message,
+                                                                                          classinfo *c)
+{
+       java_objectheader *o;
+       char              *msg;
+       s4                 msglen;
+
+       /* calculate exception message length */
+
+       msglen = strlen(message) + 1;
+       if (c) {
+               msglen += utf_strlen(c->name);
+       }
+               
+       /* allocate memory */
+
+       msg = MNEW(char, msglen);
+
+       /* generate message */
+
+       strcpy(msg,message);
+       if (c) {
+               utf_strcat(msg, c->name);
+       }
+
+       o = native_new_and_init_string(class_java_lang_LinkageError,
+                                                                  javastring_new_char(msg));
+
+       /* free memory */
+
+       MFREE(msg, char, msglen);
+
+       return o;
+}
+
+
+/* exceptions_new_nosuchmethoderror ********************************************
+
+   Generates a java.lang.NoSuchMethodError with an error message.
+
+*******************************************************************************/
+
+java_objectheader *exceptions_new_nosuchmethoderror(classinfo *c,
+                                                                                                       utf *name, utf *desc)
+{
+       java_objectheader *o;
+       char              *msg;
+       s4                 msglen;
+
+       /* calculate exception message length */
+
+       msglen = utf_strlen(c->name) + strlen(".") + utf_strlen(name) +
+               utf_strlen(desc) + strlen("0");
+
+       /* allocate memory */
+
+       msg = MNEW(char, msglen);
+
+       /* generate message */
+
+       utf_sprint(msg, c->name);
+       strcat(msg, ".");
+       utf_strcat(msg, name);
+       utf_strcat(msg, desc);
+
+       o = native_new_and_init_string(class_java_lang_NoSuchMethodError,
+                                                                  javastring_new_char(msg));
+
+       /* free memory */
+
+       MFREE(msg, char, msglen);
+
+       return o;
 }
 
 
@@ -427,22 +717,46 @@ java_objectheader *new_classformaterror(classinfo *c, char *message, ...)
 
 *******************************************************************************/
 
-java_objectheader *new_unsupportedclassversionerror(classinfo *c, char *message, ...)
+java_objectheader *new_unsupportedclassversionerror(classinfo *c, const char *message, ...)
 {
-       char msg[MAXLOGTEXT];
-       va_list ap;
+       java_objectheader *o;
+       va_list            ap;
+       char              *msg;
+    s4                 msglen;
+
+       /* calculate exception message length */
+
+       msglen = utf_strlen(c->name) + strlen(" (") + strlen(")") + strlen("0");
+
+       va_start(ap, message);
+       msglen += get_variable_message_length(message, ap);
+       va_end(ap);
+
+       /* allocate memory */
+
+       msg = MNEW(char, msglen);
+
+       /* generate message */
 
        utf_sprint_classname(msg, c->name);
-       sprintf(msg + strlen(msg), " (");
+       strcat(msg, " (");
 
        va_start(ap, message);
        vsprintf(msg + strlen(msg), message, ap);
        va_end(ap);
 
-       sprintf(msg + strlen(msg), ")");
+       strcat(msg, ")");
 
-       return new_exception_message(string_java_lang_UnsupportedClassVersionError,
-                                                                msg);
+       /* create exception object */
+
+       o = new_exception_message(string_java_lang_UnsupportedClassVersionError,
+                                                         msg);
+
+       /* free memory */
+
+       MFREE(msg, char, msglen);
+
+       return o;
 }
 
 
@@ -452,30 +766,56 @@ java_objectheader *new_unsupportedclassversionerror(classinfo *c, char *message,
 
 *******************************************************************************/
 
-java_objectheader *new_verifyerror(methodinfo *m, char *message)
+java_objectheader *new_verifyerror(methodinfo *m, const char *message, ...)
 {
        java_objectheader *o;
-       char *msg;
-       s4 len;
+       va_list            ap;
+       char              *msg;
+       s4                 msglen;
 
-       len = 8 + utf_strlen(m->class->name) +
-               10 + utf_strlen(m->name) +
-               13 + utf_strlen(m->descriptor) +
-               2 + strlen(message) + 1;
-               
-       msg = MNEW(char, len);
+       useinlining = false; /* at least until sure inlining works with exceptions*/
+
+       /* calculate exception message length */
+
+       msglen = 0;
+
+       if (m)
+               msglen = strlen("(class: ") + utf_strlen(m->class->name) +
+                       strlen(", method: ") + utf_strlen(m->name) +
+                       strlen(" signature: ") + utf_strlen(m->descriptor) +
+                       strlen(") ") + strlen("0");
+
+       va_start(ap, message);
+       msglen += get_variable_message_length(message, ap);
+       va_end(ap);
+
+       /* allocate memory */
+
+       msg = MNEW(char, msglen);
+
+       /* generate message */
 
-       sprintf(msg, "(class: ");
-       utf_sprint(msg + strlen(msg), m->class->name);
-       sprintf(msg + strlen(msg), ", method: ");
-       utf_sprint(msg + strlen(msg), m->name);
-       sprintf(msg + strlen(msg), ", signature: ");
-       utf_sprint(msg + strlen(msg), m->descriptor);
-       sprintf(msg + strlen(msg), ") %s", message);
+       if (m) {
+               strcpy(msg, "(class: ");
+               utf_strcat(msg, m->class->name);
+               strcat(msg, ", method: ");
+               utf_strcat(msg, m->name);
+               strcat(msg, " signature: ");
+               utf_strcat(msg, m->descriptor);
+               strcat(msg, ") ");
+       }
+
+       va_start(ap, message);
+       vsprintf(msg + strlen(msg), message, ap);
+       va_end(ap);
+
+       /* create exception object */
 
        o = new_exception_message(string_java_lang_VerifyError, msg);
 
-       MFREE(msg, u1, len);
+       /* free memory */
+
+       MFREE(msg, char, msglen);
 
        return o;
 }
@@ -483,11 +823,11 @@ java_objectheader *new_verifyerror(methodinfo *m, char *message)
 
 /* new_arithmeticexception *****************************************************
 
-   generates a java.lang.ArithmeticException for the jit compiler
+   Generates a java.lang.ArithmeticException for the jit compiler.
 
 *******************************************************************************/
 
-java_objectheader *new_arithmeticexception()
+java_objectheader *new_arithmeticexception(void)
 {
        java_objectheader *e;
 
@@ -503,7 +843,8 @@ java_objectheader *new_arithmeticexception()
 
 /* new_arrayindexoutofboundsexception ******************************************
 
-   generates a java.lang.ArrayIndexOutOfBoundsException for the jit compiler
+   Generates a java.lang.ArrayIndexOutOfBoundsException for the JIT
+   compiler.
 
 *******************************************************************************/
 
@@ -525,7 +866,7 @@ java_objectheader *new_arrayindexoutofboundsexception(s4 index)
                return *exceptionptr;
 
        s = (java_lang_String *) asm_calljavafunction(m,
-                                                                                                 (void *) index,
+                                                                                                 (void *) (ptrint) index,
                                                                                                  NULL,
                                                                                                  NULL,
                                                                                                  NULL);
@@ -549,11 +890,12 @@ java_objectheader *new_arrayindexoutofboundsexception(s4 index)
 
 *******************************************************************************/
 
-java_objectheader *new_arraystoreexception()
+java_objectheader *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;
@@ -568,7 +910,7 @@ java_objectheader *new_arraystoreexception()
 
 *******************************************************************************/
 
-java_objectheader *new_classcastexception()
+java_objectheader *new_classcastexception(void)
 {
        java_objectheader *e;
 
@@ -581,13 +923,48 @@ java_objectheader *new_classcastexception()
 }
 
 
+/* new_illegalargumentexception ************************************************
+
+   Generates a java.lang.IllegalArgumentException for the VM system.
+
+*******************************************************************************/
+
+java_objectheader *new_illegalargumentexception(void)
+{
+       java_objectheader *e;
+
+       if (!(e = native_new_and_init(class_java_lang_IllegalArgumentException)))
+               return *exceptionptr;
+
+       return e;
+}
+
+
+/* new_illegalmonitorstateexception ********************************************
+
+   Generates a java.lang.IllegalMonitorStateException for the VM
+   thread system.
+
+*******************************************************************************/
+
+java_objectheader *new_illegalmonitorstateexception(void)
+{
+       java_objectheader *e;
+
+       if (!(e = native_new_and_init(class_java_lang_IllegalMonitorStateException)))
+               return *exceptionptr;
+
+       return e;
+}
+
+
 /* new_negativearraysizeexception **********************************************
 
    generates a java.lang.NegativeArraySizeException for the jit compiler
 
 *******************************************************************************/
 
-java_objectheader *new_negativearraysizeexception()
+java_objectheader *new_negativearraysizeexception(void)
 {
        java_objectheader *e;
 
@@ -606,11 +983,11 @@ java_objectheader *new_negativearraysizeexception()
 
 *******************************************************************************/
 
-java_objectheader *new_nullpointerexception()
+java_objectheader *new_nullpointerexception(void)
 {
        java_objectheader *e;
 
-       e = new_exception(string_java_lang_NullPointerException);
+       e = native_new_and_init(class_java_lang_NullPointerException);
 
        if (!e)
                return *exceptionptr;
@@ -619,6 +996,53 @@ java_objectheader *new_nullpointerexception()
 }
 
 
+/* exceptions_print_exception **************************************************
+
+   Prints an exception, the detail message and the cause, if
+   available, with CACAO internal functions to stdout.
+
+*******************************************************************************/
+
+void exceptions_print_exception(java_objectheader *xptr)
+{
+       java_lang_Throwable   *t;
+       java_lang_Throwable   *cause;
+       utf                   *u;
+
+       t = (java_lang_Throwable *) xptr;
+       cause = t->cause;
+
+       /* print the root exception */
+
+       utf_display_classname(t->header.vftbl->class->name);
+
+       if (t->detailMessage) {
+               u = javastring_toutf(t->detailMessage, false);
+
+               printf(": ");
+               utf_display(u);
+       }
+
+       putc('\n', stdout);
+
+       /* print the cause if available */
+
+       if (cause && (cause != t)) {
+               printf("Caused by: ");
+               utf_display_classname(cause->header.vftbl->class->name);
+
+               if (cause->detailMessage) {
+                       u = javastring_toutf(cause->detailMessage, false);
+
+                       printf(": ");
+                       utf_display(u);
+               }
+
+               putc('\n', stdout);
+       }
+}
+
+
 /*
  * These are local overrides for various environment variables in Emacs.
  * Please do not remove this and leave it at the end of the file, where