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 8005 2007-06-04 13:12:56Z twisti $
43 #include "mm/memory.h"
45 #include "native/jni.h"
46 #include "native/native.h"
47 #include "native/include/java_lang_String.h"
48 #include "native/include/java_lang_Throwable.h"
50 #include "threads/lock-common.h"
51 #include "threads/threads-common.h"
53 #include "toolbox/logging.h"
54 #include "toolbox/util.h"
56 #include "vm/builtin.h"
57 #include "vm/exceptions.h"
58 #include "vm/global.h"
59 #include "vm/stringlocal.h"
62 #include "vm/jit/asmpart.h"
63 #include "vm/jit/disass.h"
64 #include "vm/jit/jit.h"
65 #include "vm/jit/methodheader.h"
66 #include "vm/jit/stacktrace.h"
68 #include "vmcore/class.h"
69 #include "vmcore/loader.h"
70 #include "vmcore/options.h"
72 #if defined(ENABLE_VMLOG)
73 #include <vmlog_cacao.h>
77 /* for raising exceptions from native methods *********************************/
79 #if !defined(ENABLE_THREADS)
80 java_objectheader *_no_threads_exceptionptr = NULL;
84 /* init_system_exceptions ******************************************************
86 Load and link exceptions used in the system.
88 *******************************************************************************/
90 bool exceptions_init(void)
94 /* mmap a memory page at address 0x0, so our hardware-exceptions
97 pagesize = getpagesize();
99 (void) memory_mmap_anon(NULL, pagesize, PROT_NONE, MAP_PRIVATE | MAP_FIXED);
101 /* check if we get into trouble with our hardware-exceptions */
103 if (OFFSET(java_bytearray, data) <= EXCEPTION_HARDWARE_PATCHER)
104 vm_abort("signal_init: array-data offset is less or equal the maximum hardware-exception displacement: %d <= %d", OFFSET(java_bytearray, data), EXCEPTION_HARDWARE_PATCHER);
106 /* java/lang/Throwable */
108 if (!(class_java_lang_Throwable =
109 load_class_bootstrap(utf_java_lang_Throwable)) ||
110 !link_class(class_java_lang_Throwable))
113 /* java/lang/Error */
115 if (!(class_java_lang_Error = load_class_bootstrap(utf_java_lang_Error)) ||
116 !link_class(class_java_lang_Error))
119 #if defined(ENABLE_JAVASE)
120 /* java/lang/LinkageError */
122 if (!(class_java_lang_LinkageError =
123 load_class_bootstrap(utf_java_lang_LinkageError)) ||
124 !link_class(class_java_lang_LinkageError))
128 /* java/lang/NoClassDefFoundError */
130 if (!(class_java_lang_NoClassDefFoundError =
131 load_class_bootstrap(utf_java_lang_NoClassDefFoundError)) ||
132 !link_class(class_java_lang_NoClassDefFoundError))
135 /* java/lang/OutOfMemoryError */
137 if (!(class_java_lang_OutOfMemoryError =
138 load_class_bootstrap(utf_java_lang_OutOfMemoryError)) ||
139 !link_class(class_java_lang_OutOfMemoryError))
142 /* java/lang/VirtualMachineError */
144 if (!(class_java_lang_VirtualMachineError =
145 load_class_bootstrap(utf_java_lang_VirtualMachineError)) ||
146 !link_class(class_java_lang_VirtualMachineError))
150 /* java/lang/Exception */
152 if (!(class_java_lang_Exception =
153 load_class_bootstrap(utf_java_lang_Exception)) ||
154 !link_class(class_java_lang_Exception))
157 /* java/lang/ClassCastException */
159 if (!(class_java_lang_ClassCastException =
160 load_class_bootstrap(utf_java_lang_ClassCastException)) ||
161 !link_class(class_java_lang_ClassCastException))
164 /* java/lang/ClassNotFoundException */
166 if (!(class_java_lang_ClassNotFoundException =
167 load_class_bootstrap(utf_java_lang_ClassNotFoundException)) ||
168 !link_class(class_java_lang_ClassNotFoundException))
171 /* java/lang/NullPointerException */
173 if (!(class_java_lang_NullPointerException =
174 load_class_bootstrap(utf_java_lang_NullPointerException)) ||
175 !link_class(class_java_lang_NullPointerException))
179 #if defined(WITH_CLASSPATH_GNU)
180 /* java/lang/VMThrowable */
182 if (!(class_java_lang_VMThrowable =
183 load_class_bootstrap(utf_java_lang_VMThrowable)) ||
184 !link_class(class_java_lang_VMThrowable))
192 /* exceptions_new_class ********************************************************
194 Creates an exception object from the given class and initalizes it.
197 class....class pointer
199 *******************************************************************************/
201 static java_objectheader *exceptions_new_class(classinfo *c)
203 java_objectheader *o;
205 o = native_new_and_init(c);
208 return *exceptionptr;
214 /* exceptions_new_utf **********************************************************
216 Creates an exception object with the given name and initalizes it.
219 classname....class name in UTF-8
221 *******************************************************************************/
223 static java_objectheader *exceptions_new_utf(utf *classname)
226 java_objectheader *o;
228 c = load_class_bootstrap(classname);
231 return *exceptionptr;
233 o = exceptions_new_class(c);
239 /* exceptions_throw_class ******************************************************
241 Creates an exception object from the given class, initalizes and
245 class....class pointer
247 *******************************************************************************/
249 static void exceptions_throw_class(classinfo *c)
251 java_objectheader *o;
253 o = exceptions_new_class(c);
262 /* exceptions_throw_utf ********************************************************
264 Creates an exception object with the given name, initalizes and
268 classname....class name in UTF-8
270 *******************************************************************************/
272 static void exceptions_throw_utf(utf *classname)
276 c = load_class_bootstrap(classname);
281 exceptions_throw_class(c);
285 /* exceptions_throw_utf_throwable **********************************************
287 Creates an exception object with the given name and initalizes it
288 with the given java/lang/Throwable exception.
291 classname....class name in UTF-8
292 cause........the given Throwable
294 *******************************************************************************/
296 static void exceptions_throw_utf_throwable(utf *classname,
297 java_objectheader *cause)
299 java_objectheader *o;
302 c = load_class_bootstrap(classname);
307 o = native_new_and_init_throwable(c, cause);
316 /* exceptions_new_utf_javastring ***********************************************
318 Creates an exception object with the given name and initalizes it
319 with the given java/lang/String message.
322 classname....class name in UTF-8
323 message......the message as a java.lang.String
326 an exception pointer (in any case -- either it is the newly created
327 exception, or an exception thrown while trying to create it).
329 *******************************************************************************/
331 static java_objectheader *exceptions_new_utf_javastring(utf *classname,
332 java_objectheader *message)
334 java_objectheader *o;
337 c = load_class_bootstrap(classname);
340 return *exceptionptr;
342 o = native_new_and_init_string(c, message);
345 return *exceptionptr;
351 /* exceptions_new_class_utf ****************************************************
353 Creates an exception object of the given class and initalizes it.
356 c..........class pointer
357 message....the message as UTF-8 string
359 *******************************************************************************/
361 static java_objectheader *exceptions_new_class_utf(classinfo *c, utf *message)
363 java_objectheader *o;
364 java_objectheader *s;
366 s = javastring_new(message);
369 return *exceptionptr;
371 o = native_new_and_init_string(c, s);
374 return *exceptionptr;
380 /* exceptions_new_utf_utf ******************************************************
382 Creates an exception object with the given name and initalizes it
383 with the given utf message.
386 classname....class name in UTF-8
387 message......the message as an utf *
390 an exception pointer (in any case -- either it is the newly created
391 exception, or an exception thrown while trying to create it).
393 *******************************************************************************/
395 static java_objectheader *exceptions_new_utf_utf(utf *classname, utf *message)
398 java_objectheader *o;
400 c = load_class_bootstrap(classname);
403 return *exceptionptr;
405 o = exceptions_new_class_utf(c, message);
411 /* exceptions_throw_class_utf **************************************************
413 Creates an exception object of the given class, initalizes and
414 throws it with the given utf message.
417 c..........class pointer
418 message....the message as an UTF-8
420 *******************************************************************************/
422 static void exceptions_throw_class_utf(classinfo *c, utf *message)
424 *exceptionptr = exceptions_new_class_utf(c, message);
428 /* exceptions_throw_utf_utf ****************************************************
430 Creates an exception object with the given name, initalizes and
431 throws it with the given utf message.
434 classname....class name in UTF-8
435 message......the message as an utf *
437 *******************************************************************************/
439 static void exceptions_throw_utf_utf(utf *classname, utf *message)
441 *exceptionptr = exceptions_new_utf_utf(classname, message);
445 /* exceptions_new_abstractmethoderror ****************************************
447 Generates a java.lang.AbstractMethodError for the VM.
449 *******************************************************************************/
451 java_objectheader *exceptions_new_abstractmethoderror(void)
453 java_objectheader *o;
455 o = exceptions_new_utf(utf_java_lang_AbstractMethodError);
461 /* exceptions_new_error ********************************************************
463 Generates a java.lang.Error for the VM.
465 *******************************************************************************/
467 #if defined(ENABLE_JAVAME_CLDC1_1)
468 static java_objectheader *exceptions_new_error(utf *message)
470 java_objectheader *o;
472 o = exceptions_new_class_utf(class_java_lang_Error, message);
479 /* exceptions_asm_new_abstractmethoderror **************************************
481 Generates a java.lang.AbstractMethodError for
482 asm_abstractmethoderror.
484 *******************************************************************************/
486 java_objectheader *exceptions_asm_new_abstractmethoderror(u1 *sp, u1 *ra)
489 java_objectheader *e;
491 /* create the stackframeinfo (XPC is equal to RA) */
493 stacktrace_create_extern_stackframeinfo(&sfi, NULL, sp, ra, ra);
495 /* create the exception */
497 #if defined(ENABLE_JAVASE)
498 e = exceptions_new_abstractmethoderror();
500 e = exceptions_new_error(utf_java_lang_AbstractMethodError);
503 /* remove the stackframeinfo */
505 stacktrace_remove_stackframeinfo(&sfi);
511 /* exceptions_new_arraystoreexception ******************************************
513 Generates a java.lang.ArrayStoreException for the VM.
515 *******************************************************************************/
517 java_objectheader *exceptions_new_arraystoreexception(void)
519 java_objectheader *o;
521 o = exceptions_new_utf(utf_java_lang_ArrayStoreException);
527 /* exceptions_throw_abstractmethoderror ****************************************
529 Generates and throws a java.lang.AbstractMethodError for the VM.
531 *******************************************************************************/
533 void exceptions_throw_abstractmethoderror(void)
535 exceptions_throw_utf(utf_java_lang_AbstractMethodError);
539 /* exceptions_throw_classcircularityerror **************************************
541 Generates and throws a java.lang.ClassCircularityError for the
545 c....the class in which the error was found
547 *******************************************************************************/
549 void exceptions_throw_classcircularityerror(classinfo *c)
551 exceptions_throw_utf_utf(utf_java_lang_ClassCircularityError, c->name);
555 /* exceptions_throw_classformaterror *******************************************
557 Generates and throws a java.lang.ClassFormatError for the VM.
560 c............the class in which the error was found
561 message......UTF-8 format string
563 *******************************************************************************/
565 void exceptions_throw_classformaterror(classinfo *c, const char *message, ...)
572 /* calculate message length */
577 msglen += utf_bytes(c->name) + strlen(" (");
579 va_start(ap, message);
580 msglen += get_variable_message_length(message, ap);
584 msglen += strlen(")");
586 msglen += strlen("0");
588 /* allocate a buffer */
590 msg = MNEW(char, msglen);
592 /* print message into allocated buffer */
595 utf_copy_classname(msg, c->name);
599 va_start(ap, message);
600 vsprintf(msg + strlen(msg), message, ap);
606 u = utf_new_char(msg);
610 MFREE(msg, char, msglen);
612 /* throw exception */
614 exceptions_throw_utf_utf(utf_java_lang_ClassFormatError, u);
618 /* exceptions_throw_classnotfoundexception *************************************
620 Generates and throws a java.lang.ClassNotFoundException for the
624 name.........name of the class not found as a utf *
626 *******************************************************************************/
628 void exceptions_throw_classnotfoundexception(utf *name)
630 /* we use class here, as this one is rather frequent */
632 exceptions_throw_class_utf(class_java_lang_ClassNotFoundException, name);
636 /* exceptions_throw_noclassdeffounderror ***************************************
638 Generates and throws a java.lang.NoClassDefFoundError.
641 name.........name of the class not found as a utf *
643 *******************************************************************************/
645 void exceptions_throw_noclassdeffounderror(utf *name)
648 vm_abort("java.lang.NoClassDefFoundError: %s", name->text);
650 exceptions_throw_class_utf(class_java_lang_NoClassDefFoundError, name);
654 /* exceptions_throw_noclassdeffounderror_wrong_name ****************************
656 Generates and throws a java.lang.NoClassDefFoundError with a
662 name.........name of the class not found as a utf *
664 *******************************************************************************/
666 void exceptions_throw_noclassdeffounderror_wrong_name(classinfo *c, utf *name)
672 msglen = utf_bytes(c->name) + strlen(" (wrong name: ") +
673 utf_bytes(name) + strlen(")") + strlen("0");
675 msg = MNEW(char, msglen);
677 utf_copy_classname(msg, c->name);
678 strcat(msg, " (wrong name: ");
679 utf_cat_classname(msg, name);
682 u = utf_new_char(msg);
684 MFREE(msg, char, msglen);
686 exceptions_throw_noclassdeffounderror(u);
690 /* classnotfoundexception_to_noclassdeffounderror ******************************
692 Check the *exceptionptr for a ClassNotFoundException. If it is one,
693 convert it to a NoClassDefFoundError.
695 *******************************************************************************/
697 void classnotfoundexception_to_noclassdeffounderror(void)
699 java_objectheader *xptr;
700 java_objectheader *cause;
701 java_lang_Throwable *t;
702 java_objectheader *s;
706 cause = *exceptionptr;
708 /* convert ClassNotFoundException's to NoClassDefFoundError's */
710 if (builtin_instanceof(cause, class_java_lang_ClassNotFoundException)) {
711 /* clear exception, because we are calling jit code again */
713 *exceptionptr = NULL;
715 /* create new error */
717 t = (java_lang_Throwable *) cause;
718 s = (java_objectheader *) t->detailMessage;
720 xptr = exceptions_new_utf_javastring(utf_java_lang_NoClassDefFoundError,
723 /* we had an exception while creating the error */
728 /* set new exception */
730 *exceptionptr = xptr;
735 /* exceptions_throw_exceptionininitializererror ********************************
737 Generates and throws a java.lang.ExceptionInInitializerError for
741 cause......cause exception object
743 *******************************************************************************/
745 void exceptions_throw_exceptionininitializererror(java_objectheader *cause)
747 exceptions_throw_utf_throwable(utf_java_lang_ExceptionInInitializerError,
752 /* exceptions_throw_incompatibleclasschangeerror *******************************
754 Generates and throws a java.lang.IncompatibleClassChangeError for
758 message......UTF-8 message format string
760 *******************************************************************************/
762 void exceptions_throw_incompatibleclasschangeerror(classinfo *c, const char *message)
768 /* calculate exception message length */
770 msglen = utf_bytes(c->name) + strlen(message) + strlen("0");
772 /* allocate memory */
774 msg = MNEW(char, msglen);
776 utf_copy_classname(msg, c->name);
777 strcat(msg, message);
779 u = utf_new_char(msg);
783 MFREE(msg, char, msglen);
785 /* throw exception */
787 exceptions_throw_utf_utf(utf_java_lang_IncompatibleClassChangeError, u);
791 /* exceptions_throw_instantiationerror *****************************************
793 Generates and throws a java.lang.InstantiationError for the VM.
795 *******************************************************************************/
797 void exceptions_throw_instantiationerror(classinfo *c)
799 exceptions_throw_utf_utf(utf_java_lang_InstantiationError, c->name);
803 /* exceptions_throw_internalerror **********************************************
805 Generates and throws a java.lang.InternalError for the VM.
808 message......UTF-8 message format string
810 *******************************************************************************/
812 void exceptions_throw_internalerror(const char *message, ...)
819 /* calculate exception message length */
821 va_start(ap, message);
822 msglen = get_variable_message_length(message, ap);
825 /* allocate memory */
827 msg = MNEW(char, msglen);
829 /* generate message */
831 va_start(ap, message);
832 vsprintf(msg, message, ap);
835 u = utf_new_char(msg);
839 MFREE(msg, char, msglen);
841 /* throw exception */
843 exceptions_throw_utf_utf(utf_java_lang_InternalError, u);
847 /* exceptions_throw_linkageerror ***********************************************
849 Generates and throws java.lang.LinkageError with an error message.
852 message......UTF-8 message
853 c............class related to the error. If this is != NULL
854 the name of c is appended to the error message.
856 *******************************************************************************/
858 void exceptions_throw_linkageerror(const char *message, classinfo *c)
860 java_objectheader *o;
864 /* calculate exception message length */
866 msglen = strlen(message) + 1;
869 msglen += utf_bytes(c->name);
871 /* allocate memory */
873 msg = MNEW(char, msglen);
875 /* generate message */
880 utf_cat_classname(msg, c->name);
882 o = native_new_and_init_string(class_java_lang_LinkageError,
883 javastring_new_from_utf_string(msg));
887 MFREE(msg, char, msglen);
896 /* exceptions_throw_nosuchfielderror *******************************************
898 Generates and throws a java.lang.NoSuchFieldError with an error
902 c............class in which the field was not found
903 name.........name of the field
905 *******************************************************************************/
907 void exceptions_throw_nosuchfielderror(classinfo *c, utf *name)
913 /* calculate exception message length */
915 msglen = utf_bytes(c->name) + strlen(".") + utf_bytes(name) + strlen("0");
917 /* allocate memory */
919 msg = MNEW(char, msglen);
921 /* generate message */
923 utf_copy_classname(msg, c->name);
927 u = utf_new_char(msg);
931 MFREE(msg, char, msglen);
933 exceptions_throw_utf_utf(utf_java_lang_NoSuchFieldError, u);
937 /* exceptions_throw_nosuchmethoderror ******************************************
939 Generates and throws a java.lang.NoSuchMethodError with an error
943 c............class in which the method was not found
944 name.........name of the method
945 desc.........descriptor of the method
947 *******************************************************************************/
949 void exceptions_throw_nosuchmethoderror(classinfo *c, utf *name, utf *desc)
955 /* calculate exception message length */
957 msglen = utf_bytes(c->name) + strlen(".") + utf_bytes(name) +
958 utf_bytes(desc) + strlen("0");
960 /* allocate memory */
962 msg = MNEW(char, msglen);
964 /* generate message */
966 utf_copy_classname(msg, c->name);
971 u = utf_new_char(msg);
975 MFREE(msg, char, msglen);
977 #if defined(ENABLE_JAVASE)
978 exceptions_throw_utf_utf(utf_java_lang_NoSuchMethodError, u);
980 exceptions_throw_class_utf(class_java_lang_Error, u);
985 /* exceptions_throw_outofmemoryerror *******************************************
987 Generates and throws an java.lang.OutOfMemoryError for the VM.
989 *******************************************************************************/
991 void exceptions_throw_outofmemoryerror(void)
993 exceptions_throw_class(class_java_lang_OutOfMemoryError);
997 /* exceptions_throw_unsatisfiedlinkerror ***************************************
999 Generates and throws a java.lang.UnsatisfiedLinkError for the
1003 name......UTF-8 name string
1005 *******************************************************************************/
1007 void exceptions_throw_unsatisfiedlinkerror(utf *name)
1009 #if defined(ENABLE_JAVASE)
1010 exceptions_throw_utf_utf(utf_java_lang_UnsatisfiedLinkError, name);
1012 exceptions_throw_class_utf(class_java_lang_Error, name);
1017 /* exceptions_throw_unsupportedclassversionerror *******************************
1019 Generates and throws a java.lang.UnsupportedClassVersionError for
1023 c............class in which the method was not found
1024 message......UTF-8 format string
1026 *******************************************************************************/
1028 void exceptions_throw_unsupportedclassversionerror(classinfo *c, u4 ma, u4 mi)
1034 /* calculate exception message length */
1037 utf_bytes(c->name) +
1038 strlen(" (Unsupported major.minor version 00.0)") +
1041 /* allocate memory */
1043 msg = MNEW(char, msglen);
1045 /* generate message */
1047 utf_copy_classname(msg, c->name);
1048 sprintf(msg + strlen(msg), " (Unsupported major.minor version %d.%d)",
1051 u = utf_new_char(msg);
1055 MFREE(msg, char, msglen);
1057 /* throw exception */
1059 exceptions_throw_utf_utf(utf_java_lang_UnsupportedClassVersionError, u);
1063 /* exceptions_throw_verifyerror ************************************************
1065 Generates and throws a java.lang.VerifyError for the JIT compiler.
1068 m............method in which the error was found
1069 message......UTF-8 format string
1071 *******************************************************************************/
1073 void exceptions_throw_verifyerror(methodinfo *m, const char *message, ...)
1080 /* calculate exception message length */
1086 strlen("(class: ") + utf_bytes(m->class->name) +
1087 strlen(", method: ") + utf_bytes(m->name) +
1088 strlen(" signature: ") + utf_bytes(m->descriptor) +
1089 strlen(") ") + strlen("0");
1091 va_start(ap, message);
1092 msglen += get_variable_message_length(message, ap);
1095 /* allocate memory */
1097 msg = MNEW(char, msglen);
1099 /* generate message */
1102 strcpy(msg, "(class: ");
1103 utf_cat_classname(msg, m->class->name);
1104 strcat(msg, ", method: ");
1105 utf_cat(msg, m->name);
1106 strcat(msg, " signature: ");
1107 utf_cat(msg, m->descriptor);
1111 va_start(ap, message);
1112 vsprintf(msg + strlen(msg), message, ap);
1115 u = utf_new_char(msg);
1119 MFREE(msg, char, msglen);
1121 /* throw exception */
1123 exceptions_throw_utf_utf(utf_java_lang_VerifyError, u);
1127 /* exceptions_throw_verifyerror_for_stack **************************************
1129 throws a java.lang.VerifyError for an invalid stack slot type
1132 m............method in which the error was found
1133 type.........the expected type
1136 an exception pointer (in any case -- either it is the newly created
1137 exception, or an exception thrown while trying to create it).
1139 *******************************************************************************/
1141 void exceptions_throw_verifyerror_for_stack(methodinfo *m, int type)
1148 /* calculate exception message length */
1153 msglen = strlen("(class: ") + utf_bytes(m->class->name) +
1154 strlen(", method: ") + utf_bytes(m->name) +
1155 strlen(" signature: ") + utf_bytes(m->descriptor) +
1156 strlen(") Expecting to find longest-------typename on stack")
1159 /* allocate memory */
1161 msg = MNEW(char, msglen);
1163 /* generate message */
1166 strcpy(msg, "(class: ");
1167 utf_cat_classname(msg, m->class->name);
1168 strcat(msg, ", method: ");
1169 utf_cat(msg, m->name);
1170 strcat(msg, " signature: ");
1171 utf_cat(msg, m->descriptor);
1178 strcat(msg, "Expecting to find ");
1181 case TYPE_INT: typename = "integer"; break;
1182 case TYPE_LNG: typename = "long"; break;
1183 case TYPE_FLT: typename = "float"; break;
1184 case TYPE_DBL: typename = "double"; break;
1185 case TYPE_ADR: typename = "object/array"; break;
1186 case TYPE_RET: typename = "returnAddress"; break;
1187 default: typename = "<INVALID>"; assert(0); break;
1190 strcat(msg, typename);
1191 strcat(msg, " on stack");
1193 u = utf_new_char(msg);
1197 MFREE(msg, char, msglen);
1199 /* throw exception */
1201 exceptions_throw_utf_utf(utf_java_lang_VerifyError, u);
1205 /* exceptions_new_arithmeticexception ******************************************
1207 Generates a java.lang.ArithmeticException for the JIT compiler.
1209 *******************************************************************************/
1211 java_objectheader *exceptions_new_arithmeticexception(void)
1213 java_objectheader *o;
1215 o = exceptions_new_utf_utf(utf_java_lang_ArithmeticException,
1216 utf_division_by_zero);
1222 /* exceptions_new_arrayindexoutofboundsexception *******************************
1224 Generates a java.lang.ArrayIndexOutOfBoundsException for the VM
1227 *******************************************************************************/
1229 java_objectheader *exceptions_new_arrayindexoutofboundsexception(s4 index)
1231 java_objectheader *o;
1233 java_objectheader *s;
1235 /* convert the index into a String, like Sun does */
1237 m = class_resolveclassmethod(class_java_lang_String,
1238 utf_new_char("valueOf"),
1239 utf_new_char("(I)Ljava/lang/String;"),
1240 class_java_lang_Object,
1244 return *exceptionptr;
1246 s = vm_call_method(m, NULL, index);
1249 return *exceptionptr;
1251 o = exceptions_new_utf_javastring(utf_java_lang_ArrayIndexOutOfBoundsException,
1255 return *exceptionptr;
1261 /* exceptions_throw_arrayindexoutofboundsexception *****************************
1263 Generates and throws a java.lang.ArrayIndexOutOfBoundsException for
1266 *******************************************************************************/
1268 void exceptions_throw_arrayindexoutofboundsexception(void)
1270 exceptions_throw_utf(utf_java_lang_ArrayIndexOutOfBoundsException);
1274 /* exceptions_throw_arraystoreexception ****************************************
1276 Generates and throws a java.lang.ArrayStoreException for the VM.
1278 *******************************************************************************/
1280 void exceptions_throw_arraystoreexception(void)
1282 exceptions_throw_utf(utf_java_lang_ArrayStoreException);
1283 /* e = native_new_and_init(class_java_lang_ArrayStoreException); */
1287 /* exceptions_new_classcastexception *******************************************
1289 Generates a java.lang.ClassCastException for the JIT compiler.
1291 *******************************************************************************/
1293 java_objectheader *exceptions_new_classcastexception(java_objectheader *o)
1295 java_objectheader *e;
1298 classname = o->vftbl->class->name;
1300 e = exceptions_new_class_utf(class_java_lang_ClassCastException, classname);
1306 /* exceptions_throw_clonenotsupportedexception *********************************
1308 Generates and throws a java.lang.CloneNotSupportedException for the
1311 *******************************************************************************/
1313 void exceptions_throw_clonenotsupportedexception(void)
1315 exceptions_throw_utf(utf_java_lang_CloneNotSupportedException);
1319 /* exceptions_throw_illegalaccessexception *************************************
1321 Generates and throws a java.lang.IllegalAccessException for the VM.
1323 *******************************************************************************/
1325 void exceptions_throw_illegalaccessexception(utf *message)
1327 exceptions_throw_utf_utf(utf_java_lang_IllegalAccessException, message);
1331 /* exceptions_throw_illegalargumentexception ***********************************
1333 Generates and throws a java.lang.IllegalArgumentException for the
1336 *******************************************************************************/
1338 void exceptions_throw_illegalargumentexception(void)
1340 exceptions_throw_utf(utf_java_lang_IllegalArgumentException);
1344 /* exceptions_throw_illegalmonitorstateexception *******************************
1346 Generates and throws a java.lang.IllegalMonitorStateException for
1349 *******************************************************************************/
1351 void exceptions_throw_illegalmonitorstateexception(void)
1353 exceptions_throw_utf(utf_java_lang_IllegalMonitorStateException);
1357 /* exceptions_throw_instantiationexception *************************************
1359 Generates and throws a java.lang.InstantiationException for the VM.
1361 *******************************************************************************/
1363 void exceptions_throw_instantiationexception(classinfo *c)
1365 exceptions_throw_utf_utf(utf_java_lang_InstantiationException, c->name);
1369 /* exceptions_throw_interruptedexception ***************************************
1371 Generates and throws a java.lang.InterruptedException for the VM.
1373 *******************************************************************************/
1375 void exceptions_throw_interruptedexception(void)
1377 exceptions_throw_utf(utf_java_lang_InterruptedException);
1381 /* exceptions_throw_invocationtargetexception **********************************
1383 Generates and throws a java.lang.reflect.InvocationTargetException
1387 cause......cause exception object
1389 *******************************************************************************/
1391 void exceptions_throw_invocationtargetexception(java_objectheader *cause)
1393 exceptions_throw_utf_throwable(utf_java_lang_reflect_InvocationTargetException,
1398 /* exceptions_throw_negativearraysizeexception *********************************
1400 Generates and throws a java.lang.NegativeArraySizeException for the
1403 *******************************************************************************/
1405 void exceptions_throw_negativearraysizeexception(void)
1407 exceptions_throw_utf(utf_java_lang_NegativeArraySizeException);
1411 /* exceptions_new_nullpointerexception *****************************************
1413 Generates a java.lang.NullPointerException for the VM system.
1415 *******************************************************************************/
1417 java_objectheader *exceptions_new_nullpointerexception(void)
1419 java_objectheader *o;
1421 o = exceptions_new_class(class_java_lang_NullPointerException);
1427 /* exceptions_throw_nullpointerexception ***************************************
1429 Generates a java.lang.NullPointerException for the VM system and
1430 throw it in the VM system.
1432 *******************************************************************************/
1434 void exceptions_throw_nullpointerexception(void)
1436 exceptions_throw_class(class_java_lang_NullPointerException);
1440 /* exceptions_throw_stringindexoutofboundsexception ****************************
1442 Generates and throws a java.lang.StringIndexOutOfBoundsException
1445 *******************************************************************************/
1447 void exceptions_throw_stringindexoutofboundsexception(void)
1449 exceptions_throw_utf(utf_java_lang_StringIndexOutOfBoundsException);
1453 /* exceptions_get_exception ****************************************************
1455 Returns the current exception pointer of the current thread.
1457 *******************************************************************************/
1459 java_objectheader *exceptions_get_exception(void)
1461 /* return the exception */
1463 return *exceptionptr;
1467 /* exceptions_set_exception ****************************************************
1469 Sets the exception pointer of the current thread.
1471 *******************************************************************************/
1473 void exceptions_set_exception(java_objectheader *o)
1475 /* set the exception */
1481 /* exceptions_clear_exception **************************************************
1483 Clears the current exception pointer of the current thread.
1485 *******************************************************************************/
1487 void exceptions_clear_exception(void)
1489 /* and clear the exception */
1491 *exceptionptr = NULL;
1495 /* exceptions_fillinstacktrace *************************************************
1497 Calls the fillInStackTrace-method of the currently thrown
1500 *******************************************************************************/
1502 java_objectheader *exceptions_fillinstacktrace(void)
1504 java_objectheader *o;
1512 /* clear exception */
1514 *exceptionptr = NULL;
1516 /* resolve methodinfo pointer from exception object */
1518 #if defined(ENABLE_JAVASE)
1519 m = class_resolvemethod(o->vftbl->class,
1520 utf_fillInStackTrace,
1521 utf_void__java_lang_Throwable);
1522 #elif defined(ENABLE_JAVAME_CLDC1_1)
1523 m = class_resolvemethod(o->vftbl->class,
1524 utf_fillInStackTrace,
1527 #error IMPLEMENT ME!
1532 (void) vm_call_method(m, o);
1534 /* return exception object */
1540 /* exceptions_get_and_clear_exception ******************************************
1542 Gets the exception pointer of the current thread and clears it.
1543 This function may return NULL.
1545 *******************************************************************************/
1547 java_objectheader *exceptions_get_and_clear_exception(void)
1549 java_objectheader **p;
1550 java_objectheader *e;
1552 /* get the pointer of the exception pointer */
1556 /* get the exception */
1560 /* and clear the exception */
1564 /* return the exception */
1570 /* exceptions_new_hardware_exception *******************************************
1572 Creates the correct exception for a hardware-exception thrown and
1573 caught by a signal handler.
1575 *******************************************************************************/
1577 java_objectheader *exceptions_new_hardware_exception(u1 *pv, u1 *sp, u1 *ra, u1 *xpc, s4 type, ptrint val)
1580 java_objectheader *e;
1581 java_objectheader *o;
1584 /* create stackframeinfo */
1586 stacktrace_create_extern_stackframeinfo(&sfi, pv, sp, ra, xpc);
1589 case EXCEPTION_HARDWARE_NULLPOINTER:
1590 e = exceptions_new_nullpointerexception();
1593 case EXCEPTION_HARDWARE_ARITHMETIC:
1594 e = exceptions_new_arithmeticexception();
1597 case EXCEPTION_HARDWARE_ARRAYINDEXOUTOFBOUNDS:
1599 e = exceptions_new_arrayindexoutofboundsexception(index);
1602 case EXCEPTION_HARDWARE_CLASSCAST:
1603 o = (java_objectheader *) val;
1604 e = exceptions_new_classcastexception(o);
1607 case EXCEPTION_HARDWARE_EXCEPTION:
1608 e = exceptions_fillinstacktrace();
1612 /* let's try to get a backtrace */
1614 codegen_get_pv_from_pc(xpc);
1616 /* if that does not work, print more debug info */
1618 log_println("exceptions_new_hardware_exception: unknown exception type %d", type);
1620 #if SIZEOF_VOID_P == 8
1621 log_println("PC=0x%016lx", xpc);
1623 log_println("PC=0x%08x", xpc);
1626 #if defined(ENABLE_DISASSEMBLER)
1627 log_println("machine instruction at PC:");
1631 vm_abort("Exiting...");
1633 /* keep compiler happy */
1638 /* remove stackframeinfo */
1640 stacktrace_remove_stackframeinfo(&sfi);
1642 /* return the exception object */
1648 /* exceptions_handle_exception *************************************************
1650 Try to find an exception handler for the given exception and return it.
1651 If no handler is found, exit the monitor of the method (if any)
1655 xptr.........the exception object
1656 xpc..........PC of where the exception was thrown
1657 pv...........Procedure Value of the current method
1658 sp...........current stack pointer
1661 the address of the first matching exception handler, or
1662 NULL if no handler was found
1664 *******************************************************************************/
1666 #if defined(ENABLE_JIT)
1667 u1 *exceptions_handle_exception(java_objectheader *xptr, u1 *xpc, u1 *pv, u1 *sp)
1672 dseg_exception_entry *ex;
1673 s4 exceptiontablelength;
1675 classref_or_classinfo cr;
1677 #if defined(ENABLE_THREADS)
1678 java_objectheader *o;
1682 /* Addresses are 31 bit integers */
1683 # define ADDR_MASK(x) (u1 *)((u4)(x) & 0x7FFFFFFF)
1685 # define ADDR_MASK(x) (x)
1688 xpc = ADDR_MASK(xpc);
1690 /* get info from the method header */
1692 code = *((codeinfo **) (pv + CodeinfoPointer));
1693 issync = *((s4 *) (pv + IsSync));
1694 ex = (dseg_exception_entry *) (pv + ExTableStart);
1695 exceptiontablelength = *((s4 *) (pv + ExTableSize));
1697 /* Get the methodinfo pointer from the codeinfo pointer. For
1698 asm_vm_call_method the codeinfo pointer is NULL. */
1700 m = (code == NULL) ? NULL : code->m;
1702 #if !defined(NDEBUG)
1703 /* print exception trace */
1705 if (opt_verbose || opt_verbosecall || opt_verboseexception)
1706 builtin_trace_exception(xptr, m, xpc, 1);
1709 #if defined(ENABLE_VMLOG)
1710 vmlog_cacao_throw(xptr);
1713 for (i = 0; i < exceptiontablelength; i++) {
1714 /* ATTENTION: keep this here, as we need to decrement the
1715 pointer before the loop executes! */
1719 /* If the start and end PC is NULL, this means we have the
1720 special case of asm_vm_call_method. So, just return the
1721 proper exception handler. */
1723 if ((ex->startpc == NULL) && (ex->endpc == NULL))
1724 return (u1 *) (ptrint) &asm_vm_call_method_exception_handler;
1726 /* is the xpc is the current catch range */
1728 if ((ADDR_MASK(ex->startpc) <= xpc) && (xpc < ADDR_MASK(ex->endpc))) {
1731 /* NULL catches everything */
1733 if (cr.any == NULL) {
1734 #if !defined(NDEBUG)
1735 /* Print stacktrace of exception when caught. */
1737 #if defined(ENABLE_VMLOG)
1738 vmlog_cacao_catch(xptr);
1741 if (opt_verboseexception) {
1742 exceptions_print_exception(xptr);
1743 stacktrace_print_trace(xptr);
1747 return ex->handlerpc;
1750 /* resolve or load/link the exception class */
1752 if (IS_CLASSREF(cr)) {
1753 /* The exception class reference is unresolved. */
1754 /* We have to do _eager_ resolving here. While the class of */
1755 /* the exception object is guaranteed to be loaded, it may */
1756 /* well have been loaded by a different loader than the */
1757 /* defining loader of m's class, which is the one we must */
1758 /* use to resolve the catch class. Thus lazy resolving */
1759 /* might fail, even if the result of the resolution would */
1760 /* be an already loaded class. */
1762 c = resolve_classref_eager(cr.ref);
1765 /* Exception resolving the exception class, argh! */
1769 /* Ok, we resolved it. Enter it in the table, so we don't */
1770 /* have to do this again. */
1771 /* XXX this write should be atomic. Is it? */
1773 ex->catchtype.cls = c;
1777 /* XXX I don't think this case can ever happen. -Edwin */
1778 if (!(c->state & CLASS_LOADED))
1779 /* use the methods' classloader */
1780 if (!load_class_from_classloader(c->name,
1781 m->class->classloader))
1784 /* XXX I think, if it is not linked, we can be sure that */
1785 /* the exception object is no (indirect) instance of it, no? */
1787 if (!(c->state & CLASS_LINKED))
1792 /* is the thrown exception an instance of the catch class? */
1794 if (builtin_instanceof(xptr, c)) {
1795 #if !defined(NDEBUG)
1796 /* Print stacktrace of exception when caught. */
1798 #if defined(ENABLE_VMLOG)
1799 vmlog_cacao_catch(xptr);
1802 if (opt_verboseexception) {
1803 exceptions_print_exception(xptr);
1804 stacktrace_print_trace(xptr);
1808 return ex->handlerpc;
1813 #if defined(ENABLE_THREADS)
1814 /* is this method synchronized? */
1817 /* get synchronization object */
1819 # if defined(__MIPS__) && (SIZEOF_VOID_P == 4)
1820 /* XXX change this if we ever want to use 4-byte stackslots */
1821 o = *((java_objectheader **) (sp + issync - 8));
1823 o = *((java_objectheader **) (sp + issync - SIZEOF_VOID_P));
1828 lock_monitor_exit(o);
1832 /* none of the exceptions catch this one */
1834 #if defined(ENABLE_VMLOG)
1835 vmlog_cacao_unwnd_method(m);
1840 #endif /* defined(ENABLE_JIT) */
1843 /* exceptions_print_exception **************************************************
1845 Prints an exception, the detail message and the cause, if
1846 available, with CACAO internal functions to stdout.
1848 *******************************************************************************/
1850 void exceptions_print_exception(java_objectheader *xptr)
1852 java_lang_Throwable *t;
1853 #if defined(ENABLE_JAVASE)
1854 java_lang_Throwable *cause;
1858 t = (java_lang_Throwable *) xptr;
1865 #if defined(ENABLE_JAVASE)
1869 /* print the root exception */
1871 utf_display_printable_ascii_classname(t->header.vftbl->class->name);
1873 if (t->detailMessage != NULL) {
1874 u = javastring_toutf((java_objectheader *) t->detailMessage, false);
1877 utf_display_printable_ascii(u);
1882 #if defined(ENABLE_JAVASE)
1883 /* print the cause if available */
1885 if ((cause != NULL) && (cause != t)) {
1886 printf("Caused by: ");
1887 utf_display_printable_ascii_classname(cause->header.vftbl->class->name);
1889 if (cause->detailMessage != NULL) {
1890 u = javastring_toutf((java_objectheader *) cause->detailMessage,
1894 utf_display_printable_ascii(u);
1903 /* exceptions_print_current_exception ******************************************
1905 Prints the current pending exception, the detail message and the
1906 cause, if available, with CACAO internal functions to stdout.
1908 *******************************************************************************/
1910 void exceptions_print_current_exception(void)
1912 java_objectheader *xptr;
1914 xptr = *exceptionptr;
1916 exceptions_print_exception(xptr);
1920 /* exceptions_print_stacktrace *************************************************
1922 Prints a pending exception with Throwable.printStackTrace(). If
1923 there happens an exception during printStackTrace(), we print the
1924 thrown exception and the original one.
1926 NOTE: This function calls Java code.
1928 *******************************************************************************/
1930 void exceptions_print_stacktrace(void)
1932 java_objectheader *oxptr;
1933 java_objectheader *xptr;
1937 /* get original exception */
1939 oxptr = *exceptionptr;
1942 vm_abort("exceptions_print_stacktrace: no exception thrown");
1944 /* clear exception, because we are calling jit code again */
1946 *exceptionptr = NULL;
1948 c = oxptr->vftbl->class;
1950 /* find the printStackTrace() method */
1952 m = class_resolveclassmethod(c,
1953 utf_printStackTrace,
1955 class_java_lang_Object,
1959 vm_abort("exceptions_print_stacktrace: printStackTrace()V not found");
1961 /* print compatibility message */
1963 fprintf(stderr, "Exception in thread \"main\" ");
1965 /* print the stacktrace */
1967 (void) vm_call_method(m, oxptr);
1969 /* This normally means, we are EXTREMLY out of memory or
1970 have a serious problem while printStackTrace. But may
1971 be another exception, so print it. */
1973 xptr = *exceptionptr;
1976 fprintf(stderr, "Exception while printStackTrace(): ");
1978 /* now print original exception */
1980 exceptions_print_exception(xptr);
1981 stacktrace_print_trace(xptr);
1983 /* now print original exception */
1985 fprintf(stderr, "Original exception was: ");
1986 exceptions_print_exception(oxptr);
1987 stacktrace_print_trace(oxptr);
1995 * These are local overrides for various environment variables in Emacs.
1996 * Please do not remove this and leave it at the end of the file, where
1997 * Emacs will automagically detect them.
1998 * ---------------------------------------------------------------------
2001 * indent-tabs-mode: t
2005 * vim:noexpandtab:sw=4:ts=4: