1 /* src/vm/exceptions.c - exception related functions
3 Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 $Id: exceptions.c 7596 2007-03-28 21:05:53Z twisti $
41 #include "mm/memory.h"
43 #include "native/jni.h"
44 #include "native/native.h"
45 #include "native/include/java_lang_String.h"
46 #include "native/include/java_lang_Throwable.h"
48 #if defined(ENABLE_THREADS)
49 # include "threads/native/threads.h"
51 # include "threads/none/threads.h"
54 #include "toolbox/logging.h"
55 #include "toolbox/util.h"
57 #include "vm/builtin.h"
58 #include "vm/exceptions.h"
59 #include "vm/global.h"
60 #include "vm/stringlocal.h"
63 #include "vm/jit/asmpart.h"
64 #include "vm/jit/disass.h"
65 #include "vm/jit/jit.h"
66 #include "vm/jit/methodheader.h"
67 #include "vm/jit/stacktrace.h"
69 #include "vmcore/class.h"
70 #include "vmcore/loader.h"
71 #include "vmcore/options.h"
74 /* for raising exceptions from native methods *********************************/
76 #if !defined(ENABLE_THREADS)
77 java_objectheader *_no_threads_exceptionptr = NULL;
81 /* init_system_exceptions ******************************************************
83 Load and link exceptions used in the system.
85 *******************************************************************************/
87 bool exceptions_init(void)
89 /* java/lang/Throwable */
91 if (!(class_java_lang_Throwable =
92 load_class_bootstrap(utf_java_lang_Throwable)) ||
93 !link_class(class_java_lang_Throwable))
98 if (!(class_java_lang_Error = load_class_bootstrap(utf_java_lang_Error)) ||
99 !link_class(class_java_lang_Error))
102 #if defined(ENABLE_JAVASE)
103 /* java/lang/LinkageError */
105 if (!(class_java_lang_LinkageError =
106 load_class_bootstrap(utf_java_lang_LinkageError)) ||
107 !link_class(class_java_lang_LinkageError))
111 /* java/lang/NoClassDefFoundError */
113 if (!(class_java_lang_NoClassDefFoundError =
114 load_class_bootstrap(utf_java_lang_NoClassDefFoundError)) ||
115 !link_class(class_java_lang_NoClassDefFoundError))
118 /* java/lang/OutOfMemoryError */
120 if (!(class_java_lang_OutOfMemoryError =
121 load_class_bootstrap(utf_java_lang_OutOfMemoryError)) ||
122 !link_class(class_java_lang_OutOfMemoryError))
125 /* java/lang/VirtualMachineError */
127 if (!(class_java_lang_VirtualMachineError =
128 load_class_bootstrap(utf_java_lang_VirtualMachineError)) ||
129 !link_class(class_java_lang_VirtualMachineError))
133 /* java/lang/Exception */
135 if (!(class_java_lang_Exception =
136 load_class_bootstrap(utf_java_lang_Exception)) ||
137 !link_class(class_java_lang_Exception))
140 /* java/lang/ClassCastException */
142 if (!(class_java_lang_ClassCastException =
143 load_class_bootstrap(utf_java_lang_ClassCastException)) ||
144 !link_class(class_java_lang_ClassCastException))
147 /* java/lang/ClassNotFoundException */
149 if (!(class_java_lang_ClassNotFoundException =
150 load_class_bootstrap(utf_java_lang_ClassNotFoundException)) ||
151 !link_class(class_java_lang_ClassNotFoundException))
154 /* java/lang/NullPointerException */
156 if (!(class_java_lang_NullPointerException =
157 load_class_bootstrap(utf_java_lang_NullPointerException)) ||
158 !link_class(class_java_lang_NullPointerException))
162 #if defined(WITH_CLASSPATH_GNU)
163 /* java/lang/VMThrowable */
165 if (!(class_java_lang_VMThrowable =
166 load_class_bootstrap(utf_java_lang_VMThrowable)) ||
167 !link_class(class_java_lang_VMThrowable))
175 /* exceptions_new_class ********************************************************
177 Creates an exception object from the given class and initalizes it.
180 class....class pointer
182 *******************************************************************************/
184 static java_objectheader *exceptions_new_class(classinfo *c)
186 java_objectheader *o;
188 o = native_new_and_init(c);
191 return *exceptionptr;
197 /* exceptions_new_utf **********************************************************
199 Creates an exception object with the given name and initalizes it.
202 classname....class name in UTF-8
204 *******************************************************************************/
206 static java_objectheader *exceptions_new_utf(utf *classname)
209 java_objectheader *o;
211 c = load_class_bootstrap(classname);
214 return *exceptionptr;
216 o = exceptions_new_class(c);
222 /* exceptions_throw_class ******************************************************
224 Creates an exception object from the given class, initalizes and
228 class....class pointer
230 *******************************************************************************/
232 static void exceptions_throw_class(classinfo *c)
234 java_objectheader *o;
236 o = exceptions_new_class(c);
245 /* exceptions_throw_utf ********************************************************
247 Creates an exception object with the given name, initalizes and
251 classname....class name in UTF-8
253 *******************************************************************************/
255 static void exceptions_throw_utf(utf *classname)
259 c = load_class_bootstrap(classname);
264 exceptions_throw_class(c);
268 /* exceptions_throw_utf_throwable **********************************************
270 Creates an exception object with the given name and initalizes it
271 with the given java/lang/Throwable exception.
274 classname....class name in UTF-8
275 cause........the given Throwable
277 *******************************************************************************/
279 static void exceptions_throw_utf_throwable(utf *classname,
280 java_objectheader *cause)
282 java_objectheader *o;
285 c = load_class_bootstrap(classname);
290 o = native_new_and_init_throwable(c, cause);
299 /* exceptions_new_utf_javastring ***********************************************
301 Creates an exception object with the given name and initalizes it
302 with the given java/lang/String message.
305 classname....class name in UTF-8
306 message......the message as a java.lang.String
309 an exception pointer (in any case -- either it is the newly created
310 exception, or an exception thrown while trying to create it).
312 *******************************************************************************/
314 static java_objectheader *exceptions_new_utf_javastring(utf *classname,
315 java_objectheader *message)
317 java_objectheader *o;
320 c = load_class_bootstrap(classname);
323 return *exceptionptr;
325 o = native_new_and_init_string(c, message);
328 return *exceptionptr;
334 /* exceptions_new_class_utf ****************************************************
336 Creates an exception object of the given class and initalizes it.
339 c..........class pointer
340 message....the message as UTF-8 string
342 *******************************************************************************/
344 static java_objectheader *exceptions_new_class_utf(classinfo *c, utf *message)
346 java_objectheader *o;
347 java_objectheader *s;
349 s = javastring_new(message);
352 return *exceptionptr;
354 o = native_new_and_init_string(c, s);
357 return *exceptionptr;
363 /* exceptions_new_utf_utf ******************************************************
365 Creates an exception object with the given name and initalizes it
366 with the given utf message.
369 classname....class name in UTF-8
370 message......the message as an utf *
373 an exception pointer (in any case -- either it is the newly created
374 exception, or an exception thrown while trying to create it).
376 *******************************************************************************/
378 static java_objectheader *exceptions_new_utf_utf(utf *classname, utf *message)
381 java_objectheader *o;
383 c = load_class_bootstrap(classname);
386 return *exceptionptr;
388 o = exceptions_new_class_utf(c, message);
394 /* new_exception_message *******************************************************
396 Creates an exception object with the given name and initalizes it
397 with the given char message.
400 classname....class name in UTF-8
401 message......message in UTF-8
404 an exception pointer (in any case -- either it is the newly created
405 exception, or an exception thrown while trying to create it).
407 *******************************************************************************/
409 static java_objectheader *new_exception_message(const char *classname,
412 java_objectheader *o;
413 java_objectheader *s;
415 s = javastring_new_from_utf_string(message);
418 return *exceptionptr;
420 o = exceptions_new_utf_javastring(classname, s);
426 /* exceptions_throw_class_utf **************************************************
428 Creates an exception object of the given class, initalizes and
429 throws it with the given utf message.
432 c..........class pointer
433 message....the message as an UTF-8
435 *******************************************************************************/
437 static void exceptions_throw_class_utf(classinfo *c, utf *message)
439 *exceptionptr = exceptions_new_class_utf(c, message);
443 /* exceptions_throw_utf_utf ****************************************************
445 Creates an exception object with the given name, initalizes and
446 throws it with the given utf message.
449 classname....class name in UTF-8
450 message......the message as an utf *
452 *******************************************************************************/
454 static void exceptions_throw_utf_utf(utf *classname, utf *message)
456 *exceptionptr = exceptions_new_utf_utf(classname, message);
460 /* new_exception_int ***********************************************************
462 Creates an exception object with the given name and initalizes it
463 with the given int value.
466 classname....class name in UTF-8
467 i............the integer
470 an exception pointer (in any case -- either it is the newly created
471 exception, or an exception thrown while trying to create it).
473 *******************************************************************************/
475 java_objectheader *new_exception_int(const char *classname, s4 i)
477 java_objectheader *o;
480 if (!(c = load_class_bootstrap(utf_new_char(classname))))
481 return *exceptionptr;
483 o = native_new_and_init_int(c, i);
486 return *exceptionptr;
492 /* exceptions_new_abstractmethoderror ****************************************
494 Generates a java.lang.AbstractMethodError for the VM.
496 *******************************************************************************/
498 java_objectheader *exceptions_new_abstractmethoderror(void)
500 java_objectheader *o;
502 o = exceptions_new_utf(utf_java_lang_AbstractMethodError);
508 /* exceptions_new_error ********************************************************
510 Generates a java.lang.Error for the VM.
512 *******************************************************************************/
514 #if defined(ENABLE_JAVAME_CLDC1_1)
515 static java_objectheader *exceptions_new_error(utf *message)
517 java_objectheader *o;
519 o = exceptions_new_class_utf(class_java_lang_Error, message);
526 /* exceptions_asm_new_abstractmethoderror **************************************
528 Generates a java.lang.AbstractMethodError for
529 asm_abstractmethoderror.
531 *******************************************************************************/
533 java_objectheader *exceptions_asm_new_abstractmethoderror(u1 *sp, u1 *ra)
536 java_objectheader *e;
538 /* create the stackframeinfo (XPC is equal to RA) */
540 stacktrace_create_extern_stackframeinfo(&sfi, NULL, sp, ra, ra);
542 /* create the exception */
544 #if defined(ENABLE_JAVASE)
545 e = exceptions_new_abstractmethoderror();
547 e = exceptions_new_error(utf_java_lang_AbstractMethodError);
550 /* remove the stackframeinfo */
552 stacktrace_remove_stackframeinfo(&sfi);
558 /* exceptions_new_arraystoreexception ******************************************
560 Generates a java.lang.ArrayStoreException for the VM.
562 *******************************************************************************/
564 java_objectheader *exceptions_new_arraystoreexception(void)
566 java_objectheader *o;
568 o = exceptions_new_utf(utf_java_lang_ArrayStoreException);
574 /* exceptions_throw_abstractmethoderror ****************************************
576 Generates and throws a java.lang.AbstractMethodError for the VM.
578 *******************************************************************************/
580 void exceptions_throw_abstractmethoderror(void)
582 exceptions_throw_utf(utf_java_lang_AbstractMethodError);
586 /* exceptions_throw_classcircularityerror **************************************
588 Generates and throws a java.lang.ClassCircularityError for the
592 c............the class in which the error was found
594 *******************************************************************************/
596 void exceptions_throw_classcircularityerror(classinfo *c)
598 java_objectheader *o;
602 /* calculate message length */
604 msglen = utf_bytes(c->name) + strlen("0");
606 /* allocate a buffer */
608 msg = MNEW(char, msglen);
610 /* print message into allocated buffer */
612 utf_copy_classname(msg, c->name);
614 o = new_exception_message(utf_java_lang_ClassCircularityError, msg);
616 MFREE(msg, char, msglen);
625 /* exceptions_throw_classformaterror *******************************************
627 Generates and throws a java.lang.ClassFormatError for the VM.
630 c............the class in which the error was found
631 message......UTF-8 format string
633 *******************************************************************************/
635 void exceptions_throw_classformaterror(classinfo *c, const char *message, ...)
637 java_objectheader *o;
642 /* calculate message length */
647 msglen += utf_bytes(c->name) + strlen(" (");
649 va_start(ap, message);
650 msglen += get_variable_message_length(message, ap);
654 msglen += strlen(")");
656 msglen += strlen("0");
658 /* allocate a buffer */
660 msg = MNEW(char, msglen);
662 /* print message into allocated buffer */
665 utf_copy_classname(msg, c->name);
669 va_start(ap, message);
670 vsprintf(msg + strlen(msg), message, ap);
676 o = new_exception_message(utf_java_lang_ClassFormatError, msg);
678 MFREE(msg, char, msglen);
684 /* exceptions_throw_classnotfoundexception *************************************
686 Generates and throws a java.lang.ClassNotFoundException for the
690 name.........name of the class not found as a utf *
692 *******************************************************************************/
694 void exceptions_throw_classnotfoundexception(utf *name)
696 /* we use class here, as this one is rather frequent */
698 exceptions_throw_class_utf(class_java_lang_ClassNotFoundException, name);
702 /* exceptions_throw_noclassdeffounderror ***************************************
704 Generates and throws a java.lang.NoClassDefFoundError.
707 name.........name of the class not found as a utf *
709 *******************************************************************************/
711 void exceptions_throw_noclassdeffounderror(utf *name)
714 vm_abort("java.lang.NoClassDefFoundError: %s", name->text);
716 exceptions_throw_class_utf(class_java_lang_NoClassDefFoundError, name);
720 /* exceptions_throw_noclassdeffounderror_wrong_name ****************************
722 Generates and throws a java.lang.NoClassDefFoundError with a
728 name.........name of the class not found as a utf *
730 *******************************************************************************/
732 void exceptions_throw_noclassdeffounderror_wrong_name(classinfo *c, utf *name)
738 msglen = utf_bytes(c->name) + strlen(" (wrong name: ") +
739 utf_bytes(name) + strlen(")") + strlen("0");
741 msg = MNEW(char, msglen);
743 utf_copy_classname(msg, c->name);
744 strcat(msg, " (wrong name: ");
745 utf_cat_classname(msg, name);
748 u = utf_new_char(msg);
750 MFREE(msg, char, msglen);
752 exceptions_throw_noclassdeffounderror(u);
756 /* classnotfoundexception_to_noclassdeffounderror ******************************
758 Check the *exceptionptr for a ClassNotFoundException. If it is one,
759 convert it to a NoClassDefFoundError.
761 *******************************************************************************/
763 void classnotfoundexception_to_noclassdeffounderror(void)
765 java_objectheader *xptr;
766 java_objectheader *cause;
767 java_lang_Throwable *t;
772 cause = *exceptionptr;
774 /* convert ClassNotFoundException's to NoClassDefFoundError's */
776 if (builtin_instanceof(cause, class_java_lang_ClassNotFoundException)) {
777 /* clear exception, because we are calling jit code again */
779 *exceptionptr = NULL;
781 /* create new error */
783 t = (java_lang_Throwable *) cause;
784 s = t->detailMessage;
786 xptr = exceptions_new_utf_javastring(utf_java_lang_NoClassDefFoundError, s);
788 /* we had an exception while creating the error */
793 /* set new exception */
795 *exceptionptr = xptr;
800 /* exceptions_throw_exceptionininitializererror ********************************
802 Generates and throws a java.lang.ExceptionInInitializerError for
806 cause......cause exception object
808 *******************************************************************************/
810 void exceptions_throw_exceptionininitializererror(java_objectheader *cause)
812 exceptions_throw_utf_throwable(utf_java_lang_ExceptionInInitializerError,
817 /* exceptions_throw_incompatibleclasschangeerror *******************************
819 Generates and throws a java.lang.IncompatibleClassChangeError for
823 message......UTF-8 message format string
825 *******************************************************************************/
827 void exceptions_throw_incompatibleclasschangeerror(classinfo *c, const char *message)
829 java_objectheader *o;
833 /* calculate exception message length */
835 msglen = utf_bytes(c->name) + strlen(message) + strlen("0");
837 /* allocate memory */
839 msg = MNEW(char, msglen);
841 utf_copy_classname(msg, c->name);
842 strcat(msg, message);
844 o = native_new_and_init_string(utf_java_lang_IncompatibleClassChangeError,
845 javastring_new_from_utf_string(msg));
849 MFREE(msg, char, msglen);
858 /* exceptions_throw_instantiationerror *****************************************
860 Generates and throws a java.lang.InstantiationError for the VM.
862 *******************************************************************************/
864 void exceptions_throw_instantiationerror(classinfo *c)
866 exceptions_throw_utf_utf(utf_java_lang_InstantiationError, c->name);
870 /* exceptions_throw_internalerror **********************************************
872 Generates and throws a java.lang.InternalError for the VM.
875 message......UTF-8 message format string
877 *******************************************************************************/
879 void exceptions_throw_internalerror(const char *message, ...)
881 java_objectheader *o;
886 /* calculate exception message length */
888 va_start(ap, message);
889 msglen = get_variable_message_length(message, ap);
892 /* allocate memory */
894 msg = MNEW(char, msglen);
896 /* generate message */
898 va_start(ap, message);
899 vsprintf(msg, message, ap);
902 /* create exception object */
904 o = new_exception_message(utf_java_lang_InternalError, msg);
908 MFREE(msg, char, msglen);
917 /* exceptions_throw_linkageerror ***********************************************
919 Generates and throws java.lang.LinkageError with an error message.
922 message......UTF-8 message
923 c............class related to the error. If this is != NULL
924 the name of c is appended to the error message.
926 *******************************************************************************/
928 void exceptions_throw_linkageerror(const char *message, classinfo *c)
930 java_objectheader *o;
934 /* calculate exception message length */
936 msglen = strlen(message) + 1;
939 msglen += utf_bytes(c->name);
941 /* allocate memory */
943 msg = MNEW(char, msglen);
945 /* generate message */
950 utf_cat_classname(msg, c->name);
952 o = native_new_and_init_string(class_java_lang_LinkageError,
953 javastring_new_from_utf_string(msg));
957 MFREE(msg, char, msglen);
966 /* exceptions_throw_nosuchfielderror *******************************************
968 Generates and throws a java.lang.NoSuchFieldError with an error
972 c............class in which the field was not found
973 name.........name of the field
975 *******************************************************************************/
977 void exceptions_throw_nosuchfielderror(classinfo *c, utf *name)
983 /* calculate exception message length */
985 msglen = utf_bytes(c->name) + strlen(".") + utf_bytes(name) + strlen("0");
987 /* allocate memory */
989 msg = MNEW(char, msglen);
991 /* generate message */
993 utf_copy_classname(msg, c->name);
997 u = utf_new_char(msg);
1001 MFREE(msg, char, msglen);
1003 exceptions_throw_utf_utf(utf_java_lang_NoSuchFieldError, u);
1007 /* exceptions_throw_nosuchmethoderror ******************************************
1009 Generates and throws a java.lang.NoSuchMethodError with an error
1013 c............class in which the method was not found
1014 name.........name of the method
1015 desc.........descriptor of the method
1017 *******************************************************************************/
1019 void exceptions_throw_nosuchmethoderror(classinfo *c, utf *name, utf *desc)
1025 /* calculate exception message length */
1027 msglen = utf_bytes(c->name) + strlen(".") + utf_bytes(name) +
1028 utf_bytes(desc) + strlen("0");
1030 /* allocate memory */
1032 msg = MNEW(char, msglen);
1034 /* generate message */
1036 utf_copy_classname(msg, c->name);
1041 u = utf_new_char(msg);
1045 MFREE(msg, char, msglen);
1047 exceptions_throw_utf_utf(utf_java_lang_NoSuchMethodError, u);
1051 /* exceptions_throw_outofmemoryerror *******************************************
1053 Generates and throws an java.lang.OutOfMemoryError for the VM.
1055 *******************************************************************************/
1057 void exceptions_throw_outofmemoryerror(void)
1059 exceptions_throw_class(class_java_lang_OutOfMemoryError);
1063 /* exceptions_throw_unsatisfiedlinkerror ***************************************
1065 Generates and throws a java.lang.UnsatisfiedLinkError for the
1069 name......UTF-8 name string
1071 *******************************************************************************/
1073 void exceptions_throw_unsatisfiedlinkerror(utf *name)
1075 #if defined(ENABLE_JAVASE)
1076 exceptions_throw_utf_utf(utf_java_lang_UnsatisfiedLinkError, name);
1078 exceptions_throw_class_utf(class_java_lang_Error, name);
1083 /* exceptions_throw_unsupportedclassversionerror *******************************
1085 Generates and throws a java.lang.UnsupportedClassVersionError for
1089 c............class in which the method was not found
1090 message......UTF-8 format string
1092 *******************************************************************************/
1094 void exceptions_throw_unsupportedclassversionerror(classinfo *c, u4 ma, u4 mi)
1096 java_objectheader *o;
1100 /* calculate exception message length */
1103 utf_bytes(c->name) +
1104 strlen(" (Unsupported major.minor version 00.0)") +
1107 /* allocate memory */
1109 msg = MNEW(char, msglen);
1111 /* generate message */
1113 utf_copy_classname(msg, c->name);
1114 sprintf(msg + strlen(msg), " (Unsupported major.minor version %d.%d)",
1117 /* create exception object */
1119 o = new_exception_message(utf_java_lang_UnsupportedClassVersionError, msg);
1123 MFREE(msg, char, msglen);
1132 /* exceptions_throw_verifyerror ************************************************
1134 Generates and throws a java.lang.VerifyError for the JIT compiler.
1137 m............method in which the error was found
1138 message......UTF-8 format string
1140 *******************************************************************************/
1142 void exceptions_throw_verifyerror(methodinfo *m, const char *message, ...)
1144 java_objectheader *o;
1149 /* calculate exception message length */
1155 strlen("(class: ") + utf_bytes(m->class->name) +
1156 strlen(", method: ") + utf_bytes(m->name) +
1157 strlen(" signature: ") + utf_bytes(m->descriptor) +
1158 strlen(") ") + strlen("0");
1160 va_start(ap, message);
1161 msglen += get_variable_message_length(message, ap);
1164 /* allocate memory */
1166 msg = MNEW(char, msglen);
1168 /* generate message */
1171 strcpy(msg, "(class: ");
1172 utf_cat_classname(msg, m->class->name);
1173 strcat(msg, ", method: ");
1174 utf_cat(msg, m->name);
1175 strcat(msg, " signature: ");
1176 utf_cat(msg, m->descriptor);
1180 va_start(ap, message);
1181 vsprintf(msg + strlen(msg), message, ap);
1184 /* create exception object */
1186 o = new_exception_message(utf_java_lang_VerifyError, msg);
1190 MFREE(msg, char, msglen);
1196 /* exceptions_throw_verifyerror_for_stack **************************************
1198 throws a java.lang.VerifyError for an invalid stack slot type
1201 m............method in which the error was found
1202 type.........the expected type
1205 an exception pointer (in any case -- either it is the newly created
1206 exception, or an exception thrown while trying to create it).
1208 *******************************************************************************/
1210 void exceptions_throw_verifyerror_for_stack(methodinfo *m,int type)
1212 java_objectheader *o;
1217 /* calculate exception message length */
1222 msglen = strlen("(class: ") + utf_bytes(m->class->name) +
1223 strlen(", method: ") + utf_bytes(m->name) +
1224 strlen(" signature: ") + utf_bytes(m->descriptor) +
1225 strlen(") Expecting to find longest-------typename on stack")
1228 /* allocate memory */
1230 msg = MNEW(char, msglen);
1232 /* generate message */
1235 strcpy(msg, "(class: ");
1236 utf_cat_classname(msg, m->class->name);
1237 strcat(msg, ", method: ");
1238 utf_cat(msg, m->name);
1239 strcat(msg, " signature: ");
1240 utf_cat(msg, m->descriptor);
1247 strcat(msg,"Expecting to find ");
1249 case TYPE_INT: typename = "integer"; break;
1250 case TYPE_LNG: typename = "long"; break;
1251 case TYPE_FLT: typename = "float"; break;
1252 case TYPE_DBL: typename = "double"; break;
1253 case TYPE_ADR: typename = "object/array"; break;
1254 case TYPE_RET: typename = "returnAddress"; break;
1255 default: typename = "<INVALID>"; assert(0); break;
1257 strcat(msg, typename);
1258 strcat(msg, " on stack");
1260 /* create exception object */
1262 o = new_exception_message(utf_java_lang_VerifyError, msg);
1266 MFREE(msg, char, msglen);
1272 /* exceptions_new_arithmeticexception ******************************************
1274 Generates a java.lang.ArithmeticException for the JIT compiler.
1276 *******************************************************************************/
1278 java_objectheader *exceptions_new_arithmeticexception(void)
1280 java_objectheader *o;
1282 o = new_exception_message(utf_java_lang_ArithmeticException, "/ by zero");
1285 return *exceptionptr;
1291 /* exceptions_new_arrayindexoutofboundsexception *******************************
1293 Generates a java.lang.ArrayIndexOutOfBoundsException for the VM
1296 *******************************************************************************/
1298 java_objectheader *exceptions_new_arrayindexoutofboundsexception(s4 index)
1300 java_objectheader *o;
1302 java_objectheader *s;
1304 /* convert the index into a String, like Sun does */
1306 m = class_resolveclassmethod(class_java_lang_String,
1307 utf_new_char("valueOf"),
1308 utf_new_char("(I)Ljava/lang/String;"),
1309 class_java_lang_Object,
1313 return *exceptionptr;
1315 s = vm_call_method(m, NULL, index);
1318 return *exceptionptr;
1320 o = exceptions_new_utf_javastring(utf_java_lang_ArrayIndexOutOfBoundsException,
1324 return *exceptionptr;
1330 /* exceptions_throw_arrayindexoutofboundsexception *****************************
1332 Generates and throws a java.lang.ArrayIndexOutOfBoundsException for
1335 *******************************************************************************/
1337 void exceptions_throw_arrayindexoutofboundsexception(void)
1339 exceptions_throw_utf(utf_java_lang_ArrayIndexOutOfBoundsException);
1343 /* exceptions_throw_arraystoreexception ****************************************
1345 Generates and throws a java.lang.ArrayStoreException for the VM.
1347 *******************************************************************************/
1349 void exceptions_throw_arraystoreexception(void)
1351 exceptions_throw_utf(utf_java_lang_ArrayStoreException);
1352 /* e = native_new_and_init(class_java_lang_ArrayStoreException); */
1356 /* exceptions_new_classcastexception *******************************************
1358 Generates a java.lang.ClassCastException for the JIT compiler.
1360 *******************************************************************************/
1362 java_objectheader *exceptions_new_classcastexception(java_objectheader *o)
1364 java_objectheader *e;
1366 java_lang_String *s;
1368 classname = o->vftbl->class->name;
1370 s = javastring_new(classname);
1372 e = native_new_and_init_string(class_java_lang_ClassCastException, s);
1375 return *exceptionptr;
1381 /* exceptions_throw_clonenotsupportedexception *********************************
1383 Generates and throws a java.lang.CloneNotSupportedException for the
1386 *******************************************************************************/
1388 void exceptions_throw_clonenotsupportedexception(void)
1390 exceptions_throw_utf(utf_java_lang_CloneNotSupportedException);
1394 /* exceptions_throw_illegalaccessexception *************************************
1396 Generates and throws a java.lang.IllegalAccessException for the VM.
1398 *******************************************************************************/
1400 void exceptions_throw_illegalaccessexception(classinfo *c)
1402 /* XXX handle argument */
1404 exceptions_throw_utf(utf_java_lang_IllegalAccessException);
1408 /* exceptions_throw_illegalargumentexception ***********************************
1410 Generates and throws a java.lang.IllegalArgumentException for the
1413 *******************************************************************************/
1415 void exceptions_throw_illegalargumentexception(void)
1417 exceptions_throw_utf(utf_java_lang_IllegalArgumentException);
1421 /* exceptions_throw_illegalmonitorstateexception *******************************
1423 Generates and throws a java.lang.IllegalMonitorStateException for
1426 *******************************************************************************/
1428 void exceptions_throw_illegalmonitorstateexception(void)
1430 exceptions_throw_utf(utf_java_lang_IllegalMonitorStateException);
1434 /* exceptions_throw_instantiationexception *************************************
1436 Generates and throws a java.lang.InstantiationException for the VM.
1438 *******************************************************************************/
1440 void exceptions_throw_instantiationexception(classinfo *c)
1442 exceptions_throw_utf_utf(utf_java_lang_InstantiationException, c->name);
1446 /* exceptions_throw_interruptedexception ***************************************
1448 Generates and throws a java.lang.InterruptedException for the VM.
1450 *******************************************************************************/
1452 void exceptions_throw_interruptedexception(void)
1454 exceptions_throw_utf(utf_java_lang_InterruptedException);
1458 /* exceptions_throw_invocationtargetexception **********************************
1460 Generates and throws a java.lang.reflect.InvocationTargetException
1464 cause......cause exception object
1466 *******************************************************************************/
1468 void exceptions_throw_invocationtargetexception(java_objectheader *cause)
1470 exceptions_throw_utf_throwable(utf_java_lang_reflect_InvocationTargetException,
1475 /* exceptions_throw_negativearraysizeexception *********************************
1477 Generates and throws a java.lang.NegativeArraySizeException for the
1480 *******************************************************************************/
1482 void exceptions_throw_negativearraysizeexception(void)
1484 exceptions_throw_utf(utf_java_lang_NegativeArraySizeException);
1488 /* exceptions_new_nullpointerexception *****************************************
1490 Generates a java.lang.NullPointerException for the VM system.
1492 *******************************************************************************/
1494 java_objectheader *exceptions_new_nullpointerexception(void)
1496 java_objectheader *o;
1498 o = exceptions_new_class(class_java_lang_NullPointerException);
1504 /* exceptions_throw_nullpointerexception ***************************************
1506 Generates a java.lang.NullPointerException for the VM system and
1507 throw it in the VM system.
1509 *******************************************************************************/
1511 void exceptions_throw_nullpointerexception(void)
1513 exceptions_throw_class(class_java_lang_NullPointerException);
1517 /* exceptions_throw_stringindexoutofboundsexception ****************************
1519 Generates and throws a java.lang.StringIndexOutOfBoundsException
1522 *******************************************************************************/
1524 void exceptions_throw_stringindexoutofboundsexception(void)
1526 exceptions_throw_utf(utf_java_lang_StringIndexOutOfBoundsException);
1530 /* exceptions_get_exception ****************************************************
1532 Returns the current exception pointer of the current thread.
1534 *******************************************************************************/
1536 java_objectheader *exceptions_get_exception(void)
1538 /* return the exception */
1540 return *exceptionptr;
1544 /* exceptions_set_exception ****************************************************
1546 Sets the exception pointer of the current thread.
1548 *******************************************************************************/
1550 void exceptions_set_exception(java_objectheader *o)
1552 /* set the exception */
1558 /* exceptions_clear_exception **************************************************
1560 Clears the current exception pointer of the current thread.
1562 *******************************************************************************/
1564 void exceptions_clear_exception(void)
1566 /* and clear the exception */
1568 *exceptionptr = NULL;
1572 /* exceptions_fillinstacktrace *************************************************
1574 Calls the fillInStackTrace-method of the currently thrown
1577 *******************************************************************************/
1579 java_objectheader *exceptions_fillinstacktrace(void)
1581 java_objectheader *e;
1589 /* clear exception */
1591 *exceptionptr = NULL;
1593 /* resolve methodinfo pointer from exception object */
1595 m = class_resolvemethod(e->vftbl->class,
1596 utf_fillInStackTrace,
1597 utf_void__java_lang_Throwable);
1601 (void) vm_call_method(m, e);
1603 /* return exception object */
1609 /* exceptions_get_and_clear_exception ******************************************
1611 Gets the exception pointer of the current thread and clears it.
1612 This function may return NULL.
1614 *******************************************************************************/
1616 java_objectheader *exceptions_get_and_clear_exception(void)
1618 java_objectheader **p;
1619 java_objectheader *e;
1621 /* get the pointer of the exception pointer */
1625 /* get the exception */
1629 /* and clear the exception */
1633 /* return the exception */
1639 /* exceptions_new_hardware_exception *******************************************
1641 Creates the correct exception for a hardware-exception thrown and
1642 caught by a signal handler.
1644 *******************************************************************************/
1646 java_objectheader *exceptions_new_hardware_exception(u1 *pv, u1 *sp, u1 *ra, u1 *xpc, s4 type, ptrint val)
1649 java_objectheader *e;
1650 java_objectheader *o;
1653 /* create stackframeinfo */
1655 stacktrace_create_extern_stackframeinfo(&sfi, pv, sp, ra, xpc);
1658 case EXCEPTION_HARDWARE_NULLPOINTER:
1659 e = exceptions_new_nullpointerexception();
1662 case EXCEPTION_HARDWARE_ARITHMETIC:
1663 e = exceptions_new_arithmeticexception();
1666 case EXCEPTION_HARDWARE_ARRAYINDEXOUTOFBOUNDS:
1668 e = exceptions_new_arrayindexoutofboundsexception(index);
1671 case EXCEPTION_HARDWARE_CLASSCAST:
1672 o = (java_objectheader *) val;
1673 e = exceptions_new_classcastexception(o);
1676 case EXCEPTION_HARDWARE_EXCEPTION:
1677 e = exceptions_fillinstacktrace();
1681 /* let's try to get a backtrace */
1683 codegen_get_pv_from_pc(xpc);
1685 /* if that does not work, print more debug info */
1687 log_println("exceptions_new_hardware_exception: unknown exception type %d", type);
1689 #if SIZEOF_VOID_P == 8
1690 log_println("PC=0x%016lx", xpc);
1692 log_println("PC=0x%08x", xpc);
1695 #if defined(ENABLE_DISASSEMBLER)
1696 log_println("machine instruction at PC:");
1700 vm_abort("Exiting...");
1703 /* remove stackframeinfo */
1705 stacktrace_remove_stackframeinfo(&sfi);
1707 /* return the exception object */
1713 /* exceptions_handle_exception *************************************************
1715 Try to find an exception handler for the given exception and return it.
1716 If no handler is found, exit the monitor of the method (if any)
1720 xptr.........the exception object
1721 xpc..........PC of where the exception was thrown
1722 pv...........Procedure Value of the current method
1723 sp...........current stack pointer
1726 the address of the first matching exception handler, or
1727 NULL if no handler was found
1729 *******************************************************************************/
1731 #if defined(ENABLE_JIT)
1732 u1 *exceptions_handle_exception(java_objectheader *xptr, u1 *xpc, u1 *pv, u1 *sp)
1737 dseg_exception_entry *ex;
1738 s4 exceptiontablelength;
1740 classref_or_classinfo cr;
1742 #if defined(ENABLE_THREADS)
1743 java_objectheader *o;
1747 /* Addresses are 31 bit integers */
1748 # define ADDR_MASK(x) (u1 *)((u4)(x) & 0x7FFFFFFF)
1750 # define ADDR_MASK(x) (x)
1753 xpc = ADDR_MASK(xpc);
1755 /* get info from the method header */
1757 code = *((codeinfo **) (pv + CodeinfoPointer));
1758 issync = *((s4 *) (pv + IsSync));
1759 ex = (dseg_exception_entry *) (pv + ExTableStart);
1760 exceptiontablelength = *((s4 *) (pv + ExTableSize));
1762 /* Get the methodinfo pointer from the codeinfo pointer. For
1763 asm_vm_call_method the codeinfo pointer is NULL. */
1765 m = (code == NULL) ? NULL : code->m;
1767 #if !defined(NDEBUG)
1768 /* print exception trace */
1770 if (opt_verbose || opt_verbosecall || opt_verboseexception)
1771 builtin_trace_exception(xptr, m, xpc, 1);
1774 for (i = 0; i < exceptiontablelength; i++) {
1775 /* ATTENTION: keep this here, as we need to decrement the
1776 pointer before the loop executes! */
1780 /* If the start and end PC is NULL, this means we have the
1781 special case of asm_vm_call_method. So, just return the
1782 proper exception handler. */
1784 if ((ex->startpc == NULL) && (ex->endpc == NULL))
1785 return (u1 *) (ptrint) &asm_vm_call_method_exception_handler;
1787 /* is the xpc is the current catch range */
1789 if ((ADDR_MASK(ex->startpc) <= xpc) && (xpc < ADDR_MASK(ex->endpc))) {
1792 /* NULL catches everything */
1794 if (cr.any == NULL) {
1795 #if !defined(NDEBUG)
1796 /* Print stacktrace of exception when caught. */
1798 if (opt_verboseexception) {
1799 exceptions_print_exception(xptr);
1800 stacktrace_print_trace(xptr);
1804 return ex->handlerpc;
1807 /* resolve or load/link the exception class */
1809 if (IS_CLASSREF(cr)) {
1810 /* The exception class reference is unresolved. */
1811 /* We have to do _eager_ resolving here. While the class of */
1812 /* the exception object is guaranteed to be loaded, it may */
1813 /* well have been loaded by a different loader than the */
1814 /* defining loader of m's class, which is the one we must */
1815 /* use to resolve the catch class. Thus lazy resolving */
1816 /* might fail, even if the result of the resolution would */
1817 /* be an already loaded class. */
1819 c = resolve_classref_eager(cr.ref);
1822 /* Exception resolving the exception class, argh! */
1826 /* Ok, we resolved it. Enter it in the table, so we don't */
1827 /* have to do this again. */
1828 /* XXX this write should be atomic. Is it? */
1830 ex->catchtype.cls = c;
1834 /* XXX I don't think this case can ever happen. -Edwin */
1835 if (!(c->state & CLASS_LOADED))
1836 /* use the methods' classloader */
1837 if (!load_class_from_classloader(c->name,
1838 m->class->classloader))
1841 /* XXX I think, if it is not linked, we can be sure that */
1842 /* the exception object is no (indirect) instance of it, no? */
1844 if (!(c->state & CLASS_LINKED))
1849 /* is the thrown exception an instance of the catch class? */
1851 if (builtin_instanceof(xptr, c)) {
1852 #if !defined(NDEBUG)
1853 /* Print stacktrace of exception when caught. */
1855 if (opt_verboseexception) {
1856 exceptions_print_exception(xptr);
1857 stacktrace_print_trace(xptr);
1861 return ex->handlerpc;
1866 #if defined(ENABLE_THREADS)
1867 /* is this method synchronized? */
1870 /* get synchronization object */
1872 # if defined(__MIPS__) && (SIZEOF_VOID_P == 4)
1873 /* XXX change this if we ever want to use 4-byte stackslots */
1874 o = *((java_objectheader **) (sp + issync - 8));
1876 o = *((java_objectheader **) (sp + issync - SIZEOF_VOID_P));
1881 lock_monitor_exit(o);
1885 /* none of the exceptions catch this one */
1889 #endif /* defined(ENABLE_JIT) */
1892 /* exceptions_print_exception **************************************************
1894 Prints an exception, the detail message and the cause, if
1895 available, with CACAO internal functions to stdout.
1897 *******************************************************************************/
1899 void exceptions_print_exception(java_objectheader *xptr)
1901 java_lang_Throwable *t;
1902 #if defined(ENABLE_JAVASE)
1903 java_lang_Throwable *cause;
1907 t = (java_lang_Throwable *) xptr;
1914 #if defined(ENABLE_JAVASE)
1918 /* print the root exception */
1920 utf_display_printable_ascii_classname(t->header.vftbl->class->name);
1922 if (t->detailMessage != NULL) {
1923 u = javastring_toutf(t->detailMessage, false);
1926 utf_display_printable_ascii(u);
1931 #if defined(ENABLE_JAVASE)
1932 /* print the cause if available */
1934 if ((cause != NULL) && (cause != t)) {
1935 printf("Caused by: ");
1936 utf_display_printable_ascii_classname(cause->header.vftbl->class->name);
1938 if (cause->detailMessage) {
1939 u = javastring_toutf(cause->detailMessage, false);
1942 utf_display_printable_ascii(u);
1951 /* exceptions_print_current_exception ******************************************
1953 Prints the current pending exception, the detail message and the
1954 cause, if available, with CACAO internal functions to stdout.
1956 *******************************************************************************/
1958 void exceptions_print_current_exception(void)
1960 java_objectheader *xptr;
1962 xptr = *exceptionptr;
1964 exceptions_print_exception(xptr);
1968 /* exceptions_print_stacktrace *************************************************
1970 Prints a pending exception with Throwable.printStackTrace(). If
1971 there happens an exception during printStackTrace(), we print the
1972 thrown exception and the original one.
1974 NOTE: This function calls Java code.
1976 *******************************************************************************/
1978 void exceptions_print_stacktrace(void)
1980 java_objectheader *oxptr;
1981 java_objectheader *xptr;
1985 /* get original exception */
1987 oxptr = *exceptionptr;
1990 vm_abort("exceptions_print_stacktrace: no exception thrown");
1992 /* clear exception, because we are calling jit code again */
1994 *exceptionptr = NULL;
1996 c = oxptr->vftbl->class;
1998 /* find the printStackTrace() method */
2000 m = class_resolveclassmethod(c,
2001 utf_printStackTrace,
2003 class_java_lang_Object,
2007 vm_abort("exceptions_print_stacktrace: printStackTrace()V not found");
2009 /* print compatibility message */
2011 fprintf(stderr, "Exception in thread \"main\" ");
2013 /* print the stacktrace */
2015 (void) vm_call_method(m, oxptr);
2017 /* This normally means, we are EXTREMLY out of memory or
2018 have a serious problem while printStackTrace. But may
2019 be another exception, so print it. */
2021 xptr = *exceptionptr;
2024 fprintf(stderr, "Exception while printStackTrace(): ");
2026 /* now print original exception */
2028 exceptions_print_exception(xptr);
2029 stacktrace_print_trace(xptr);
2031 /* now print original exception */
2033 fprintf(stderr, "Original exception was: ");
2034 exceptions_print_exception(oxptr);
2035 stacktrace_print_trace(oxptr);
2043 * These are local overrides for various environment variables in Emacs.
2044 * Please do not remove this and leave it at the end of the file, where
2045 * Emacs will automagically detect them.
2046 * ---------------------------------------------------------------------
2049 * indent-tabs-mode: t
2053 * vim:noexpandtab:sw=4:ts=4: