Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
- $Id: exceptions.c 7305 2007-02-09 11:08:14Z twisti $
-
*/
#include <string.h>
#include <stdarg.h>
#include <stdlib.h>
+#include <unistd.h>
+#include <sys/mman.h>
#include "vm/types.h"
+#include "md-abi.h"
+
#include "mm/memory.h"
#include "native/jni.h"
+#include "native/llni.h"
#include "native/native.h"
+
#include "native/include/java_lang_String.h"
#include "native/include/java_lang_Throwable.h"
-#if defined(ENABLE_THREADS)
-# include "threads/native/threads.h"
-#else
-# include "threads/none/threads.h"
-#endif
+#include "threads/lock-common.h"
+#include "threads/threads-common.h"
-#include "toolbox/logging.h"
#include "toolbox/util.h"
#include "vm/builtin.h"
#include "vm/jit/asmpart.h"
#include "vm/jit/jit.h"
#include "vm/jit/methodheader.h"
+#include "vm/jit/patcher-common.h"
+#include "vm/jit/stacktrace.h"
#include "vmcore/class.h"
#include "vmcore/loader.h"
+#include "vmcore/method.h"
#include "vmcore/options.h"
+#if defined(ENABLE_VMLOG)
+#include <vmlog_cacao.h>
+#endif
+
/* for raising exceptions from native methods *********************************/
#if !defined(ENABLE_THREADS)
-java_objectheader *_no_threads_exceptionptr = NULL;
+java_object_t *_no_threads_exceptionptr = NULL;
#endif
bool exceptions_init(void)
{
+#if !(defined(__ARM__) && defined(__LINUX__))
+ /* On arm-linux the first memory page can't be mmap'ed, as it
+ contains the exception vectors. */
+
+ int pagesize;
+
+ /* mmap a memory page at address 0x0, so our hardware-exceptions
+ work. */
+
+ pagesize = getpagesize();
+
+ (void) memory_mmap_anon(NULL, pagesize, PROT_NONE, MAP_PRIVATE | MAP_FIXED);
+#endif
+
+ /* check if we get into trouble with our hardware-exceptions */
+
+ if (OFFSET(java_bytearray_t, data) <= EXCEPTION_HARDWARE_LARGEST)
+ vm_abort("signal_init: array-data offset is less or equal the maximum hardware-exception displacement: %d <= %d", OFFSET(java_bytearray_t, data), EXCEPTION_HARDWARE_LARGEST);
+
/* java/lang/Throwable */
if (!(class_java_lang_Throwable =
}
-static void throw_exception_exit_intern(bool doexit)
-{
- java_objectheader *xptr;
- classinfo *c;
- methodinfo *pss;
-
- xptr = *exceptionptr;
-
- if (xptr) {
- /* clear exception, because we are calling jit code again */
- *exceptionptr = NULL;
-
- c = xptr->vftbl->class;
-
- pss = class_resolveclassmethod(c,
- utf_printStackTrace,
- utf_void__void,
- class_java_lang_Object,
- false);
-
- /* print the stacktrace */
-
- if (pss) {
- (void) vm_call_method(pss, xptr);
-
- /* 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) {
- java_lang_Throwable *t;
-
- t = (java_lang_Throwable *) *exceptionptr;
+/* exceptions_get_exception ****************************************************
- fprintf(stderr, "Exception while printStackTrace(): ");
- utf_fprint_printable_ascii_classname(stderr, t->header.vftbl->class->name);
+ Returns the current exception pointer of the current thread.
- if (t->detailMessage) {
- char *buf;
+*******************************************************************************/
- buf = javastring_tochar((java_objectheader *) t->detailMessage);
- fprintf(stderr, ": %s", buf);
- MFREE(buf, char, strlen(buf));
- }
-
- fprintf(stderr, "\n");
- }
+java_handle_t *exceptions_get_exception(void)
+{
+ /* return the exception */
- } else {
- utf_fprint_printable_ascii_classname(stderr, c->name);
- fprintf(stderr, ": printStackTrace()V not found!\n");
- }
+ return *exceptionptr;
+}
- fflush(stderr);
- /* good bye! */
+/* exceptions_set_exception ****************************************************
- if (doexit)
- exit(1);
- }
-}
+ Sets the exception pointer of the current thread.
+*******************************************************************************/
-void throw_exception(void)
+void exceptions_set_exception(java_handle_t *o)
{
- throw_exception_exit_intern(false);
-}
-
+ /* set the exception */
-void throw_exception_exit(void)
-{
- throw_exception_exit_intern(true);
+ *exceptionptr = o;
}
-void throw_main_exception(void)
-{
- fprintf(stderr, "Exception in thread \"main\" ");
- fflush(stderr);
+/* exceptions_clear_exception **************************************************
- throw_exception_exit_intern(false);
-}
+ Clears the current exception pointer of the current thread.
+*******************************************************************************/
-void throw_main_exception_exit(void)
+void exceptions_clear_exception(void)
{
- fprintf(stderr, "Exception in thread \"main\" ");
- fflush(stderr);
-
- throw_exception_exit_intern(true);
+ exceptions_set_exception(NULL);
}
-void throw_cacao_exception_exit(const char *exception, const char *message, ...)
-{
- s4 i;
- char *tmp;
- s4 len;
- va_list ap;
-
- len = strlen(exception);
- tmp = MNEW(char, len + 1);
- strncpy(tmp, exception, len);
- tmp[len] = '\0';
+/* exceptions_get_and_clear_exception ******************************************
- /* convert to classname */
+ Gets the exception pointer of the current thread and clears it.
+ This function may return NULL.
- for (i = len - 1; i >= 0; i--)
- if (tmp[i] == '/') tmp[i] = '.';
+*******************************************************************************/
- fprintf(stderr, "Exception in thread \"main\" %s", tmp);
+java_handle_t *exceptions_get_and_clear_exception(void)
+{
+ java_handle_t *o;
- MFREE(tmp, char, len);
+ /* get the exception */
- if (strlen(message) > 0) {
- fprintf(stderr, ": ");
+ o = exceptions_get_exception();
- va_start(ap, message);
- vfprintf(stderr, message, ap);
- va_end(ap);
- }
+ /* and clear the exception */
- fprintf(stderr, "\n");
- fflush(stderr);
+ exceptions_clear_exception();
- /* good bye! */
+ /* return the exception */
- exit(1);
+ return o;
}
*******************************************************************************/
-static java_objectheader *exceptions_new_class(classinfo *c)
+static java_handle_t *exceptions_new_class(classinfo *c)
{
- java_objectheader *o;
+ java_handle_t *o;
o = native_new_and_init(c);
if (o == NULL)
- return *exceptionptr;
+ return exceptions_get_exception();
return o;
}
*******************************************************************************/
-static java_objectheader *exceptions_new_utf(utf *classname)
+static java_handle_t *exceptions_new_utf(utf *classname)
{
- classinfo *c;
- java_objectheader *o;
+ classinfo *c;
+ java_handle_t *o;
c = load_class_bootstrap(classname);
if (c == NULL)
- return *exceptionptr;
+ return exceptions_get_exception();
o = exceptions_new_class(c);
static void exceptions_throw_class(classinfo *c)
{
- java_objectheader *o;
+ java_handle_t *o;
o = exceptions_new_class(c);
if (o == NULL)
return;
- *exceptionptr = o;
+ exceptions_set_exception(o);
}
*******************************************************************************/
static void exceptions_throw_utf_throwable(utf *classname,
- java_objectheader *cause)
+ java_handle_t *cause)
{
- java_objectheader *o;
- classinfo *c;
-
+ classinfo *c;
+ java_handle_t *o;
+ methodinfo *m;
+ java_lang_Throwable *object;
+
+ object = (java_lang_Throwable *) cause;
+
c = load_class_bootstrap(classname);
if (c == NULL)
return;
- o = native_new_and_init_throwable(c, cause);
+ /* create object */
+ o = builtin_new(c);
+
if (o == NULL)
return;
- *exceptionptr = o;
+ /* call initializer */
+
+ m = class_resolveclassmethod(c,
+ utf_init,
+ utf_java_lang_Throwable__void,
+ NULL,
+ true);
+
+ if (m == NULL)
+ return;
+
+ (void) vm_call_method(m, o, cause);
+
+ exceptions_set_exception(o);
+}
+
+
+/* exceptions_throw_utf_exception **********************************************
+
+ Creates an exception object with the given name and initalizes it
+ with the given java/lang/Exception exception.
+
+ IN:
+ classname....class name in UTF-8
+ exception....the given Exception
+
+*******************************************************************************/
+
+static void exceptions_throw_utf_exception(utf *classname,
+ java_handle_t *exception)
+{
+ classinfo *c;
+ java_handle_t *o;
+ methodinfo *m;
+
+ c = load_class_bootstrap(classname);
+
+ if (c == NULL)
+ return;
+
+ /* create object */
+
+ o = builtin_new(c);
+
+ if (o == NULL)
+ return;
+
+ /* call initializer */
+
+ m = class_resolveclassmethod(c,
+ utf_init,
+ utf_java_lang_Exception__V,
+ NULL,
+ true);
+
+ if (m == NULL)
+ return;
+
+ (void) vm_call_method(m, o, exception);
+
+ exceptions_set_exception(o);
+}
+
+
+/* exceptions_throw_utf_cause **************************************************
+
+ Creates an exception object with the given name and initalizes it
+ with the given java/lang/Throwable exception with initCause.
+
+ IN:
+ classname....class name in UTF-8
+ cause........the given Throwable
+
+*******************************************************************************/
+
+static void exceptions_throw_utf_cause(utf *classname, java_handle_t *cause)
+{
+ classinfo *c;
+ java_handle_t *o;
+ methodinfo *m;
+ java_lang_String *s;
+ java_lang_Throwable *object;
+
+ object = (java_lang_Throwable *) cause;
+
+ c = load_class_bootstrap(classname);
+
+ if (c == NULL)
+ return;
+
+ /* create object */
+
+ o = builtin_new(c);
+
+ if (o == NULL)
+ return;
+
+ /* call initializer */
+
+ m = class_resolveclassmethod(c,
+ utf_init,
+ utf_java_lang_String__void,
+ NULL,
+ true);
+
+ if (m == NULL)
+ return;
+
+ LLNI_field_get_ref(object, detailMessage, s);
+
+ (void) vm_call_method(m, o, s);
+
+ /* call initCause */
+
+ m = class_resolveclassmethod(c,
+ utf_initCause,
+ utf_java_lang_Throwable__java_lang_Throwable,
+ NULL,
+ true);
+
+ if (m == NULL)
+ return;
+
+ (void) vm_call_method(m, o, cause);
+
+ exceptions_set_exception(o);
}
*******************************************************************************/
-static java_objectheader *exceptions_new_utf_javastring(utf *classname,
- java_objectheader *message)
+static java_handle_t *exceptions_new_utf_javastring(utf *classname,
+ java_handle_t *message)
{
- java_objectheader *o;
- classinfo *c;
+ java_handle_t *o;
+ classinfo *c;
c = load_class_bootstrap(classname);
if (c == NULL)
- return *exceptionptr;
+ return exceptions_get_exception();
o = native_new_and_init_string(c, message);
if (o == NULL)
- return *exceptionptr;
+ return exceptions_get_exception();
return o;
}
*******************************************************************************/
-static java_objectheader *exceptions_new_class_utf(classinfo *c, utf *message)
+static java_handle_t *exceptions_new_class_utf(classinfo *c, utf *message)
{
- java_objectheader *o;
- java_objectheader *s;
+ java_handle_t *o;
+ java_handle_t *s;
s = javastring_new(message);
if (s == NULL)
- return *exceptionptr;
+ return exceptions_get_exception();
o = native_new_and_init_string(c, s);
if (o == NULL)
- return *exceptionptr;
+ return exceptions_get_exception();
return o;
}
*******************************************************************************/
-static java_objectheader *exceptions_new_utf_utf(utf *classname, utf *message)
+static java_handle_t *exceptions_new_utf_utf(utf *classname, utf *message)
{
- classinfo *c;
- java_objectheader *o;
+ classinfo *c;
+ java_handle_t *o;
c = load_class_bootstrap(classname);
if (c == NULL)
- return *exceptionptr;
+ return exceptions_get_exception();
o = exceptions_new_class_utf(c, message);
}
-/* new_exception_message *******************************************************
-
- Creates an exception object with the given name and initalizes it
- with the given char message.
-
- 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).
-
-*******************************************************************************/
-
-static java_objectheader *new_exception_message(const char *classname,
- const char *message)
-{
- java_objectheader *o;
- java_objectheader *s;
-
- s = javastring_new_from_utf_string(message);
-
- if (s == NULL)
- return *exceptionptr;
-
- o = exceptions_new_utf_javastring(classname, s);
-
- return o;
-}
-
-
/* exceptions_throw_class_utf **************************************************
Creates an exception object of the given class, initalizes and
static void exceptions_throw_class_utf(classinfo *c, utf *message)
{
- *exceptionptr = exceptions_new_class_utf(c, message);
+ java_handle_t *o;
+
+ o = exceptions_new_class_utf(c, message);
+
+ exceptions_set_exception(o);
}
static void exceptions_throw_utf_utf(utf *classname, utf *message)
{
- *exceptionptr = exceptions_new_utf_utf(classname, message);
-}
-
-
-/* new_exception_int ***********************************************************
-
- Creates an exception object with the given name and initalizes it
- with the given int value.
-
- IN:
- classname....class name in UTF-8
- i............the integer
-
- 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_exception_int(const char *classname, s4 i)
-{
- java_objectheader *o;
- classinfo *c;
-
- if (!(c = load_class_bootstrap(utf_new_char(classname))))
- return *exceptionptr;
-
- o = native_new_and_init_int(c, i);
+ java_handle_t *o;
- if (!o)
- return *exceptionptr;
+ o = exceptions_new_utf_utf(classname, message);
- return o;
+ exceptions_set_exception(o);
}
*******************************************************************************/
-java_objectheader *exceptions_new_abstractmethoderror(void)
+java_handle_t *exceptions_new_abstractmethoderror(void)
{
- java_objectheader *o;
+ java_handle_t *o;
o = exceptions_new_utf(utf_java_lang_AbstractMethodError);
*******************************************************************************/
#if defined(ENABLE_JAVAME_CLDC1_1)
-static java_objectheader *exceptions_new_error(utf *message)
+static java_handle_t *exceptions_new_error(utf *message)
{
- java_objectheader *o;
+ java_handle_t *o;
o = exceptions_new_class_utf(class_java_lang_Error, message);
*******************************************************************************/
-java_objectheader *exceptions_asm_new_abstractmethoderror(u1 *sp, u1 *ra)
+java_object_t *exceptions_asm_new_abstractmethoderror(u1 *sp, u1 *ra)
{
- stackframeinfo sfi;
- java_objectheader *e;
+ stackframeinfo sfi;
+ java_handle_t *e;
/* create the stackframeinfo (XPC is equal to RA) */
*******************************************************************************/
-java_objectheader *exceptions_new_arraystoreexception(void)
+java_handle_t *exceptions_new_arraystoreexception(void)
{
- java_objectheader *o;
+ java_handle_t *o;
o = exceptions_new_utf(utf_java_lang_ArrayStoreException);
classloader.
IN:
- c............the class in which the error was found
+ c....the class in which the error was found
*******************************************************************************/
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_utf_utf(utf_java_lang_ClassCircularityError, c->name);
}
void exceptions_throw_classformaterror(classinfo *c, const char *message, ...)
{
- java_objectheader *o;
- char *msg;
- s4 msglen;
- va_list ap;
+ char *msg;
+ s4 msglen;
+ va_list ap;
+ utf *u;
/* calculate message length */
if (c != NULL)
strcat(msg, ")");
- o = new_exception_message(utf_java_lang_ClassFormatError, msg);
+ u = utf_new_char(msg);
+
+ /* free memory */
MFREE(msg, char, msglen);
- *exceptionptr = o;
+ /* throw exception */
+
+ exceptions_throw_utf_utf(utf_java_lang_ClassFormatError, u);
}
void exceptions_throw_noclassdeffounderror(utf *name)
{
+ if (vm_initializing)
+ vm_abort("java.lang.NoClassDefFoundError: %s", name->text);
+
exceptions_throw_class_utf(class_java_lang_NoClassDefFoundError, name);
}
-/* classnotfoundexception_to_noclassdeffounderror ******************************
+/* exceptions_throw_noclassdeffounderror_cause *********************************
- Check the *exceptionptr for a ClassNotFoundException. If it is one,
- convert it to a NoClassDefFoundError.
+ Generates and throws a java.lang.NoClassDefFoundError with the
+ given cause.
*******************************************************************************/
-void classnotfoundexception_to_noclassdeffounderror(void)
+void exceptions_throw_noclassdeffounderror_cause(java_handle_t *cause)
{
- java_objectheader *xptr;
- java_objectheader *cause;
- java_lang_Throwable *t;
- java_lang_String *s;
+ exceptions_throw_utf_cause(utf_java_lang_NoClassDefFoundError, cause);
+}
- /* get the cause */
- cause = *exceptionptr;
+/* exceptions_throw_noclassdeffounderror_wrong_name ****************************
- /* convert ClassNotFoundException's to NoClassDefFoundError's */
+ Generates and throws a java.lang.NoClassDefFoundError with a
+ specific message:
- if (builtin_instanceof(cause, class_java_lang_ClassNotFoundException)) {
- /* clear exception, because we are calling jit code again */
+ IN:
+ name.........name of the class not found as a utf *
- *exceptionptr = NULL;
+*******************************************************************************/
- /* create new error */
+void exceptions_throw_noclassdeffounderror_wrong_name(classinfo *c, utf *name)
+{
+ char *msg;
+ s4 msglen;
+ utf *u;
- t = (java_lang_Throwable *) cause;
- s = t->detailMessage;
+ msglen = utf_bytes(c->name) + strlen(" (wrong name: ") +
+ utf_bytes(name) + strlen(")") + strlen("0");
- xptr = exceptions_new_utf_javastring(utf_java_lang_NoClassDefFoundError, s);
+ msg = MNEW(char, msglen);
- /* we had an exception while creating the error */
+ utf_copy_classname(msg, c->name);
+ strcat(msg, " (wrong name: ");
+ utf_cat_classname(msg, name);
+ strcat(msg, ")");
- if (*exceptionptr)
- return;
+ u = utf_new_char(msg);
- /* set new exception */
+ MFREE(msg, char, msglen);
- *exceptionptr = xptr;
- }
+ exceptions_throw_noclassdeffounderror(u);
}
*******************************************************************************/
-void exceptions_throw_exceptionininitializererror(java_objectheader *cause)
+void exceptions_throw_exceptionininitializererror(java_handle_t *cause)
{
exceptions_throw_utf_throwable(utf_java_lang_ExceptionInInitializerError,
cause);
void exceptions_throw_incompatibleclasschangeerror(classinfo *c, const char *message)
{
- java_objectheader *o;
- char *msg;
- s4 msglen;
+ char *msg;
+ s4 msglen;
+ utf *u;
/* calculate exception message length */
utf_copy_classname(msg, c->name);
strcat(msg, message);
- o = native_new_and_init_string(utf_java_lang_IncompatibleClassChangeError,
- javastring_new_from_utf_string(msg));
+ u = utf_new_char(msg);
/* free memory */
MFREE(msg, char, msglen);
- if (o == NULL)
- return;
+ /* throw exception */
- *exceptionptr = o;
+ exceptions_throw_utf_utf(utf_java_lang_IncompatibleClassChangeError, u);
}
void exceptions_throw_internalerror(const char *message, ...)
{
- java_objectheader *o;
- va_list ap;
- char *msg;
- s4 msglen;
+ va_list ap;
+ char *msg;
+ s4 msglen;
+ utf *u;
/* calculate exception message length */
vsprintf(msg, message, ap);
va_end(ap);
- /* create exception object */
-
- o = new_exception_message(utf_java_lang_InternalError, msg);
+ u = utf_new_char(msg);
/* free memory */
MFREE(msg, char, msglen);
- if (o == NULL)
- return;
+ /* throw exception */
- *exceptionptr = o;
+ exceptions_throw_utf_utf(utf_java_lang_InternalError, u);
}
void exceptions_throw_linkageerror(const char *message, classinfo *c)
{
- java_objectheader *o;
- char *msg;
- s4 msglen;
+ java_handle_t *o;
+ char *msg;
+ s4 msglen;
/* calculate exception message length */
if (o == NULL)
return;
- *exceptionptr = o;
+ exceptions_set_exception(o);
}
MFREE(msg, char, msglen);
+#if defined(ENABLE_JAVASE)
exceptions_throw_utf_utf(utf_java_lang_NoSuchMethodError, u);
+#else
+ exceptions_throw_class_utf(class_java_lang_Error, u);
+#endif
}
void exceptions_throw_unsupportedclassversionerror(classinfo *c, u4 ma, u4 mi)
{
- java_objectheader *o;
- char *msg;
- s4 msglen;
+ char *msg;
+ s4 msglen;
+ utf *u;
/* calculate exception message length */
sprintf(msg + strlen(msg), " (Unsupported major.minor version %d.%d)",
ma, mi);
- /* create exception object */
-
- o = new_exception_message(utf_java_lang_UnsupportedClassVersionError, msg);
+ u = utf_new_char(msg);
/* free memory */
MFREE(msg, char, msglen);
- if (o == NULL)
- return;
+ /* throw exception */
- *exceptionptr = o;
+ exceptions_throw_utf_utf(utf_java_lang_UnsupportedClassVersionError, u);
}
void exceptions_throw_verifyerror(methodinfo *m, const char *message, ...)
{
- java_objectheader *o;
- va_list ap;
- char *msg;
- s4 msglen;
+ va_list ap;
+ char *msg;
+ s4 msglen;
+ utf *u;
/* calculate exception message length */
vsprintf(msg + strlen(msg), message, ap);
va_end(ap);
- /* create exception object */
-
- o = new_exception_message(utf_java_lang_VerifyError, msg);
+ u = utf_new_char(msg);
/* free memory */
MFREE(msg, char, msglen);
- *exceptionptr = o;
+ /* throw exception */
+
+ exceptions_throw_utf_utf(utf_java_lang_VerifyError, u);
}
*******************************************************************************/
-void exceptions_throw_verifyerror_for_stack(methodinfo *m,int type)
+void exceptions_throw_verifyerror_for_stack(methodinfo *m, int type)
{
- java_objectheader *o;
- char *msg;
- s4 msglen;
- char *typename;
+ char *msg;
+ s4 msglen;
+ char *typename;
+ utf *u;
/* calculate exception message length */
msglen = 0;
- if (m)
+ if (m != NULL)
msglen = strlen("(class: ") + utf_bytes(m->class->name) +
strlen(", method: ") + utf_bytes(m->name) +
strlen(" signature: ") + utf_bytes(m->descriptor) +
/* generate message */
- if (m) {
+ if (m != NULL) {
strcpy(msg, "(class: ");
utf_cat_classname(msg, m->class->name);
strcat(msg, ", method: ");
msg[0] = 0;
}
- strcat(msg,"Expecting to find ");
+ strcat(msg, "Expecting to find ");
+
switch (type) {
case TYPE_INT: typename = "integer"; break;
case TYPE_LNG: typename = "long"; break;
case TYPE_RET: typename = "returnAddress"; break;
default: typename = "<INVALID>"; assert(0); break;
}
+
strcat(msg, typename);
strcat(msg, " on stack");
- /* create exception object */
-
- o = new_exception_message(utf_java_lang_VerifyError, msg);
+ u = utf_new_char(msg);
/* free memory */
MFREE(msg, char, msglen);
- *exceptionptr = o;
+ /* throw exception */
+
+ exceptions_throw_utf_utf(utf_java_lang_VerifyError, u);
}
*******************************************************************************/
-java_objectheader *exceptions_new_arithmeticexception(void)
+java_handle_t *exceptions_new_arithmeticexception(void)
{
- java_objectheader *o;
+ java_handle_t *o;
- o = new_exception_message(utf_java_lang_ArithmeticException, "/ by zero");
-
- if (o == NULL)
- return *exceptionptr;
+ o = exceptions_new_utf_utf(utf_java_lang_ArithmeticException,
+ utf_division_by_zero);
return o;
}
*******************************************************************************/
-java_objectheader *exceptions_new_arrayindexoutofboundsexception(s4 index)
+java_handle_t *exceptions_new_arrayindexoutofboundsexception(s4 index)
{
- java_objectheader *o;
- methodinfo *m;
- java_objectheader *s;
+ java_handle_t *o;
+ methodinfo *m;
+ java_handle_t *s;
/* convert the index into a String, like Sun does */
true);
if (m == NULL)
- return *exceptionptr;
+ return exceptions_get_exception();
s = vm_call_method(m, NULL, index);
if (s == NULL)
- return *exceptionptr;
+ return exceptions_get_exception();
o = exceptions_new_utf_javastring(utf_java_lang_ArrayIndexOutOfBoundsException,
s);
if (o == NULL)
- return *exceptionptr;
+ return exceptions_get_exception();
return o;
}
*******************************************************************************/
-java_objectheader *exceptions_new_classcastexception(java_objectheader *o)
+java_handle_t *exceptions_new_classcastexception(java_handle_t *o)
{
- java_objectheader *e;
- utf *classname;
- java_lang_String *s;
+ java_handle_t *e;
+ utf *classname;
classname = o->vftbl->class->name;
- s = javastring_new(classname);
-
- e = native_new_and_init_string(class_java_lang_ClassCastException, s);
-
- if (e == NULL)
- return *exceptionptr;
+ e = exceptions_new_class_utf(class_java_lang_ClassCastException, classname);
return e;
}
*******************************************************************************/
-void exceptions_throw_illegalaccessexception(classinfo *c)
+void exceptions_throw_illegalaccessexception(utf *message)
{
- /* XXX handle argument */
-
- exceptions_throw_utf(utf_java_lang_IllegalAccessException);
+ exceptions_throw_utf_utf(utf_java_lang_IllegalAccessException, message);
}
*******************************************************************************/
-void exceptions_throw_invocationtargetexception(java_objectheader *cause)
+void exceptions_throw_invocationtargetexception(java_handle_t *cause)
{
exceptions_throw_utf_throwable(utf_java_lang_reflect_InvocationTargetException,
cause);
*******************************************************************************/
-java_objectheader *exceptions_new_nullpointerexception(void)
+java_handle_t *exceptions_new_nullpointerexception(void)
{
- java_objectheader *o;
+ java_handle_t *o;
o = exceptions_new_class(class_java_lang_NullPointerException);
}
+/* exceptions_throw_privilegedactionexception **********************************
+
+ Generates and throws a java.security.PrivilegedActionException.
+
+*******************************************************************************/
+
+void exceptions_throw_privilegedactionexception(java_handle_t *exception)
+{
+ exceptions_throw_utf_exception(utf_java_security_PrivilegedActionException,
+ exception);
+}
+
+
/* exceptions_throw_stringindexoutofboundsexception ****************************
Generates and throws a java.lang.StringIndexOutOfBoundsException
}
-/* exceptions_get_exception ****************************************************
+/* exceptions_classnotfoundexception_to_noclassdeffounderror *******************
- Returns the current exception pointer of the current thread.
+ Check the exception for a ClassNotFoundException. If it is one,
+ convert it to a NoClassDefFoundError.
*******************************************************************************/
-java_objectheader *exceptions_get_exception(void)
+void exceptions_classnotfoundexception_to_noclassdeffounderror(void)
{
- /* return the exception */
+ java_handle_t *o;
+ java_handle_t *cause;
+ java_lang_Throwable *object;
+ java_lang_String *s;
- return *exceptionptr;
-}
+ /* get the cause */
+ cause = exceptions_get_exception();
-/* exceptions_set_exception ****************************************************
-
- Sets the exception pointer of the current thread.
+ /* convert ClassNotFoundException's to NoClassDefFoundError's */
-*******************************************************************************/
+ if (builtin_instanceof(cause, class_java_lang_ClassNotFoundException)) {
+ /* clear exception, because we are calling jit code again */
-void exceptions_set_exception(java_objectheader *o)
-{
- /* set the exception */
+ exceptions_clear_exception();
- *exceptionptr = o;
-}
+ /* create new error */
+ object = (java_lang_Throwable *) cause;
+ LLNI_field_get_ref(object, detailMessage, s);
-/* exceptions_clear_exception **************************************************
+ o = exceptions_new_utf_javastring(utf_java_lang_NoClassDefFoundError,
+ (java_handle_t *) s);
- Clears the current exception pointer of the current thread.
+ /* we had an exception while creating the error */
-*******************************************************************************/
+ if (exceptions_get_exception())
+ return;
-void exceptions_clear_exception(void)
-{
- /* and clear the exception */
+ /* set new exception */
- *exceptionptr = NULL;
+ exceptions_set_exception(o);
+ }
}
-/* exceptions_get_and_clear_exception ******************************************
+/* exceptions_fillinstacktrace *************************************************
- Gets the exception pointer of the current thread and clears it.
- This function may return NULL.
+ Calls the fillInStackTrace-method of the currently thrown
+ exception.
*******************************************************************************/
-java_objectheader *exceptions_get_and_clear_exception(void)
+java_handle_t *exceptions_fillinstacktrace(void)
{
- java_objectheader **p;
- java_objectheader *e;
+ java_handle_t *o;
+ methodinfo *m;
- /* get the pointer of the exception pointer */
+ /* get exception */
- p = exceptionptr;
+ o = exceptions_get_and_clear_exception();
- /* get the exception */
+ assert(o);
- e = *p;
+ /* resolve methodinfo pointer from exception object */
- /* and clear the exception */
+#if defined(ENABLE_JAVASE)
+ m = class_resolvemethod(o->vftbl->class,
+ utf_fillInStackTrace,
+ utf_void__java_lang_Throwable);
+#elif defined(ENABLE_JAVAME_CLDC1_1)
+ m = class_resolvemethod(o->vftbl->class,
+ utf_fillInStackTrace,
+ utf_void__void);
+#else
+#error IMPLEMENT ME!
+#endif
- *p = NULL;
+ /* call function */
- /* return the exception */
+ (void) vm_call_method(m, o);
- return e;
+ /* return exception object */
+
+ return o;
}
*******************************************************************************/
#if defined(ENABLE_JIT)
-u1 *exceptions_handle_exception(java_objectheader *xptr, u1 *xpc, u1 *pv, u1 *sp)
+u1 *exceptions_handle_exception(java_object_t *xptr, u1 *xpc, u1 *pv, u1 *sp)
{
methodinfo *m;
codeinfo *code;
classref_or_classinfo cr;
classinfo *c;
#if defined(ENABLE_THREADS)
- java_objectheader *o;
+ java_object_t *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));
#if !defined(NDEBUG)
/* print exception trace */
- if (opt_verbose || opt_verbosecall || opt_verboseexception)
+ if (opt_verbose || opt_verbosecall || opt_TraceExceptions)
builtin_trace_exception(xptr, m, xpc, 1);
#endif
+#if defined(ENABLE_VMLOG)
+ vmlog_cacao_throw(xptr);
+#endif
+
for (i = 0; i < exceptiontablelength; i++) {
/* ATTENTION: keep this here, as we need to decrement the
pointer before the loop executes! */
/* 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 */
#if !defined(NDEBUG)
/* Print stacktrace of exception when caught. */
- if (opt_verboseexception) {
+#if defined(ENABLE_VMLOG)
+ vmlog_cacao_catch(xptr);
+#endif
+
+ if (opt_TraceExceptions) {
exceptions_print_exception(xptr);
stacktrace_print_trace(xptr);
}
#if !defined(NDEBUG)
/* Print stacktrace of exception when caught. */
- if (opt_verboseexception) {
+#if defined(ENABLE_VMLOG)
+ vmlog_cacao_catch(xptr);
+#endif
+
+ if (opt_TraceExceptions) {
exceptions_print_exception(xptr);
stacktrace_print_trace(xptr);
}
if (issync) {
/* get synchronization object */
-# if defined(__MIPS__) && (SIZEOF_VOID_P == 4)
+# if (defined(__MIPS__) && (SIZEOF_VOID_P == 4)) || defined(__I386__) || defined(__S390__) || defined(__POWERPC__)
/* XXX change this if we ever want to use 4-byte stackslots */
- o = *((java_objectheader **) (sp + issync - 8));
+ o = *((java_object_t **) (sp + issync - 8));
# else
- o = *((java_objectheader **) (sp + issync - SIZEOF_VOID_P));
-#endif
+ o = *((java_object_t **) (sp + issync - SIZEOF_VOID_P));
+# endif
assert(o != NULL);
/* none of the exceptions catch this one */
+#if defined(ENABLE_VMLOG)
+ vmlog_cacao_unwnd_method(m);
+#endif
+
return NULL;
}
#endif /* defined(ENABLE_JIT) */
*******************************************************************************/
-void exceptions_print_exception(java_objectheader *xptr)
+void exceptions_print_exception(java_handle_t *xptr)
{
java_lang_Throwable *t;
#if defined(ENABLE_JAVASE)
java_lang_Throwable *cause;
#endif
+ java_lang_String *s;
+ classinfo *c;
utf *u;
t = (java_lang_Throwable *) xptr;
}
#if defined(ENABLE_JAVASE)
- cause = t->cause;
+ LLNI_field_get_ref(t, cause, cause);
#endif
/* print the root exception */
- utf_display_printable_ascii_classname(t->header.vftbl->class->name);
+ LLNI_class_get(t, c);
+ utf_display_printable_ascii_classname(c->name);
+
+ LLNI_field_get_ref(t, detailMessage, s);
- if (t->detailMessage != NULL) {
- u = javastring_toutf(t->detailMessage, false);
+ if (s != NULL) {
+ u = javastring_toutf((java_handle_t *) s, false);
printf(": ");
utf_display_printable_ascii(u);
if ((cause != NULL) && (cause != t)) {
printf("Caused by: ");
- utf_display_printable_ascii_classname(cause->header.vftbl->class->name);
+
+ LLNI_class_get(cause, c);
+ utf_display_printable_ascii_classname(c->name);
+
+ LLNI_field_get_ref(cause, detailMessage, s);
- if (cause->detailMessage) {
- u = javastring_toutf(cause->detailMessage, false);
+ if (s != NULL) {
+ u = javastring_toutf((java_handle_t *) s, false);
printf(": ");
utf_display_printable_ascii(u);
void exceptions_print_current_exception(void)
{
- java_objectheader *xptr;
+ java_handle_t *o;
+
+ o = exceptions_get_exception();
+
+ exceptions_print_exception(o);
+}
+
+
+/* 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_handle_t *oxptr;
+ java_handle_t *xptr;
+ classinfo *c;
+ methodinfo *m;
+
+ /* get original exception */
+
+ oxptr = exceptions_get_and_clear_exception();
+
+ if (oxptr == NULL)
+ vm_abort("exceptions_print_stacktrace: no exception thrown");
+
+ /* clear exception, because we are calling jit code again */
+
+ 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 */
- xptr = *exceptionptr;
+ 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 = exceptions_get_exception();
+
+ if (xptr != NULL) {
+ fprintf(stderr, "Exception while printStackTrace(): ");
- exceptions_print_exception(xptr);
+ /* 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);
}