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 8056 2007-06-10 14:49:57Z michi $
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_throw_utf_exception **********************************************
318 Creates an exception object with the given name and initalizes it
319 with the given java/lang/Exception exception.
322 classname....class name in UTF-8
323 exception....the given Exception
325 *******************************************************************************/
327 static void exceptions_throw_utf_exception(utf *classname,
328 java_objectheader *exception)
330 java_objectheader *o;
333 c = load_class_bootstrap(classname);
338 o = native_new_and_init_exception(c, exception);
347 /* exceptions_new_utf_javastring ***********************************************
349 Creates an exception object with the given name and initalizes it
350 with the given java/lang/String message.
353 classname....class name in UTF-8
354 message......the message as a java.lang.String
357 an exception pointer (in any case -- either it is the newly created
358 exception, or an exception thrown while trying to create it).
360 *******************************************************************************/
362 static java_objectheader *exceptions_new_utf_javastring(utf *classname,
363 java_objectheader *message)
365 java_objectheader *o;
368 c = load_class_bootstrap(classname);
371 return *exceptionptr;
373 o = native_new_and_init_string(c, message);
376 return *exceptionptr;
382 /* exceptions_new_class_utf ****************************************************
384 Creates an exception object of the given class and initalizes it.
387 c..........class pointer
388 message....the message as UTF-8 string
390 *******************************************************************************/
392 static java_objectheader *exceptions_new_class_utf(classinfo *c, utf *message)
394 java_objectheader *o;
395 java_objectheader *s;
397 s = javastring_new(message);
400 return *exceptionptr;
402 o = native_new_and_init_string(c, s);
405 return *exceptionptr;
411 /* exceptions_new_utf_utf ******************************************************
413 Creates an exception object with the given name and initalizes it
414 with the given utf message.
417 classname....class name in UTF-8
418 message......the message as an utf *
421 an exception pointer (in any case -- either it is the newly created
422 exception, or an exception thrown while trying to create it).
424 *******************************************************************************/
426 static java_objectheader *exceptions_new_utf_utf(utf *classname, utf *message)
429 java_objectheader *o;
431 c = load_class_bootstrap(classname);
434 return *exceptionptr;
436 o = exceptions_new_class_utf(c, message);
442 /* exceptions_throw_class_utf **************************************************
444 Creates an exception object of the given class, initalizes and
445 throws it with the given utf message.
448 c..........class pointer
449 message....the message as an UTF-8
451 *******************************************************************************/
453 static void exceptions_throw_class_utf(classinfo *c, utf *message)
455 *exceptionptr = exceptions_new_class_utf(c, message);
459 /* exceptions_throw_utf_utf ****************************************************
461 Creates an exception object with the given name, initalizes and
462 throws it with the given utf message.
465 classname....class name in UTF-8
466 message......the message as an utf *
468 *******************************************************************************/
470 static void exceptions_throw_utf_utf(utf *classname, utf *message)
472 *exceptionptr = exceptions_new_utf_utf(classname, message);
476 /* exceptions_new_abstractmethoderror ****************************************
478 Generates a java.lang.AbstractMethodError for the VM.
480 *******************************************************************************/
482 java_objectheader *exceptions_new_abstractmethoderror(void)
484 java_objectheader *o;
486 o = exceptions_new_utf(utf_java_lang_AbstractMethodError);
492 /* exceptions_new_error ********************************************************
494 Generates a java.lang.Error for the VM.
496 *******************************************************************************/
498 #if defined(ENABLE_JAVAME_CLDC1_1)
499 static java_objectheader *exceptions_new_error(utf *message)
501 java_objectheader *o;
503 o = exceptions_new_class_utf(class_java_lang_Error, message);
510 /* exceptions_asm_new_abstractmethoderror **************************************
512 Generates a java.lang.AbstractMethodError for
513 asm_abstractmethoderror.
515 *******************************************************************************/
517 java_objectheader *exceptions_asm_new_abstractmethoderror(u1 *sp, u1 *ra)
520 java_objectheader *e;
522 /* create the stackframeinfo (XPC is equal to RA) */
524 stacktrace_create_extern_stackframeinfo(&sfi, NULL, sp, ra, ra);
526 /* create the exception */
528 #if defined(ENABLE_JAVASE)
529 e = exceptions_new_abstractmethoderror();
531 e = exceptions_new_error(utf_java_lang_AbstractMethodError);
534 /* remove the stackframeinfo */
536 stacktrace_remove_stackframeinfo(&sfi);
542 /* exceptions_new_arraystoreexception ******************************************
544 Generates a java.lang.ArrayStoreException for the VM.
546 *******************************************************************************/
548 java_objectheader *exceptions_new_arraystoreexception(void)
550 java_objectheader *o;
552 o = exceptions_new_utf(utf_java_lang_ArrayStoreException);
558 /* exceptions_throw_abstractmethoderror ****************************************
560 Generates and throws a java.lang.AbstractMethodError for the VM.
562 *******************************************************************************/
564 void exceptions_throw_abstractmethoderror(void)
566 exceptions_throw_utf(utf_java_lang_AbstractMethodError);
570 /* exceptions_throw_classcircularityerror **************************************
572 Generates and throws a java.lang.ClassCircularityError for the
576 c....the class in which the error was found
578 *******************************************************************************/
580 void exceptions_throw_classcircularityerror(classinfo *c)
582 exceptions_throw_utf_utf(utf_java_lang_ClassCircularityError, c->name);
586 /* exceptions_throw_classformaterror *******************************************
588 Generates and throws a java.lang.ClassFormatError for the VM.
591 c............the class in which the error was found
592 message......UTF-8 format string
594 *******************************************************************************/
596 void exceptions_throw_classformaterror(classinfo *c, const char *message, ...)
603 /* calculate message length */
608 msglen += utf_bytes(c->name) + strlen(" (");
610 va_start(ap, message);
611 msglen += get_variable_message_length(message, ap);
615 msglen += strlen(")");
617 msglen += strlen("0");
619 /* allocate a buffer */
621 msg = MNEW(char, msglen);
623 /* print message into allocated buffer */
626 utf_copy_classname(msg, c->name);
630 va_start(ap, message);
631 vsprintf(msg + strlen(msg), message, ap);
637 u = utf_new_char(msg);
641 MFREE(msg, char, msglen);
643 /* throw exception */
645 exceptions_throw_utf_utf(utf_java_lang_ClassFormatError, u);
649 /* exceptions_throw_classnotfoundexception *************************************
651 Generates and throws a java.lang.ClassNotFoundException for the
655 name.........name of the class not found as a utf *
657 *******************************************************************************/
659 void exceptions_throw_classnotfoundexception(utf *name)
661 /* we use class here, as this one is rather frequent */
663 exceptions_throw_class_utf(class_java_lang_ClassNotFoundException, name);
667 /* exceptions_throw_noclassdeffounderror ***************************************
669 Generates and throws a java.lang.NoClassDefFoundError.
672 name.........name of the class not found as a utf *
674 *******************************************************************************/
676 void exceptions_throw_noclassdeffounderror(utf *name)
679 vm_abort("java.lang.NoClassDefFoundError: %s", name->text);
681 exceptions_throw_class_utf(class_java_lang_NoClassDefFoundError, name);
685 /* exceptions_throw_noclassdeffounderror_wrong_name ****************************
687 Generates and throws a java.lang.NoClassDefFoundError with a
693 name.........name of the class not found as a utf *
695 *******************************************************************************/
697 void exceptions_throw_noclassdeffounderror_wrong_name(classinfo *c, utf *name)
703 msglen = utf_bytes(c->name) + strlen(" (wrong name: ") +
704 utf_bytes(name) + strlen(")") + strlen("0");
706 msg = MNEW(char, msglen);
708 utf_copy_classname(msg, c->name);
709 strcat(msg, " (wrong name: ");
710 utf_cat_classname(msg, name);
713 u = utf_new_char(msg);
715 MFREE(msg, char, msglen);
717 exceptions_throw_noclassdeffounderror(u);
721 /* classnotfoundexception_to_noclassdeffounderror ******************************
723 Check the *exceptionptr for a ClassNotFoundException. If it is one,
724 convert it to a NoClassDefFoundError.
726 *******************************************************************************/
728 void classnotfoundexception_to_noclassdeffounderror(void)
730 java_objectheader *xptr;
731 java_objectheader *cause;
732 java_lang_Throwable *t;
733 java_objectheader *s;
737 cause = *exceptionptr;
739 /* convert ClassNotFoundException's to NoClassDefFoundError's */
741 if (builtin_instanceof(cause, class_java_lang_ClassNotFoundException)) {
742 /* clear exception, because we are calling jit code again */
744 *exceptionptr = NULL;
746 /* create new error */
748 t = (java_lang_Throwable *) cause;
749 s = (java_objectheader *) t->detailMessage;
751 xptr = exceptions_new_utf_javastring(utf_java_lang_NoClassDefFoundError,
754 /* we had an exception while creating the error */
759 /* set new exception */
761 *exceptionptr = xptr;
766 /* exceptions_throw_exceptionininitializererror ********************************
768 Generates and throws a java.lang.ExceptionInInitializerError for
772 cause......cause exception object
774 *******************************************************************************/
776 void exceptions_throw_exceptionininitializererror(java_objectheader *cause)
778 exceptions_throw_utf_throwable(utf_java_lang_ExceptionInInitializerError,
783 /* exceptions_throw_incompatibleclasschangeerror *******************************
785 Generates and throws a java.lang.IncompatibleClassChangeError for
789 message......UTF-8 message format string
791 *******************************************************************************/
793 void exceptions_throw_incompatibleclasschangeerror(classinfo *c, const char *message)
799 /* calculate exception message length */
801 msglen = utf_bytes(c->name) + strlen(message) + strlen("0");
803 /* allocate memory */
805 msg = MNEW(char, msglen);
807 utf_copy_classname(msg, c->name);
808 strcat(msg, message);
810 u = utf_new_char(msg);
814 MFREE(msg, char, msglen);
816 /* throw exception */
818 exceptions_throw_utf_utf(utf_java_lang_IncompatibleClassChangeError, u);
822 /* exceptions_throw_instantiationerror *****************************************
824 Generates and throws a java.lang.InstantiationError for the VM.
826 *******************************************************************************/
828 void exceptions_throw_instantiationerror(classinfo *c)
830 exceptions_throw_utf_utf(utf_java_lang_InstantiationError, c->name);
834 /* exceptions_throw_internalerror **********************************************
836 Generates and throws a java.lang.InternalError for the VM.
839 message......UTF-8 message format string
841 *******************************************************************************/
843 void exceptions_throw_internalerror(const char *message, ...)
850 /* calculate exception message length */
852 va_start(ap, message);
853 msglen = get_variable_message_length(message, ap);
856 /* allocate memory */
858 msg = MNEW(char, msglen);
860 /* generate message */
862 va_start(ap, message);
863 vsprintf(msg, message, ap);
866 u = utf_new_char(msg);
870 MFREE(msg, char, msglen);
872 /* throw exception */
874 exceptions_throw_utf_utf(utf_java_lang_InternalError, u);
878 /* exceptions_throw_linkageerror ***********************************************
880 Generates and throws java.lang.LinkageError with an error message.
883 message......UTF-8 message
884 c............class related to the error. If this is != NULL
885 the name of c is appended to the error message.
887 *******************************************************************************/
889 void exceptions_throw_linkageerror(const char *message, classinfo *c)
891 java_objectheader *o;
895 /* calculate exception message length */
897 msglen = strlen(message) + 1;
900 msglen += utf_bytes(c->name);
902 /* allocate memory */
904 msg = MNEW(char, msglen);
906 /* generate message */
911 utf_cat_classname(msg, c->name);
913 o = native_new_and_init_string(class_java_lang_LinkageError,
914 javastring_new_from_utf_string(msg));
918 MFREE(msg, char, msglen);
927 /* exceptions_throw_nosuchfielderror *******************************************
929 Generates and throws a java.lang.NoSuchFieldError with an error
933 c............class in which the field was not found
934 name.........name of the field
936 *******************************************************************************/
938 void exceptions_throw_nosuchfielderror(classinfo *c, utf *name)
944 /* calculate exception message length */
946 msglen = utf_bytes(c->name) + strlen(".") + utf_bytes(name) + strlen("0");
948 /* allocate memory */
950 msg = MNEW(char, msglen);
952 /* generate message */
954 utf_copy_classname(msg, c->name);
958 u = utf_new_char(msg);
962 MFREE(msg, char, msglen);
964 exceptions_throw_utf_utf(utf_java_lang_NoSuchFieldError, u);
968 /* exceptions_throw_nosuchmethoderror ******************************************
970 Generates and throws a java.lang.NoSuchMethodError with an error
974 c............class in which the method was not found
975 name.........name of the method
976 desc.........descriptor of the method
978 *******************************************************************************/
980 void exceptions_throw_nosuchmethoderror(classinfo *c, utf *name, utf *desc)
986 /* calculate exception message length */
988 msglen = utf_bytes(c->name) + strlen(".") + utf_bytes(name) +
989 utf_bytes(desc) + strlen("0");
991 /* allocate memory */
993 msg = MNEW(char, msglen);
995 /* generate message */
997 utf_copy_classname(msg, c->name);
1002 u = utf_new_char(msg);
1006 MFREE(msg, char, msglen);
1008 #if defined(ENABLE_JAVASE)
1009 exceptions_throw_utf_utf(utf_java_lang_NoSuchMethodError, u);
1011 exceptions_throw_class_utf(class_java_lang_Error, u);
1016 /* exceptions_throw_outofmemoryerror *******************************************
1018 Generates and throws an java.lang.OutOfMemoryError for the VM.
1020 *******************************************************************************/
1022 void exceptions_throw_outofmemoryerror(void)
1024 exceptions_throw_class(class_java_lang_OutOfMemoryError);
1028 /* exceptions_throw_unsatisfiedlinkerror ***************************************
1030 Generates and throws a java.lang.UnsatisfiedLinkError for the
1034 name......UTF-8 name string
1036 *******************************************************************************/
1038 void exceptions_throw_unsatisfiedlinkerror(utf *name)
1040 #if defined(ENABLE_JAVASE)
1041 exceptions_throw_utf_utf(utf_java_lang_UnsatisfiedLinkError, name);
1043 exceptions_throw_class_utf(class_java_lang_Error, name);
1048 /* exceptions_throw_unsupportedclassversionerror *******************************
1050 Generates and throws a java.lang.UnsupportedClassVersionError for
1054 c............class in which the method was not found
1055 message......UTF-8 format string
1057 *******************************************************************************/
1059 void exceptions_throw_unsupportedclassversionerror(classinfo *c, u4 ma, u4 mi)
1065 /* calculate exception message length */
1068 utf_bytes(c->name) +
1069 strlen(" (Unsupported major.minor version 00.0)") +
1072 /* allocate memory */
1074 msg = MNEW(char, msglen);
1076 /* generate message */
1078 utf_copy_classname(msg, c->name);
1079 sprintf(msg + strlen(msg), " (Unsupported major.minor version %d.%d)",
1082 u = utf_new_char(msg);
1086 MFREE(msg, char, msglen);
1088 /* throw exception */
1090 exceptions_throw_utf_utf(utf_java_lang_UnsupportedClassVersionError, u);
1094 /* exceptions_throw_verifyerror ************************************************
1096 Generates and throws a java.lang.VerifyError for the JIT compiler.
1099 m............method in which the error was found
1100 message......UTF-8 format string
1102 *******************************************************************************/
1104 void exceptions_throw_verifyerror(methodinfo *m, const char *message, ...)
1111 /* calculate exception message length */
1117 strlen("(class: ") + utf_bytes(m->class->name) +
1118 strlen(", method: ") + utf_bytes(m->name) +
1119 strlen(" signature: ") + utf_bytes(m->descriptor) +
1120 strlen(") ") + strlen("0");
1122 va_start(ap, message);
1123 msglen += get_variable_message_length(message, ap);
1126 /* allocate memory */
1128 msg = MNEW(char, msglen);
1130 /* generate message */
1133 strcpy(msg, "(class: ");
1134 utf_cat_classname(msg, m->class->name);
1135 strcat(msg, ", method: ");
1136 utf_cat(msg, m->name);
1137 strcat(msg, " signature: ");
1138 utf_cat(msg, m->descriptor);
1142 va_start(ap, message);
1143 vsprintf(msg + strlen(msg), message, ap);
1146 u = utf_new_char(msg);
1150 MFREE(msg, char, msglen);
1152 /* throw exception */
1154 exceptions_throw_utf_utf(utf_java_lang_VerifyError, u);
1158 /* exceptions_throw_verifyerror_for_stack **************************************
1160 throws a java.lang.VerifyError for an invalid stack slot type
1163 m............method in which the error was found
1164 type.........the expected type
1167 an exception pointer (in any case -- either it is the newly created
1168 exception, or an exception thrown while trying to create it).
1170 *******************************************************************************/
1172 void exceptions_throw_verifyerror_for_stack(methodinfo *m, int type)
1179 /* calculate exception message length */
1184 msglen = strlen("(class: ") + utf_bytes(m->class->name) +
1185 strlen(", method: ") + utf_bytes(m->name) +
1186 strlen(" signature: ") + utf_bytes(m->descriptor) +
1187 strlen(") Expecting to find longest-------typename on stack")
1190 /* allocate memory */
1192 msg = MNEW(char, msglen);
1194 /* generate message */
1197 strcpy(msg, "(class: ");
1198 utf_cat_classname(msg, m->class->name);
1199 strcat(msg, ", method: ");
1200 utf_cat(msg, m->name);
1201 strcat(msg, " signature: ");
1202 utf_cat(msg, m->descriptor);
1209 strcat(msg, "Expecting to find ");
1212 case TYPE_INT: typename = "integer"; break;
1213 case TYPE_LNG: typename = "long"; break;
1214 case TYPE_FLT: typename = "float"; break;
1215 case TYPE_DBL: typename = "double"; break;
1216 case TYPE_ADR: typename = "object/array"; break;
1217 case TYPE_RET: typename = "returnAddress"; break;
1218 default: typename = "<INVALID>"; assert(0); break;
1221 strcat(msg, typename);
1222 strcat(msg, " on stack");
1224 u = utf_new_char(msg);
1228 MFREE(msg, char, msglen);
1230 /* throw exception */
1232 exceptions_throw_utf_utf(utf_java_lang_VerifyError, u);
1236 /* exceptions_new_arithmeticexception ******************************************
1238 Generates a java.lang.ArithmeticException for the JIT compiler.
1240 *******************************************************************************/
1242 java_objectheader *exceptions_new_arithmeticexception(void)
1244 java_objectheader *o;
1246 o = exceptions_new_utf_utf(utf_java_lang_ArithmeticException,
1247 utf_division_by_zero);
1253 /* exceptions_new_arrayindexoutofboundsexception *******************************
1255 Generates a java.lang.ArrayIndexOutOfBoundsException for the VM
1258 *******************************************************************************/
1260 java_objectheader *exceptions_new_arrayindexoutofboundsexception(s4 index)
1262 java_objectheader *o;
1264 java_objectheader *s;
1266 /* convert the index into a String, like Sun does */
1268 m = class_resolveclassmethod(class_java_lang_String,
1269 utf_new_char("valueOf"),
1270 utf_new_char("(I)Ljava/lang/String;"),
1271 class_java_lang_Object,
1275 return *exceptionptr;
1277 s = vm_call_method(m, NULL, index);
1280 return *exceptionptr;
1282 o = exceptions_new_utf_javastring(utf_java_lang_ArrayIndexOutOfBoundsException,
1286 return *exceptionptr;
1292 /* exceptions_throw_arrayindexoutofboundsexception *****************************
1294 Generates and throws a java.lang.ArrayIndexOutOfBoundsException for
1297 *******************************************************************************/
1299 void exceptions_throw_arrayindexoutofboundsexception(void)
1301 exceptions_throw_utf(utf_java_lang_ArrayIndexOutOfBoundsException);
1305 /* exceptions_throw_arraystoreexception ****************************************
1307 Generates and throws a java.lang.ArrayStoreException for the VM.
1309 *******************************************************************************/
1311 void exceptions_throw_arraystoreexception(void)
1313 exceptions_throw_utf(utf_java_lang_ArrayStoreException);
1314 /* e = native_new_and_init(class_java_lang_ArrayStoreException); */
1318 /* exceptions_new_classcastexception *******************************************
1320 Generates a java.lang.ClassCastException for the JIT compiler.
1322 *******************************************************************************/
1324 java_objectheader *exceptions_new_classcastexception(java_objectheader *o)
1326 java_objectheader *e;
1329 classname = o->vftbl->class->name;
1331 e = exceptions_new_class_utf(class_java_lang_ClassCastException, classname);
1337 /* exceptions_throw_clonenotsupportedexception *********************************
1339 Generates and throws a java.lang.CloneNotSupportedException for the
1342 *******************************************************************************/
1344 void exceptions_throw_clonenotsupportedexception(void)
1346 exceptions_throw_utf(utf_java_lang_CloneNotSupportedException);
1350 /* exceptions_throw_illegalaccessexception *************************************
1352 Generates and throws a java.lang.IllegalAccessException for the VM.
1354 *******************************************************************************/
1356 void exceptions_throw_illegalaccessexception(utf *message)
1358 exceptions_throw_utf_utf(utf_java_lang_IllegalAccessException, message);
1362 /* exceptions_throw_illegalargumentexception ***********************************
1364 Generates and throws a java.lang.IllegalArgumentException for the
1367 *******************************************************************************/
1369 void exceptions_throw_illegalargumentexception(void)
1371 exceptions_throw_utf(utf_java_lang_IllegalArgumentException);
1375 /* exceptions_throw_illegalmonitorstateexception *******************************
1377 Generates and throws a java.lang.IllegalMonitorStateException for
1380 *******************************************************************************/
1382 void exceptions_throw_illegalmonitorstateexception(void)
1384 exceptions_throw_utf(utf_java_lang_IllegalMonitorStateException);
1388 /* exceptions_throw_instantiationexception *************************************
1390 Generates and throws a java.lang.InstantiationException for the VM.
1392 *******************************************************************************/
1394 void exceptions_throw_instantiationexception(classinfo *c)
1396 exceptions_throw_utf_utf(utf_java_lang_InstantiationException, c->name);
1400 /* exceptions_throw_interruptedexception ***************************************
1402 Generates and throws a java.lang.InterruptedException for the VM.
1404 *******************************************************************************/
1406 void exceptions_throw_interruptedexception(void)
1408 exceptions_throw_utf(utf_java_lang_InterruptedException);
1412 /* exceptions_throw_invocationtargetexception **********************************
1414 Generates and throws a java.lang.reflect.InvocationTargetException
1418 cause......cause exception object
1420 *******************************************************************************/
1422 void exceptions_throw_invocationtargetexception(java_objectheader *cause)
1424 exceptions_throw_utf_throwable(utf_java_lang_reflect_InvocationTargetException,
1429 /* exceptions_throw_negativearraysizeexception *********************************
1431 Generates and throws a java.lang.NegativeArraySizeException for the
1434 *******************************************************************************/
1436 void exceptions_throw_negativearraysizeexception(void)
1438 exceptions_throw_utf(utf_java_lang_NegativeArraySizeException);
1442 /* exceptions_new_nullpointerexception *****************************************
1444 Generates a java.lang.NullPointerException for the VM system.
1446 *******************************************************************************/
1448 java_objectheader *exceptions_new_nullpointerexception(void)
1450 java_objectheader *o;
1452 o = exceptions_new_class(class_java_lang_NullPointerException);
1458 /* exceptions_throw_nullpointerexception ***************************************
1460 Generates a java.lang.NullPointerException for the VM system and
1461 throw it in the VM system.
1463 *******************************************************************************/
1465 void exceptions_throw_nullpointerexception(void)
1467 exceptions_throw_class(class_java_lang_NullPointerException);
1471 /* exceptions_throw_privilegedactionexception **********************************
1473 Generates and throws a java.security.PrivilegedActionException.
1475 *******************************************************************************/
1477 void exceptions_throw_privilegedactionexception(java_objectheader *exception)
1479 exceptions_throw_utf_exception(utf_java_security_PrivilegedActionException,
1484 /* exceptions_throw_stringindexoutofboundsexception ****************************
1486 Generates and throws a java.lang.StringIndexOutOfBoundsException
1489 *******************************************************************************/
1491 void exceptions_throw_stringindexoutofboundsexception(void)
1493 exceptions_throw_utf(utf_java_lang_StringIndexOutOfBoundsException);
1497 /* exceptions_get_exception ****************************************************
1499 Returns the current exception pointer of the current thread.
1501 *******************************************************************************/
1503 java_objectheader *exceptions_get_exception(void)
1505 /* return the exception */
1507 return *exceptionptr;
1511 /* exceptions_set_exception ****************************************************
1513 Sets the exception pointer of the current thread.
1515 *******************************************************************************/
1517 void exceptions_set_exception(java_objectheader *o)
1519 /* set the exception */
1525 /* exceptions_clear_exception **************************************************
1527 Clears the current exception pointer of the current thread.
1529 *******************************************************************************/
1531 void exceptions_clear_exception(void)
1533 /* and clear the exception */
1535 *exceptionptr = NULL;
1539 /* exceptions_fillinstacktrace *************************************************
1541 Calls the fillInStackTrace-method of the currently thrown
1544 *******************************************************************************/
1546 java_objectheader *exceptions_fillinstacktrace(void)
1548 java_objectheader *o;
1556 /* clear exception */
1558 *exceptionptr = NULL;
1560 /* resolve methodinfo pointer from exception object */
1562 #if defined(ENABLE_JAVASE)
1563 m = class_resolvemethod(o->vftbl->class,
1564 utf_fillInStackTrace,
1565 utf_void__java_lang_Throwable);
1566 #elif defined(ENABLE_JAVAME_CLDC1_1)
1567 m = class_resolvemethod(o->vftbl->class,
1568 utf_fillInStackTrace,
1571 #error IMPLEMENT ME!
1576 (void) vm_call_method(m, o);
1578 /* return exception object */
1584 /* exceptions_get_and_clear_exception ******************************************
1586 Gets the exception pointer of the current thread and clears it.
1587 This function may return NULL.
1589 *******************************************************************************/
1591 java_objectheader *exceptions_get_and_clear_exception(void)
1593 java_objectheader **p;
1594 java_objectheader *e;
1596 /* get the pointer of the exception pointer */
1600 /* get the exception */
1604 /* and clear the exception */
1608 /* return the exception */
1614 /* exceptions_new_hardware_exception *******************************************
1616 Creates the correct exception for a hardware-exception thrown and
1617 caught by a signal handler.
1619 *******************************************************************************/
1621 java_objectheader *exceptions_new_hardware_exception(u1 *pv, u1 *sp, u1 *ra, u1 *xpc, s4 type, ptrint val)
1624 java_objectheader *e;
1625 java_objectheader *o;
1628 /* create stackframeinfo */
1630 stacktrace_create_extern_stackframeinfo(&sfi, pv, sp, ra, xpc);
1633 case EXCEPTION_HARDWARE_NULLPOINTER:
1634 e = exceptions_new_nullpointerexception();
1637 case EXCEPTION_HARDWARE_ARITHMETIC:
1638 e = exceptions_new_arithmeticexception();
1641 case EXCEPTION_HARDWARE_ARRAYINDEXOUTOFBOUNDS:
1643 e = exceptions_new_arrayindexoutofboundsexception(index);
1646 case EXCEPTION_HARDWARE_CLASSCAST:
1647 o = (java_objectheader *) val;
1648 e = exceptions_new_classcastexception(o);
1651 case EXCEPTION_HARDWARE_EXCEPTION:
1652 e = exceptions_fillinstacktrace();
1656 /* let's try to get a backtrace */
1658 codegen_get_pv_from_pc(xpc);
1660 /* if that does not work, print more debug info */
1662 log_println("exceptions_new_hardware_exception: unknown exception type %d", type);
1664 #if SIZEOF_VOID_P == 8
1665 log_println("PC=0x%016lx", xpc);
1667 log_println("PC=0x%08x", xpc);
1670 #if defined(ENABLE_DISASSEMBLER)
1671 log_println("machine instruction at PC:");
1675 vm_abort("Exiting...");
1677 /* keep compiler happy */
1682 /* remove stackframeinfo */
1684 stacktrace_remove_stackframeinfo(&sfi);
1686 /* return the exception object */
1692 /* exceptions_handle_exception *************************************************
1694 Try to find an exception handler for the given exception and return it.
1695 If no handler is found, exit the monitor of the method (if any)
1699 xptr.........the exception object
1700 xpc..........PC of where the exception was thrown
1701 pv...........Procedure Value of the current method
1702 sp...........current stack pointer
1705 the address of the first matching exception handler, or
1706 NULL if no handler was found
1708 *******************************************************************************/
1710 #if defined(ENABLE_JIT)
1711 u1 *exceptions_handle_exception(java_objectheader *xptr, u1 *xpc, u1 *pv, u1 *sp)
1716 dseg_exception_entry *ex;
1717 s4 exceptiontablelength;
1719 classref_or_classinfo cr;
1721 #if defined(ENABLE_THREADS)
1722 java_objectheader *o;
1726 /* Addresses are 31 bit integers */
1727 # define ADDR_MASK(x) (u1 *)((u4)(x) & 0x7FFFFFFF)
1729 # define ADDR_MASK(x) (x)
1732 xpc = ADDR_MASK(xpc);
1734 /* get info from the method header */
1736 code = *((codeinfo **) (pv + CodeinfoPointer));
1737 issync = *((s4 *) (pv + IsSync));
1738 ex = (dseg_exception_entry *) (pv + ExTableStart);
1739 exceptiontablelength = *((s4 *) (pv + ExTableSize));
1741 /* Get the methodinfo pointer from the codeinfo pointer. For
1742 asm_vm_call_method the codeinfo pointer is NULL. */
1744 m = (code == NULL) ? NULL : code->m;
1746 #if !defined(NDEBUG)
1747 /* print exception trace */
1749 if (opt_verbose || opt_verbosecall || opt_verboseexception)
1750 builtin_trace_exception(xptr, m, xpc, 1);
1753 #if defined(ENABLE_VMLOG)
1754 vmlog_cacao_throw(xptr);
1757 for (i = 0; i < exceptiontablelength; i++) {
1758 /* ATTENTION: keep this here, as we need to decrement the
1759 pointer before the loop executes! */
1763 /* If the start and end PC is NULL, this means we have the
1764 special case of asm_vm_call_method. So, just return the
1765 proper exception handler. */
1767 if ((ex->startpc == NULL) && (ex->endpc == NULL))
1768 return (u1 *) (ptrint) &asm_vm_call_method_exception_handler;
1770 /* is the xpc is the current catch range */
1772 if ((ADDR_MASK(ex->startpc) <= xpc) && (xpc < ADDR_MASK(ex->endpc))) {
1775 /* NULL catches everything */
1777 if (cr.any == NULL) {
1778 #if !defined(NDEBUG)
1779 /* Print stacktrace of exception when caught. */
1781 #if defined(ENABLE_VMLOG)
1782 vmlog_cacao_catch(xptr);
1785 if (opt_verboseexception) {
1786 exceptions_print_exception(xptr);
1787 stacktrace_print_trace(xptr);
1791 return ex->handlerpc;
1794 /* resolve or load/link the exception class */
1796 if (IS_CLASSREF(cr)) {
1797 /* The exception class reference is unresolved. */
1798 /* We have to do _eager_ resolving here. While the class of */
1799 /* the exception object is guaranteed to be loaded, it may */
1800 /* well have been loaded by a different loader than the */
1801 /* defining loader of m's class, which is the one we must */
1802 /* use to resolve the catch class. Thus lazy resolving */
1803 /* might fail, even if the result of the resolution would */
1804 /* be an already loaded class. */
1806 c = resolve_classref_eager(cr.ref);
1809 /* Exception resolving the exception class, argh! */
1813 /* Ok, we resolved it. Enter it in the table, so we don't */
1814 /* have to do this again. */
1815 /* XXX this write should be atomic. Is it? */
1817 ex->catchtype.cls = c;
1821 /* XXX I don't think this case can ever happen. -Edwin */
1822 if (!(c->state & CLASS_LOADED))
1823 /* use the methods' classloader */
1824 if (!load_class_from_classloader(c->name,
1825 m->class->classloader))
1828 /* XXX I think, if it is not linked, we can be sure that */
1829 /* the exception object is no (indirect) instance of it, no? */
1831 if (!(c->state & CLASS_LINKED))
1836 /* is the thrown exception an instance of the catch class? */
1838 if (builtin_instanceof(xptr, c)) {
1839 #if !defined(NDEBUG)
1840 /* Print stacktrace of exception when caught. */
1842 #if defined(ENABLE_VMLOG)
1843 vmlog_cacao_catch(xptr);
1846 if (opt_verboseexception) {
1847 exceptions_print_exception(xptr);
1848 stacktrace_print_trace(xptr);
1852 return ex->handlerpc;
1857 #if defined(ENABLE_THREADS)
1858 /* is this method synchronized? */
1861 /* get synchronization object */
1863 # if defined(__MIPS__) && (SIZEOF_VOID_P == 4)
1864 /* XXX change this if we ever want to use 4-byte stackslots */
1865 o = *((java_objectheader **) (sp + issync - 8));
1867 o = *((java_objectheader **) (sp + issync - SIZEOF_VOID_P));
1872 lock_monitor_exit(o);
1876 /* none of the exceptions catch this one */
1878 #if defined(ENABLE_VMLOG)
1879 vmlog_cacao_unwnd_method(m);
1884 #endif /* defined(ENABLE_JIT) */
1887 /* exceptions_print_exception **************************************************
1889 Prints an exception, the detail message and the cause, if
1890 available, with CACAO internal functions to stdout.
1892 *******************************************************************************/
1894 void exceptions_print_exception(java_objectheader *xptr)
1896 java_lang_Throwable *t;
1897 #if defined(ENABLE_JAVASE)
1898 java_lang_Throwable *cause;
1902 t = (java_lang_Throwable *) xptr;
1909 #if defined(ENABLE_JAVASE)
1913 /* print the root exception */
1915 utf_display_printable_ascii_classname(t->header.vftbl->class->name);
1917 if (t->detailMessage != NULL) {
1918 u = javastring_toutf((java_objectheader *) t->detailMessage, false);
1921 utf_display_printable_ascii(u);
1926 #if defined(ENABLE_JAVASE)
1927 /* print the cause if available */
1929 if ((cause != NULL) && (cause != t)) {
1930 printf("Caused by: ");
1931 utf_display_printable_ascii_classname(cause->header.vftbl->class->name);
1933 if (cause->detailMessage != NULL) {
1934 u = javastring_toutf((java_objectheader *) cause->detailMessage,
1938 utf_display_printable_ascii(u);
1947 /* exceptions_print_current_exception ******************************************
1949 Prints the current pending exception, the detail message and the
1950 cause, if available, with CACAO internal functions to stdout.
1952 *******************************************************************************/
1954 void exceptions_print_current_exception(void)
1956 java_objectheader *xptr;
1958 xptr = *exceptionptr;
1960 exceptions_print_exception(xptr);
1964 /* exceptions_print_stacktrace *************************************************
1966 Prints a pending exception with Throwable.printStackTrace(). If
1967 there happens an exception during printStackTrace(), we print the
1968 thrown exception and the original one.
1970 NOTE: This function calls Java code.
1972 *******************************************************************************/
1974 void exceptions_print_stacktrace(void)
1976 java_objectheader *oxptr;
1977 java_objectheader *xptr;
1981 /* get original exception */
1983 oxptr = *exceptionptr;
1986 vm_abort("exceptions_print_stacktrace: no exception thrown");
1988 /* clear exception, because we are calling jit code again */
1990 *exceptionptr = NULL;
1992 c = oxptr->vftbl->class;
1994 /* find the printStackTrace() method */
1996 m = class_resolveclassmethod(c,
1997 utf_printStackTrace,
1999 class_java_lang_Object,
2003 vm_abort("exceptions_print_stacktrace: printStackTrace()V not found");
2005 /* print compatibility message */
2007 fprintf(stderr, "Exception in thread \"main\" ");
2009 /* print the stacktrace */
2011 (void) vm_call_method(m, oxptr);
2013 /* This normally means, we are EXTREMLY out of memory or
2014 have a serious problem while printStackTrace. But may
2015 be another exception, so print it. */
2017 xptr = *exceptionptr;
2020 fprintf(stderr, "Exception while printStackTrace(): ");
2022 /* now print original exception */
2024 exceptions_print_exception(xptr);
2025 stacktrace_print_trace(xptr);
2027 /* now print original exception */
2029 fprintf(stderr, "Original exception was: ");
2030 exceptions_print_exception(oxptr);
2031 stacktrace_print_trace(oxptr);
2039 * These are local overrides for various environment variables in Emacs.
2040 * Please do not remove this and leave it at the end of the file, where
2041 * Emacs will automagically detect them.
2042 * ---------------------------------------------------------------------
2045 * indent-tabs-mode: t
2049 * vim:noexpandtab:sw=4:ts=4: