Authors: Christian Thalinger
- Changes:
+ Changes: Edwin Steiner
- $Id: exceptions.c 2490 2005-05-20 23:05:49Z twisti $
+ $Id: exceptions.c 3807 2005-11-26 21:51:11Z edwin $
*/
#include "vm/jit/jit.h"
-/* for raising exceptions from native methods */
+/* for raising exceptions from native methods *********************************/
#if !defined(USE_THREADS) || !defined(NATIVE_THREADS)
-java_objectheader* _exceptionptr = NULL;
-u1 _dontfillinexceptionstacktrace = false;
+java_objectheader *_no_threads_exceptionptr = NULL;
#endif
{
/* java/lang/Throwable */
- if (!load_class_bootstrap(utf_java_lang_Throwable,
- &class_java_lang_Throwable) ||
+ if (!(class_java_lang_Throwable =
+ load_class_bootstrap(utf_java_lang_Throwable)) ||
!link_class(class_java_lang_Throwable))
return false;
/* java/lang/VMThrowable */
- if (!load_class_bootstrap(utf_java_lang_VMThrowable,
- &class_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 (!load_class_bootstrap(utf_java_lang_Error, &class_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/NoClassDefFoundError */
- /* java/lang/Exception */
-
- if (!load_class_bootstrap(utf_java_lang_Exception,
- &class_java_lang_Exception) ||
- !link_class(class_java_lang_Exception))
+ if (!(class_java_lang_NoClassDefFoundError =
+ load_class_bootstrap(utf_java_lang_NoClassDefFoundError)) ||
+ !link_class(class_java_lang_NoClassDefFoundError))
return false;
+ /* java/lang/LinkageError */
- /* java/lang/NoClassDefFoundError */
-
- if (!load_class_bootstrap(utf_java_lang_NoClassDefFoundError,
- &class_java_lang_NoClassDefFoundError) ||
- !link_class(class_java_lang_NoClassDefFoundError))
+ if (!(class_java_lang_LinkageError =
+ load_class_bootstrap(utf_java_lang_LinkageError)) ||
+ !link_class(class_java_lang_LinkageError))
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 (!load_class_bootstrap(utf_java_lang_OutOfMemoryError,
- &class_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 */
+
+ if (!(class_java_lang_Exception =
+ load_class_bootstrap(utf_java_lang_Exception)) ||
+ !link_class(class_java_lang_Exception))
+ return false;
+
/* java/lang/ClassNotFoundException */
- if (!load_class_bootstrap(utf_java_lang_ClassNotFoundException,
- &class_java_lang_ClassNotFoundException) ||
+ if (!(class_java_lang_ClassNotFoundException =
+ load_class_bootstrap(utf_java_lang_ClassNotFoundException)) ||
!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 =
+ load_class_bootstrap(utf_java_lang_NullPointerException)) ||
+ !link_class(class_java_lang_NullPointerException))
+ return false;
+
+
return true;
}
/* exception, so print it. */
if (*exceptionptr) {
+ java_lang_Throwable *t;
+
+ t = (java_lang_Throwable *) *exceptionptr;
+
fprintf(stderr, "Exception while printStackTrace(): ");
- utf_fprint_classname(stderr, c->name);
+ 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");
}
}
+/* exceptions_throw_outofmemory_exit *******************************************
+
+ 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;
-
- if (!load_class_bootstrap(utf_new_char(classname), &c))
+ java_objectheader *o;
+ classinfo *c;
+
+ if (!(c = load_class_bootstrap(utf_new_char(classname))))
return *exceptionptr;
- return native_new_and_init(c);
+ o = native_new_and_init(c);
+
+ if (!o)
+ return *exceptionptr;
+
+ return o;
}
-java_objectheader *new_exception_message(const char *classname, const 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;
+ java_objectheader *o;
+ classinfo *c;
- if (!load_class_bootstrap(utf_new_char(classname), &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;
- return native_new_and_init_string(c, javastring_new_char(message));
+ return o;
}
-java_objectheader *new_exception_throwable(const 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;
+ java_objectheader *o;
+ classinfo *c;
- if (!load_class_bootstrap(utf_new_char(classname), &c))
+ if (!(c = load_class_bootstrap(utf_new_char(classname))))
return *exceptionptr;
+ o = native_new_and_init_throwable(c, throwable);
- return native_new_and_init_throwable(c, throwable);
+ if (!o)
+ return *exceptionptr;
+
+ return o;
}
+/* 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;
+ java_objectheader *o;
+ classinfo *c;
- if (!load_class_bootstrap(utf_new_char(classname), &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;
- return native_new_and_init_string(c, javastring_new(message));
+ return o;
}
-java_objectheader *new_exception_javastring(const 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;
+ java_objectheader *o;
+ classinfo *c;
- if (!load_class_bootstrap(utf_new_char(classname), &c))
+ if (!(c = load_class_bootstrap(utf_new_char(classname))))
return *exceptionptr;
+ o = native_new_and_init_string(c, message);
+
+ if (!o)
+ return *exceptionptr;
- return native_new_and_init_string(c, message);
+ return o;
}
+/* 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 (!load_class_bootstrap(utf_new_char(classname), &c))
+ if (!(c = load_class_bootstrap(utf_new_char(classname))))
+ return *exceptionptr;
+
+ o = native_new_and_init_int(c, i);
+
+ if (!o)
return *exceptionptr;
- return native_new_and_init_int(c, i);
+ return o;
}
/* calculate message length */
+ msglen = 0;
+
if (c)
- msglen = utf_strlen(c->name) + strlen(" (");
+ msglen += utf_strlen(c->name) + strlen(" (");
va_start(ap, message);
msglen += get_variable_message_length(message, ap);
}
+/* 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 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.
}
+/* 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;
+}
+
+
/* new_unsupportedclassversionerror ********************************************
generates a java.lang.UnsupportedClassVersionError for the classloader
/* calculate exception message length */
- msglen = strlen("(class: ") + utf_strlen(m->class->name) +
- strlen(", method: ") + utf_strlen(m->name) +
- strlen(" signature: ") + utf_strlen(m->descriptor) +
- strlen(") ") + strlen("0");
+ 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);
/* generate message */
- 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, ") ");
+ 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);
java_objectheader *e;
e = new_exception(string_java_lang_ArrayStoreException);
+/* e = native_new_and_init(class_java_lang_ArrayStoreException); */
if (!e)
return *exceptionptr;
}
+/* 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 *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