Changes: Edwin Steiner
- $Id: exceptions.c 4878 2006-05-05 17:09:48Z edwin $
+ $Id: exceptions.c 5586 2006-09-29 14:21:42Z edwin $
*/
/* for raising exceptions from native methods *********************************/
-#if !defined(USE_THREADS) || !defined(NATIVE_THREADS)
+#if !defined(ENABLE_THREADS)
java_objectheader *_no_threads_exceptionptr = NULL;
#endif
!link_class(class_java_lang_Error))
return false;
- /* java/lang/NoClassDefFoundError */
+ /* java/lang/AbstractMethodError */
- if (!(class_java_lang_NoClassDefFoundError =
- load_class_bootstrap(utf_java_lang_NoClassDefFoundError)) ||
- !link_class(class_java_lang_NoClassDefFoundError))
+ if (!(class_java_lang_AbstractMethodError =
+ load_class_bootstrap(utf_java_lang_AbstractMethodError)) ||
+ !link_class(class_java_lang_AbstractMethodError))
return false;
/* java/lang/LinkageError */
!link_class(class_java_lang_LinkageError))
return false;
+ /* java/lang/NoClassDefFoundError */
+
+ if (!(class_java_lang_NoClassDefFoundError =
+ load_class_bootstrap(utf_java_lang_NoClassDefFoundError)) ||
+ !link_class(class_java_lang_NoClassDefFoundError))
+ return false;
+
/* java/lang/NoSuchMethodError */
if (!(class_java_lang_NoSuchMethodError =
!link_class(class_java_lang_Exception))
return false;
+ /* java/lang/ClassCastException */
+
+ if (!(class_java_lang_ClassCastException =
+ load_class_bootstrap(utf_java_lang_ClassCastException)) ||
+ !link_class(class_java_lang_ClassCastException))
+ return false;
+
/* java/lang/ClassNotFoundException */
if (!(class_java_lang_ClassNotFoundException =
t = (java_lang_Throwable *) *exceptionptr;
fprintf(stderr, "Exception while printStackTrace(): ");
- utf_fprint_classname(stderr, t->header.vftbl->class->name);
+ utf_fprint_printable_ascii_classname(stderr, t->header.vftbl->class->name);
if (t->detailMessage) {
char *buf;
}
} else {
- utf_fprint_classname(stderr, c->name);
+ utf_fprint_printable_ascii_classname(stderr, c->name);
fprintf(stderr, ": printStackTrace()V not found!\n");
}
}
+/* exceptions_new_abstractmethoderror ******************************************
+
+ Generates a java.lang.AbstractMethodError for the VM.
+
+*******************************************************************************/
+
+java_objectheader *exceptions_new_abstractmethoderror(void)
+{
+ java_objectheader *e;
+
+ e = native_new_and_init(class_java_lang_AbstractMethodError);
+
+ if (e == NULL)
+ return *exceptionptr;
+
+ return e;
+}
+
+
+/* exceptions_asm_new_abstractmethoderror **************************************
+
+ Generates a java.lang.AbstractMethodError for
+ asm_abstractmethoderror.
+
+*******************************************************************************/
+
+java_objectheader *exceptions_asm_new_abstractmethoderror(u1 *sp, u1 *ra)
+{
+ stackframeinfo sfi;
+ java_objectheader *e;
+
+ /* create the stackframeinfo (XPC is equal to RA) */
+
+ stacktrace_create_extern_stackframeinfo(&sfi, NULL, sp, ra, ra);
+
+ /* create the exception */
+
+ e = exceptions_new_abstractmethoderror();
+
+ /* remove the stackframeinfo */
+
+ stacktrace_remove_stackframeinfo(&sfi);
+
+ return e;
+}
+
+
+/* exceptions_throw_abstractmethoderror ****************************************
+
+ Generates a java.lang.AbstractMethodError for the VM and throws it.
+
+*******************************************************************************/
+
+void exceptions_throw_abstractmethoderror(void)
+{
+ *exceptionptr = exceptions_new_abstractmethoderror();
+}
+
+
/* new_classformaterror ********************************************************
generates a java.lang.ClassFormatError for the classloader
}
-/* new_verifyerror *************************************************************
+/* exceptions_new_verifyerror **************************************************
Generates a java.lang.VerifyError for the JIT compiler.
*******************************************************************************/
-java_objectheader *new_verifyerror(methodinfo *m, const char *message, ...)
+java_objectheader *exceptions_new_verifyerror(methodinfo *m,
+ const char *message, ...)
{
java_objectheader *o;
va_list ap;
}
+/* exceptions_throw_verifyerror ************************************************
+
+ Throws a java.lang.VerifyError for the VM system.
+
+*******************************************************************************/
+
+void exceptions_throw_verifyerror(methodinfo *m, const char *message, ...)
+{
+ *exceptionptr = exceptions_new_verifyerror(m, message);
+}
+
+
/* exceptions_throw_verifyerror_for_stack **************************************
throws a java.lang.VerifyError for an invalid stack slot type
case TYPE_FLT: typename = "float"; break;
case TYPE_DBL: typename = "double"; break;
case TYPE_ADR: typename = "object/array"; break;
+ case TYPE_RET: typename = "returnAddress"; break;
default: typename = "<INVALID>"; assert(0); break;
}
strcat(msg, typename);
*exceptionptr = o;
}
+
/* new_arithmeticexception *****************************************************
Generates a java.lang.ArithmeticException for the jit compiler.
}
-/* new_arraystoreexception *****************************************************
+/* exceptions_new_arraystoreexception ******************************************
- generates a java.lang.ArrayStoreException for the jit compiler
+ Generates a java.lang.ArrayStoreException for the VM compiler.
*******************************************************************************/
-java_objectheader *new_arraystoreexception(void)
+java_objectheader *exceptions_new_arraystoreexception(void)
{
java_objectheader *e;
}
-/* new_classcastexception ******************************************************
+/* exceptions_throw_arraystoreexception ****************************************
+
+ Generates a java.lang.ArrayStoreException for the VM system and
+ throw it in the VM system.
+
+*******************************************************************************/
+
+void exceptions_throw_arraystoreexception(void)
+{
+ *exceptionptr = exceptions_new_arraystoreexception();
+}
+
+
+/* exceptions_new_classcastexception *******************************************
- generates a java.lang.ClassCastException for the jit compiler
+ Generates a java.lang.ClassCastException for the JIT compiler.
*******************************************************************************/
-java_objectheader *new_classcastexception(void)
+java_objectheader *exceptions_new_classcastexception(java_objectheader *o)
{
java_objectheader *e;
+ utf *classname;
+ java_lang_String *s;
- e = new_exception(string_java_lang_ClassCastException);
+ classname = o->vftbl->class->name;
- if (!e)
+ s = javastring_new(classname);
+
+ e = native_new_and_init_string(class_java_lang_ClassCastException, s);
+
+ if (e == NULL)
return *exceptionptr;
return e;
}
-/* new_illegalmonitorstateexception ********************************************
+/* exceptions_new_illegalmonitorstateexception *********************************
Generates a java.lang.IllegalMonitorStateException for the VM
thread system.
*******************************************************************************/
-java_objectheader *new_illegalmonitorstateexception(void)
+java_objectheader *exceptions_new_illegalmonitorstateexception(void)
{
java_objectheader *e;
e = native_new_and_init(class_java_lang_IllegalMonitorStateException);
- if (!e)
+ if (e == NULL)
return *exceptionptr;
return e;
}
+/* exceptions_throw_illegalmonitorstateexception *******************************
+
+ Generates a java.lang.IllegalMonitorStateException for the VM
+ system and throw it in the VM system.
+
+*******************************************************************************/
+
+void exceptions_throw_illegalmonitorstateexception(void)
+{
+ *exceptionptr = exceptions_new_illegalmonitorstateexception();
+}
+
+
/* exceptions_new_negativearraysizeexception ***********************************
Generates a java.lang.NegativeArraySizeException for the VM system.
}
+/* exceptions_get_and_clear_exception ******************************************
+
+ Gets the exception pointer of the current thread and clears it.
+ This function may return NULL.
+
+*******************************************************************************/
+
+java_objectheader *exceptions_get_and_clear_exception(void)
+{
+ java_objectheader **p;
+ java_objectheader *e;
+
+ /* get the pointer of the exception pointer */
+
+ p = exceptionptr;
+
+ /* get the exception */
+
+ e = *p;
+
+ /* and clear the exception */
+
+ *p = NULL;
+
+ /* return the exception */
+
+ return e;
+}
+
+
/* exceptions_handle_exception *************************************************
Try to find an exception handler for the given exception and return it.
u1 *exceptions_handle_exception(java_objectheader *xptr, u1 *xpc, u1 *pv, u1 *sp)
{
methodinfo *m;
+ codeinfo *code;
s4 framesize;
s4 issync;
exceptionentry *ex;
s4 i;
classref_or_classinfo cr;
classinfo *c;
-#if defined(USE_THREADS)
+#if defined(ENABLE_THREADS)
java_objectheader *o;
#endif
- /* get methodinfo pointer from method header */
+ /* get info from the method header */
- m = *((methodinfo **) (pv + MethodPointer));
+ code = *((codeinfo **) (pv + CodeinfoPointer));
framesize = *((s4 *) (pv + FrameSize));
issync = *((s4 *) (pv + IsSync));
ex = (exceptionentry *) (pv + ExTableStart);
exceptiontablelength = *((s4 *) (pv + ExTableSize));
+ /* Get the methodinfo pointer from the codeinfo pointer. For
+ asm_vm_call_method the codeinfo pointer is NULL. */
+
+ m = (code == NULL) ? NULL : code->m;
+
#if !defined(NDEBUG)
/* print exception trace */
/* resolve or load/link the exception class */
if (IS_CLASSREF(cr)) {
+ /* The exception class reference is unresolved. */
+ /* We have to do _eager_ resolving here. While the class of */
+ /* the exception object is guaranteed to be loaded, it may */
+ /* well have been loaded by a different loader than the */
+ /* defining loader of m's class, which is the one we must */
+ /* use to resolve the catch class. Thus lazy resolving */
+ /* might fail, even if the result of the resolution would */
+ /* be an already loaded class. */
+
c = resolve_classref_eager(cr.ref);
+ if (c == NULL) {
+ /* Exception resolving the exception class, argh! */
+ return NULL;
+ }
+
+ /* Ok, we resolved it. Enter it in the table, so we don't */
+ /* have to do this again. */
+ /* XXX this write should be atomic. Is it? */
+
+ ex->catchtype.cls = c;
} else {
c = cr.cls;
+ /* XXX I don't think this case can ever happen. -Edwin */
if (!(c->state & CLASS_LOADED))
/* use the methods' classloader */
if (!load_class_from_classloader(c->name,
m->class->classloader))
return NULL;
+ /* XXX I think, if it is not linked, we can be sure that */
+ /* the exception object is no (indirect) instance of it, no? */
+ /* -Edwin */
if (!(c->state & CLASS_LINKED))
if (!link_class(c))
return NULL;
}
}
-#if defined(USE_THREADS)
+#if defined(ENABLE_THREADS)
/* is this method synchronized? */
if (issync) {
assert(o != NULL);
- builtin_monitorexit(o);
+ lock_monitor_exit(o);
}
#endif
/* print the root exception */
- utf_display_classname(t->header.vftbl->class->name);
+ utf_display_printable_ascii_classname(t->header.vftbl->class->name);
if (t->detailMessage) {
u = javastring_toutf(t->detailMessage, false);
printf(": ");
- utf_display(u);
+ utf_display_printable_ascii(u);
}
putc('\n', stdout);
if (cause && (cause != t)) {
printf("Caused by: ");
- utf_display_classname(cause->header.vftbl->class->name);
+ utf_display_printable_ascii_classname(cause->header.vftbl->class->name);
if (cause->detailMessage) {
u = javastring_toutf(cause->detailMessage, false);
printf(": ");
- utf_display(u);
+ utf_display_printable_ascii(u);
}
putc('\n', stdout);