-/* 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.
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;
}
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);
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");
}
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);
}
-void throw_main_exception_exit()
+void throw_main_exception_exit(void)
{
fprintf(stderr, "Exception in thread \"main\" ");
fflush(stderr);
}
-void throw_cacao_exception_exit(char *exception, char *message, ...)
+void throw_cacao_exception_exit(const char *exception, const char *message, ...)
{
s4 i;
char *tmp;
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);
fprintf(stderr, ": ");
va_start(ap, message);
- fprintf(stderr, message, ap);
+ vfprintf(stderr, message, ap);
va_end(ap);
}
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;
}
*******************************************************************************/
-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;
}
*******************************************************************************/
-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;
}
*******************************************************************************/
-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;
}
/* 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;
/* new_arrayindexoutofboundsexception ******************************************
- generates a java.lang.ArrayIndexOutOfBoundsException for the jit compiler
+ Generates a java.lang.ArrayIndexOutOfBoundsException for the JIT
+ compiler.
*******************************************************************************/
return *exceptionptr;
s = (java_lang_String *) asm_calljavafunction(m,
- (void *) index,
+ (void *) (ptrint) index,
NULL,
NULL,
NULL);
*******************************************************************************/
-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;
*******************************************************************************/
-java_objectheader *new_classcastexception()
+java_objectheader *new_classcastexception(void)
{
java_objectheader *e;
}
+/* 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;
*******************************************************************************/
-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;
}
+/* 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