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 8145 2007-06-27 08:54:10Z michi $
43 #include "mm/memory.h"
45 #include "native/jni.h"
46 #include "native/native.h"
48 #include "native/include/java_lang_String.h"
49 #include "native/include/java_lang_Throwable.h"
51 #include "threads/lock-common.h"
52 #include "threads/threads-common.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/patcher-common.h"
68 #include "vm/jit/stacktrace.h"
70 #include "vmcore/class.h"
71 #include "vmcore/loader.h"
72 #include "vmcore/method.h"
73 #include "vmcore/options.h"
75 #if defined(ENABLE_VMLOG)
76 #include <vmlog_cacao.h>
80 /* for raising exceptions from native methods *********************************/
82 #if !defined(ENABLE_THREADS)
83 java_objectheader *_no_threads_exceptionptr = NULL;
87 /* init_system_exceptions ******************************************************
89 Load and link exceptions used in the system.
91 *******************************************************************************/
93 bool exceptions_init(void)
97 /* mmap a memory page at address 0x0, so our hardware-exceptions
100 pagesize = getpagesize();
102 (void) memory_mmap_anon(NULL, pagesize, PROT_NONE, MAP_PRIVATE | MAP_FIXED);
104 /* check if we get into trouble with our hardware-exceptions */
106 if (OFFSET(java_bytearray, data) <= EXCEPTION_HARDWARE_PATCHER)
107 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);
109 /* java/lang/Throwable */
111 if (!(class_java_lang_Throwable =
112 load_class_bootstrap(utf_java_lang_Throwable)) ||
113 !link_class(class_java_lang_Throwable))
116 /* java/lang/Error */
118 if (!(class_java_lang_Error = load_class_bootstrap(utf_java_lang_Error)) ||
119 !link_class(class_java_lang_Error))
122 #if defined(ENABLE_JAVASE)
123 /* java/lang/LinkageError */
125 if (!(class_java_lang_LinkageError =
126 load_class_bootstrap(utf_java_lang_LinkageError)) ||
127 !link_class(class_java_lang_LinkageError))
131 /* java/lang/NoClassDefFoundError */
133 if (!(class_java_lang_NoClassDefFoundError =
134 load_class_bootstrap(utf_java_lang_NoClassDefFoundError)) ||
135 !link_class(class_java_lang_NoClassDefFoundError))
138 /* java/lang/OutOfMemoryError */
140 if (!(class_java_lang_OutOfMemoryError =
141 load_class_bootstrap(utf_java_lang_OutOfMemoryError)) ||
142 !link_class(class_java_lang_OutOfMemoryError))
145 /* java/lang/VirtualMachineError */
147 if (!(class_java_lang_VirtualMachineError =
148 load_class_bootstrap(utf_java_lang_VirtualMachineError)) ||
149 !link_class(class_java_lang_VirtualMachineError))
153 /* java/lang/Exception */
155 if (!(class_java_lang_Exception =
156 load_class_bootstrap(utf_java_lang_Exception)) ||
157 !link_class(class_java_lang_Exception))
160 /* java/lang/ClassCastException */
162 if (!(class_java_lang_ClassCastException =
163 load_class_bootstrap(utf_java_lang_ClassCastException)) ||
164 !link_class(class_java_lang_ClassCastException))
167 /* java/lang/ClassNotFoundException */
169 if (!(class_java_lang_ClassNotFoundException =
170 load_class_bootstrap(utf_java_lang_ClassNotFoundException)) ||
171 !link_class(class_java_lang_ClassNotFoundException))
174 /* java/lang/NullPointerException */
176 if (!(class_java_lang_NullPointerException =
177 load_class_bootstrap(utf_java_lang_NullPointerException)) ||
178 !link_class(class_java_lang_NullPointerException))
182 #if defined(WITH_CLASSPATH_GNU)
183 /* java/lang/VMThrowable */
185 if (!(class_java_lang_VMThrowable =
186 load_class_bootstrap(utf_java_lang_VMThrowable)) ||
187 !link_class(class_java_lang_VMThrowable))
195 /* exceptions_get_exception ****************************************************
197 Returns the current exception pointer of the current thread.
199 *******************************************************************************/
201 java_objectheader *exceptions_get_exception(void)
203 /* return the exception */
205 return *exceptionptr;
209 /* exceptions_set_exception ****************************************************
211 Sets the exception pointer of the current thread.
213 *******************************************************************************/
215 void exceptions_set_exception(java_objectheader *o)
217 /* set the exception */
223 /* exceptions_clear_exception **************************************************
225 Clears the current exception pointer of the current thread.
227 *******************************************************************************/
229 void exceptions_clear_exception(void)
231 exceptions_set_exception(NULL);
235 /* exceptions_get_and_clear_exception ******************************************
237 Gets the exception pointer of the current thread and clears it.
238 This function may return NULL.
240 *******************************************************************************/
242 java_objectheader *exceptions_get_and_clear_exception(void)
244 java_objectheader *o;
246 /* get the exception */
248 o = exceptions_get_exception();
250 /* and clear the exception */
252 exceptions_clear_exception();
254 /* return the exception */
260 /* exceptions_new_class ********************************************************
262 Creates an exception object from the given class and initalizes it.
265 class....class pointer
267 *******************************************************************************/
269 static java_objectheader *exceptions_new_class(classinfo *c)
271 java_objectheader *o;
273 o = native_new_and_init(c);
276 return exceptions_get_exception();
282 /* exceptions_new_utf **********************************************************
284 Creates an exception object with the given name and initalizes it.
287 classname....class name in UTF-8
289 *******************************************************************************/
291 static java_objectheader *exceptions_new_utf(utf *classname)
294 java_objectheader *o;
296 c = load_class_bootstrap(classname);
299 return exceptions_get_exception();
301 o = exceptions_new_class(c);
307 /* exceptions_throw_class ******************************************************
309 Creates an exception object from the given class, initalizes and
313 class....class pointer
315 *******************************************************************************/
317 static void exceptions_throw_class(classinfo *c)
319 java_objectheader *o;
321 o = exceptions_new_class(c);
326 exceptions_set_exception(o);
330 /* exceptions_throw_utf ********************************************************
332 Creates an exception object with the given name, initalizes and
336 classname....class name in UTF-8
338 *******************************************************************************/
340 static void exceptions_throw_utf(utf *classname)
344 c = load_class_bootstrap(classname);
349 exceptions_throw_class(c);
353 /* exceptions_throw_utf_throwable **********************************************
355 Creates an exception object with the given name and initalizes it
356 with the given java/lang/Throwable exception.
359 classname....class name in UTF-8
360 cause........the given Throwable
362 *******************************************************************************/
364 static void exceptions_throw_utf_throwable(utf *classname,
365 java_objectheader *cause)
368 java_objectheader *o;
370 java_lang_Throwable *object;
372 object = (java_lang_Throwable *) cause;
374 c = load_class_bootstrap(classname);
386 /* call initializer */
388 m = class_resolveclassmethod(c,
390 utf_java_lang_Throwable__void,
397 (void) vm_call_method(m, o, cause);
399 exceptions_set_exception(o);
403 /* exceptions_throw_utf_exception **********************************************
405 Creates an exception object with the given name and initalizes it
406 with the given java/lang/Exception exception.
409 classname....class name in UTF-8
410 exception....the given Exception
412 *******************************************************************************/
414 static void exceptions_throw_utf_exception(utf *classname,
415 java_objectheader *exception)
418 java_objectheader *o;
421 c = load_class_bootstrap(classname);
433 /* call initializer */
435 m = class_resolveclassmethod(c,
437 utf_java_lang_Exception__V,
444 (void) vm_call_method(m, o, exception);
446 exceptions_set_exception(o);
450 /* exceptions_throw_utf_cause **************************************************
452 Creates an exception object with the given name and initalizes it
453 with the given java/lang/Throwable exception with initCause.
456 classname....class name in UTF-8
457 cause........the given Throwable
459 *******************************************************************************/
461 static void exceptions_throw_utf_cause(utf *classname, java_objectheader *cause)
464 java_objectheader *o;
466 java_lang_Throwable *object;
468 object = (java_lang_Throwable *) cause;
470 c = load_class_bootstrap(classname);
482 /* call initializer */
484 m = class_resolveclassmethod(c,
486 utf_java_lang_String__void,
493 (void) vm_call_method(m, o, object->detailMessage);
497 m = class_resolveclassmethod(c,
499 utf_java_lang_Throwable__java_lang_Throwable,
506 (void) vm_call_method(m, o, cause);
508 exceptions_set_exception(o);
512 /* exceptions_new_utf_javastring ***********************************************
514 Creates an exception object with the given name and initalizes it
515 with the given java/lang/String message.
518 classname....class name in UTF-8
519 message......the message as a java.lang.String
522 an exception pointer (in any case -- either it is the newly created
523 exception, or an exception thrown while trying to create it).
525 *******************************************************************************/
527 static java_objectheader *exceptions_new_utf_javastring(utf *classname,
528 java_objectheader *message)
530 java_objectheader *o;
533 c = load_class_bootstrap(classname);
536 return exceptions_get_exception();
538 o = native_new_and_init_string(c, message);
541 return exceptions_get_exception();
547 /* exceptions_new_class_utf ****************************************************
549 Creates an exception object of the given class and initalizes it.
552 c..........class pointer
553 message....the message as UTF-8 string
555 *******************************************************************************/
557 static java_objectheader *exceptions_new_class_utf(classinfo *c, utf *message)
559 java_objectheader *o;
560 java_objectheader *s;
562 s = javastring_new(message);
565 return exceptions_get_exception();
567 o = native_new_and_init_string(c, s);
570 return exceptions_get_exception();
576 /* exceptions_new_utf_utf ******************************************************
578 Creates an exception object with the given name and initalizes it
579 with the given utf message.
582 classname....class name in UTF-8
583 message......the message as an utf *
586 an exception pointer (in any case -- either it is the newly created
587 exception, or an exception thrown while trying to create it).
589 *******************************************************************************/
591 static java_objectheader *exceptions_new_utf_utf(utf *classname, utf *message)
594 java_objectheader *o;
596 c = load_class_bootstrap(classname);
599 return exceptions_get_exception();
601 o = exceptions_new_class_utf(c, message);
607 /* exceptions_throw_class_utf **************************************************
609 Creates an exception object of the given class, initalizes and
610 throws it with the given utf message.
613 c..........class pointer
614 message....the message as an UTF-8
616 *******************************************************************************/
618 static void exceptions_throw_class_utf(classinfo *c, utf *message)
620 java_objectheader *o;
622 o = exceptions_new_class_utf(c, message);
624 exceptions_set_exception(o);
628 /* exceptions_throw_utf_utf ****************************************************
630 Creates an exception object with the given name, initalizes and
631 throws it with the given utf message.
634 classname....class name in UTF-8
635 message......the message as an utf *
637 *******************************************************************************/
639 static void exceptions_throw_utf_utf(utf *classname, utf *message)
641 java_objectheader *o;
643 o = exceptions_new_utf_utf(classname, message);
645 exceptions_set_exception(o);
649 /* exceptions_new_abstractmethoderror ****************************************
651 Generates a java.lang.AbstractMethodError for the VM.
653 *******************************************************************************/
655 java_objectheader *exceptions_new_abstractmethoderror(void)
657 java_objectheader *o;
659 o = exceptions_new_utf(utf_java_lang_AbstractMethodError);
665 /* exceptions_new_error ********************************************************
667 Generates a java.lang.Error for the VM.
669 *******************************************************************************/
671 #if defined(ENABLE_JAVAME_CLDC1_1)
672 static java_objectheader *exceptions_new_error(utf *message)
674 java_objectheader *o;
676 o = exceptions_new_class_utf(class_java_lang_Error, message);
683 /* exceptions_asm_new_abstractmethoderror **************************************
685 Generates a java.lang.AbstractMethodError for
686 asm_abstractmethoderror.
688 *******************************************************************************/
690 java_objectheader *exceptions_asm_new_abstractmethoderror(u1 *sp, u1 *ra)
693 java_objectheader *e;
695 /* create the stackframeinfo (XPC is equal to RA) */
697 stacktrace_create_extern_stackframeinfo(&sfi, NULL, sp, ra, ra);
699 /* create the exception */
701 #if defined(ENABLE_JAVASE)
702 e = exceptions_new_abstractmethoderror();
704 e = exceptions_new_error(utf_java_lang_AbstractMethodError);
707 /* remove the stackframeinfo */
709 stacktrace_remove_stackframeinfo(&sfi);
715 /* exceptions_new_arraystoreexception ******************************************
717 Generates a java.lang.ArrayStoreException for the VM.
719 *******************************************************************************/
721 java_objectheader *exceptions_new_arraystoreexception(void)
723 java_objectheader *o;
725 o = exceptions_new_utf(utf_java_lang_ArrayStoreException);
731 /* exceptions_throw_abstractmethoderror ****************************************
733 Generates and throws a java.lang.AbstractMethodError for the VM.
735 *******************************************************************************/
737 void exceptions_throw_abstractmethoderror(void)
739 exceptions_throw_utf(utf_java_lang_AbstractMethodError);
743 /* exceptions_throw_classcircularityerror **************************************
745 Generates and throws a java.lang.ClassCircularityError for the
749 c....the class in which the error was found
751 *******************************************************************************/
753 void exceptions_throw_classcircularityerror(classinfo *c)
755 exceptions_throw_utf_utf(utf_java_lang_ClassCircularityError, c->name);
759 /* exceptions_throw_classformaterror *******************************************
761 Generates and throws a java.lang.ClassFormatError for the VM.
764 c............the class in which the error was found
765 message......UTF-8 format string
767 *******************************************************************************/
769 void exceptions_throw_classformaterror(classinfo *c, const char *message, ...)
776 /* calculate message length */
781 msglen += utf_bytes(c->name) + strlen(" (");
783 va_start(ap, message);
784 msglen += get_variable_message_length(message, ap);
788 msglen += strlen(")");
790 msglen += strlen("0");
792 /* allocate a buffer */
794 msg = MNEW(char, msglen);
796 /* print message into allocated buffer */
799 utf_copy_classname(msg, c->name);
803 va_start(ap, message);
804 vsprintf(msg + strlen(msg), message, ap);
810 u = utf_new_char(msg);
814 MFREE(msg, char, msglen);
816 /* throw exception */
818 exceptions_throw_utf_utf(utf_java_lang_ClassFormatError, u);
822 /* exceptions_throw_classnotfoundexception *************************************
824 Generates and throws a java.lang.ClassNotFoundException for the
828 name.........name of the class not found as a utf *
830 *******************************************************************************/
832 void exceptions_throw_classnotfoundexception(utf *name)
834 /* we use class here, as this one is rather frequent */
836 exceptions_throw_class_utf(class_java_lang_ClassNotFoundException, name);
840 /* exceptions_throw_noclassdeffounderror ***************************************
842 Generates and throws a java.lang.NoClassDefFoundError.
845 name.........name of the class not found as a utf *
847 *******************************************************************************/
849 void exceptions_throw_noclassdeffounderror(utf *name)
852 vm_abort("java.lang.NoClassDefFoundError: %s", name->text);
854 exceptions_throw_class_utf(class_java_lang_NoClassDefFoundError, name);
858 /* exceptions_throw_noclassdeffounderror_cause *********************************
860 Generates and throws a java.lang.NoClassDefFoundError with the
863 *******************************************************************************/
865 void exceptions_throw_noclassdeffounderror_cause(java_objectheader *cause)
867 exceptions_throw_utf_cause(utf_java_lang_NoClassDefFoundError, cause);
871 /* exceptions_throw_noclassdeffounderror_wrong_name ****************************
873 Generates and throws a java.lang.NoClassDefFoundError with a
877 name.........name of the class not found as a utf *
879 *******************************************************************************/
881 void exceptions_throw_noclassdeffounderror_wrong_name(classinfo *c, utf *name)
887 msglen = utf_bytes(c->name) + strlen(" (wrong name: ") +
888 utf_bytes(name) + strlen(")") + strlen("0");
890 msg = MNEW(char, msglen);
892 utf_copy_classname(msg, c->name);
893 strcat(msg, " (wrong name: ");
894 utf_cat_classname(msg, name);
897 u = utf_new_char(msg);
899 MFREE(msg, char, msglen);
901 exceptions_throw_noclassdeffounderror(u);
905 /* exceptions_throw_exceptionininitializererror ********************************
907 Generates and throws a java.lang.ExceptionInInitializerError for
911 cause......cause exception object
913 *******************************************************************************/
915 void exceptions_throw_exceptionininitializererror(java_objectheader *cause)
917 exceptions_throw_utf_throwable(utf_java_lang_ExceptionInInitializerError,
922 /* exceptions_throw_incompatibleclasschangeerror *******************************
924 Generates and throws a java.lang.IncompatibleClassChangeError for
928 message......UTF-8 message format string
930 *******************************************************************************/
932 void exceptions_throw_incompatibleclasschangeerror(classinfo *c, const char *message)
938 /* calculate exception message length */
940 msglen = utf_bytes(c->name) + strlen(message) + strlen("0");
942 /* allocate memory */
944 msg = MNEW(char, msglen);
946 utf_copy_classname(msg, c->name);
947 strcat(msg, message);
949 u = utf_new_char(msg);
953 MFREE(msg, char, msglen);
955 /* throw exception */
957 exceptions_throw_utf_utf(utf_java_lang_IncompatibleClassChangeError, u);
961 /* exceptions_throw_instantiationerror *****************************************
963 Generates and throws a java.lang.InstantiationError for the VM.
965 *******************************************************************************/
967 void exceptions_throw_instantiationerror(classinfo *c)
969 exceptions_throw_utf_utf(utf_java_lang_InstantiationError, c->name);
973 /* exceptions_throw_internalerror **********************************************
975 Generates and throws a java.lang.InternalError for the VM.
978 message......UTF-8 message format string
980 *******************************************************************************/
982 void exceptions_throw_internalerror(const char *message, ...)
989 /* calculate exception message length */
991 va_start(ap, message);
992 msglen = get_variable_message_length(message, ap);
995 /* allocate memory */
997 msg = MNEW(char, msglen);
999 /* generate message */
1001 va_start(ap, message);
1002 vsprintf(msg, message, ap);
1005 u = utf_new_char(msg);
1009 MFREE(msg, char, msglen);
1011 /* throw exception */
1013 exceptions_throw_utf_utf(utf_java_lang_InternalError, u);
1017 /* exceptions_throw_linkageerror ***********************************************
1019 Generates and throws java.lang.LinkageError with an error message.
1022 message......UTF-8 message
1023 c............class related to the error. If this is != NULL
1024 the name of c is appended to the error message.
1026 *******************************************************************************/
1028 void exceptions_throw_linkageerror(const char *message, classinfo *c)
1030 java_objectheader *o;
1034 /* calculate exception message length */
1036 msglen = strlen(message) + 1;
1039 msglen += utf_bytes(c->name);
1041 /* allocate memory */
1043 msg = MNEW(char, msglen);
1045 /* generate message */
1047 strcpy(msg,message);
1050 utf_cat_classname(msg, c->name);
1052 o = native_new_and_init_string(class_java_lang_LinkageError,
1053 javastring_new_from_utf_string(msg));
1057 MFREE(msg, char, msglen);
1062 exceptions_set_exception(o);
1066 /* exceptions_throw_nosuchfielderror *******************************************
1068 Generates and throws a java.lang.NoSuchFieldError with an error
1072 c............class in which the field was not found
1073 name.........name of the field
1075 *******************************************************************************/
1077 void exceptions_throw_nosuchfielderror(classinfo *c, utf *name)
1083 /* calculate exception message length */
1085 msglen = utf_bytes(c->name) + strlen(".") + utf_bytes(name) + strlen("0");
1087 /* allocate memory */
1089 msg = MNEW(char, msglen);
1091 /* generate message */
1093 utf_copy_classname(msg, c->name);
1097 u = utf_new_char(msg);
1101 MFREE(msg, char, msglen);
1103 exceptions_throw_utf_utf(utf_java_lang_NoSuchFieldError, u);
1107 /* exceptions_throw_nosuchmethoderror ******************************************
1109 Generates and throws a java.lang.NoSuchMethodError with an error
1113 c............class in which the method was not found
1114 name.........name of the method
1115 desc.........descriptor of the method
1117 *******************************************************************************/
1119 void exceptions_throw_nosuchmethoderror(classinfo *c, utf *name, utf *desc)
1125 /* calculate exception message length */
1127 msglen = utf_bytes(c->name) + strlen(".") + utf_bytes(name) +
1128 utf_bytes(desc) + strlen("0");
1130 /* allocate memory */
1132 msg = MNEW(char, msglen);
1134 /* generate message */
1136 utf_copy_classname(msg, c->name);
1141 u = utf_new_char(msg);
1145 MFREE(msg, char, msglen);
1147 #if defined(ENABLE_JAVASE)
1148 exceptions_throw_utf_utf(utf_java_lang_NoSuchMethodError, u);
1150 exceptions_throw_class_utf(class_java_lang_Error, u);
1155 /* exceptions_throw_outofmemoryerror *******************************************
1157 Generates and throws an java.lang.OutOfMemoryError for the VM.
1159 *******************************************************************************/
1161 void exceptions_throw_outofmemoryerror(void)
1163 exceptions_throw_class(class_java_lang_OutOfMemoryError);
1167 /* exceptions_throw_unsatisfiedlinkerror ***************************************
1169 Generates and throws a java.lang.UnsatisfiedLinkError for the
1173 name......UTF-8 name string
1175 *******************************************************************************/
1177 void exceptions_throw_unsatisfiedlinkerror(utf *name)
1179 #if defined(ENABLE_JAVASE)
1180 exceptions_throw_utf_utf(utf_java_lang_UnsatisfiedLinkError, name);
1182 exceptions_throw_class_utf(class_java_lang_Error, name);
1187 /* exceptions_throw_unsupportedclassversionerror *******************************
1189 Generates and throws a java.lang.UnsupportedClassVersionError for
1193 c............class in which the method was not found
1194 message......UTF-8 format string
1196 *******************************************************************************/
1198 void exceptions_throw_unsupportedclassversionerror(classinfo *c, u4 ma, u4 mi)
1204 /* calculate exception message length */
1207 utf_bytes(c->name) +
1208 strlen(" (Unsupported major.minor version 00.0)") +
1211 /* allocate memory */
1213 msg = MNEW(char, msglen);
1215 /* generate message */
1217 utf_copy_classname(msg, c->name);
1218 sprintf(msg + strlen(msg), " (Unsupported major.minor version %d.%d)",
1221 u = utf_new_char(msg);
1225 MFREE(msg, char, msglen);
1227 /* throw exception */
1229 exceptions_throw_utf_utf(utf_java_lang_UnsupportedClassVersionError, u);
1233 /* exceptions_throw_verifyerror ************************************************
1235 Generates and throws a java.lang.VerifyError for the JIT compiler.
1238 m............method in which the error was found
1239 message......UTF-8 format string
1241 *******************************************************************************/
1243 void exceptions_throw_verifyerror(methodinfo *m, const char *message, ...)
1250 /* calculate exception message length */
1256 strlen("(class: ") + utf_bytes(m->class->name) +
1257 strlen(", method: ") + utf_bytes(m->name) +
1258 strlen(" signature: ") + utf_bytes(m->descriptor) +
1259 strlen(") ") + strlen("0");
1261 va_start(ap, message);
1262 msglen += get_variable_message_length(message, ap);
1265 /* allocate memory */
1267 msg = MNEW(char, msglen);
1269 /* generate message */
1272 strcpy(msg, "(class: ");
1273 utf_cat_classname(msg, m->class->name);
1274 strcat(msg, ", method: ");
1275 utf_cat(msg, m->name);
1276 strcat(msg, " signature: ");
1277 utf_cat(msg, m->descriptor);
1281 va_start(ap, message);
1282 vsprintf(msg + strlen(msg), message, ap);
1285 u = utf_new_char(msg);
1289 MFREE(msg, char, msglen);
1291 /* throw exception */
1293 exceptions_throw_utf_utf(utf_java_lang_VerifyError, u);
1297 /* exceptions_throw_verifyerror_for_stack **************************************
1299 throws a java.lang.VerifyError for an invalid stack slot type
1302 m............method in which the error was found
1303 type.........the expected type
1306 an exception pointer (in any case -- either it is the newly created
1307 exception, or an exception thrown while trying to create it).
1309 *******************************************************************************/
1311 void exceptions_throw_verifyerror_for_stack(methodinfo *m, int type)
1318 /* calculate exception message length */
1323 msglen = strlen("(class: ") + utf_bytes(m->class->name) +
1324 strlen(", method: ") + utf_bytes(m->name) +
1325 strlen(" signature: ") + utf_bytes(m->descriptor) +
1326 strlen(") Expecting to find longest-------typename on stack")
1329 /* allocate memory */
1331 msg = MNEW(char, msglen);
1333 /* generate message */
1336 strcpy(msg, "(class: ");
1337 utf_cat_classname(msg, m->class->name);
1338 strcat(msg, ", method: ");
1339 utf_cat(msg, m->name);
1340 strcat(msg, " signature: ");
1341 utf_cat(msg, m->descriptor);
1348 strcat(msg, "Expecting to find ");
1351 case TYPE_INT: typename = "integer"; break;
1352 case TYPE_LNG: typename = "long"; break;
1353 case TYPE_FLT: typename = "float"; break;
1354 case TYPE_DBL: typename = "double"; break;
1355 case TYPE_ADR: typename = "object/array"; break;
1356 case TYPE_RET: typename = "returnAddress"; break;
1357 default: typename = "<INVALID>"; assert(0); break;
1360 strcat(msg, typename);
1361 strcat(msg, " on stack");
1363 u = utf_new_char(msg);
1367 MFREE(msg, char, msglen);
1369 /* throw exception */
1371 exceptions_throw_utf_utf(utf_java_lang_VerifyError, u);
1375 /* exceptions_new_arithmeticexception ******************************************
1377 Generates a java.lang.ArithmeticException for the JIT compiler.
1379 *******************************************************************************/
1381 java_objectheader *exceptions_new_arithmeticexception(void)
1383 java_objectheader *o;
1385 o = exceptions_new_utf_utf(utf_java_lang_ArithmeticException,
1386 utf_division_by_zero);
1392 /* exceptions_new_arrayindexoutofboundsexception *******************************
1394 Generates a java.lang.ArrayIndexOutOfBoundsException for the VM
1397 *******************************************************************************/
1399 java_objectheader *exceptions_new_arrayindexoutofboundsexception(s4 index)
1401 java_objectheader *o;
1403 java_objectheader *s;
1405 /* convert the index into a String, like Sun does */
1407 m = class_resolveclassmethod(class_java_lang_String,
1408 utf_new_char("valueOf"),
1409 utf_new_char("(I)Ljava/lang/String;"),
1410 class_java_lang_Object,
1414 return exceptions_get_exception();
1416 s = vm_call_method(m, NULL, index);
1419 return exceptions_get_exception();
1421 o = exceptions_new_utf_javastring(utf_java_lang_ArrayIndexOutOfBoundsException,
1425 return exceptions_get_exception();
1431 /* exceptions_throw_arrayindexoutofboundsexception *****************************
1433 Generates and throws a java.lang.ArrayIndexOutOfBoundsException for
1436 *******************************************************************************/
1438 void exceptions_throw_arrayindexoutofboundsexception(void)
1440 exceptions_throw_utf(utf_java_lang_ArrayIndexOutOfBoundsException);
1444 /* exceptions_throw_arraystoreexception ****************************************
1446 Generates and throws a java.lang.ArrayStoreException for the VM.
1448 *******************************************************************************/
1450 void exceptions_throw_arraystoreexception(void)
1452 exceptions_throw_utf(utf_java_lang_ArrayStoreException);
1453 /* e = native_new_and_init(class_java_lang_ArrayStoreException); */
1457 /* exceptions_new_classcastexception *******************************************
1459 Generates a java.lang.ClassCastException for the JIT compiler.
1461 *******************************************************************************/
1463 java_objectheader *exceptions_new_classcastexception(java_objectheader *o)
1465 java_objectheader *e;
1468 classname = o->vftbl->class->name;
1470 e = exceptions_new_class_utf(class_java_lang_ClassCastException, classname);
1476 /* exceptions_throw_clonenotsupportedexception *********************************
1478 Generates and throws a java.lang.CloneNotSupportedException for the
1481 *******************************************************************************/
1483 void exceptions_throw_clonenotsupportedexception(void)
1485 exceptions_throw_utf(utf_java_lang_CloneNotSupportedException);
1489 /* exceptions_throw_illegalaccessexception *************************************
1491 Generates and throws a java.lang.IllegalAccessException for the VM.
1493 *******************************************************************************/
1495 void exceptions_throw_illegalaccessexception(utf *message)
1497 exceptions_throw_utf_utf(utf_java_lang_IllegalAccessException, message);
1501 /* exceptions_throw_illegalargumentexception ***********************************
1503 Generates and throws a java.lang.IllegalArgumentException for the
1506 *******************************************************************************/
1508 void exceptions_throw_illegalargumentexception(void)
1510 exceptions_throw_utf(utf_java_lang_IllegalArgumentException);
1514 /* exceptions_throw_illegalmonitorstateexception *******************************
1516 Generates and throws a java.lang.IllegalMonitorStateException for
1519 *******************************************************************************/
1521 void exceptions_throw_illegalmonitorstateexception(void)
1523 exceptions_throw_utf(utf_java_lang_IllegalMonitorStateException);
1527 /* exceptions_throw_instantiationexception *************************************
1529 Generates and throws a java.lang.InstantiationException for the VM.
1531 *******************************************************************************/
1533 void exceptions_throw_instantiationexception(classinfo *c)
1535 exceptions_throw_utf_utf(utf_java_lang_InstantiationException, c->name);
1539 /* exceptions_throw_interruptedexception ***************************************
1541 Generates and throws a java.lang.InterruptedException for the VM.
1543 *******************************************************************************/
1545 void exceptions_throw_interruptedexception(void)
1547 exceptions_throw_utf(utf_java_lang_InterruptedException);
1551 /* exceptions_throw_invocationtargetexception **********************************
1553 Generates and throws a java.lang.reflect.InvocationTargetException
1557 cause......cause exception object
1559 *******************************************************************************/
1561 void exceptions_throw_invocationtargetexception(java_objectheader *cause)
1563 exceptions_throw_utf_throwable(utf_java_lang_reflect_InvocationTargetException,
1568 /* exceptions_throw_negativearraysizeexception *********************************
1570 Generates and throws a java.lang.NegativeArraySizeException for the
1573 *******************************************************************************/
1575 void exceptions_throw_negativearraysizeexception(void)
1577 exceptions_throw_utf(utf_java_lang_NegativeArraySizeException);
1581 /* exceptions_new_nullpointerexception *****************************************
1583 Generates a java.lang.NullPointerException for the VM system.
1585 *******************************************************************************/
1587 java_objectheader *exceptions_new_nullpointerexception(void)
1589 java_objectheader *o;
1591 o = exceptions_new_class(class_java_lang_NullPointerException);
1597 /* exceptions_throw_nullpointerexception ***************************************
1599 Generates a java.lang.NullPointerException for the VM system and
1600 throw it in the VM system.
1602 *******************************************************************************/
1604 void exceptions_throw_nullpointerexception(void)
1606 exceptions_throw_class(class_java_lang_NullPointerException);
1610 /* exceptions_throw_privilegedactionexception **********************************
1612 Generates and throws a java.security.PrivilegedActionException.
1614 *******************************************************************************/
1616 void exceptions_throw_privilegedactionexception(java_objectheader *exception)
1618 exceptions_throw_utf_exception(utf_java_security_PrivilegedActionException,
1623 /* exceptions_throw_stringindexoutofboundsexception ****************************
1625 Generates and throws a java.lang.StringIndexOutOfBoundsException
1628 *******************************************************************************/
1630 void exceptions_throw_stringindexoutofboundsexception(void)
1632 exceptions_throw_utf(utf_java_lang_StringIndexOutOfBoundsException);
1636 /* exceptions_classnotfoundexception_to_noclassdeffounderror *******************
1638 Check the exception for a ClassNotFoundException. If it is one,
1639 convert it to a NoClassDefFoundError.
1641 *******************************************************************************/
1643 void exceptions_classnotfoundexception_to_noclassdeffounderror(void)
1645 java_objectheader *o;
1646 java_objectheader *cause;
1647 java_lang_Throwable *object;
1648 java_objectheader *s;
1652 cause = exceptions_get_exception();
1654 /* convert ClassNotFoundException's to NoClassDefFoundError's */
1656 if (builtin_instanceof(cause, class_java_lang_ClassNotFoundException)) {
1657 /* clear exception, because we are calling jit code again */
1659 exceptions_clear_exception();
1661 /* create new error */
1663 object = (java_lang_Throwable *) cause;
1664 s = (java_objectheader *) object->detailMessage;
1666 o = exceptions_new_utf_javastring(utf_java_lang_NoClassDefFoundError,
1669 /* we had an exception while creating the error */
1671 if (exceptions_get_exception())
1674 /* set new exception */
1676 exceptions_set_exception(o);
1681 /* exceptions_fillinstacktrace *************************************************
1683 Calls the fillInStackTrace-method of the currently thrown
1686 *******************************************************************************/
1688 java_objectheader *exceptions_fillinstacktrace(void)
1690 java_objectheader *o;
1695 o = exceptions_get_and_clear_exception();
1699 /* resolve methodinfo pointer from exception object */
1701 #if defined(ENABLE_JAVASE)
1702 m = class_resolvemethod(o->vftbl->class,
1703 utf_fillInStackTrace,
1704 utf_void__java_lang_Throwable);
1705 #elif defined(ENABLE_JAVAME_CLDC1_1)
1706 m = class_resolvemethod(o->vftbl->class,
1707 utf_fillInStackTrace,
1710 #error IMPLEMENT ME!
1715 (void) vm_call_method(m, o);
1717 /* return exception object */
1723 /* exceptions_new_hardware_exception *******************************************
1725 Creates the correct exception for a hardware-exception thrown and
1726 caught by a signal handler.
1728 *******************************************************************************/
1730 java_objectheader *exceptions_new_hardware_exception(u1 *pv, u1 *sp, u1 *ra, u1 *xpc, s4 type, ptrint val)
1733 java_objectheader *e;
1734 java_objectheader *o;
1737 /* create stackframeinfo */
1739 stacktrace_create_extern_stackframeinfo(&sfi, pv, sp, ra, xpc);
1742 case EXCEPTION_HARDWARE_NULLPOINTER:
1743 e = exceptions_new_nullpointerexception();
1746 case EXCEPTION_HARDWARE_ARITHMETIC:
1747 e = exceptions_new_arithmeticexception();
1750 case EXCEPTION_HARDWARE_ARRAYINDEXOUTOFBOUNDS:
1752 e = exceptions_new_arrayindexoutofboundsexception(index);
1755 case EXCEPTION_HARDWARE_CLASSCAST:
1756 o = (java_objectheader *) val;
1757 e = exceptions_new_classcastexception(o);
1760 case EXCEPTION_HARDWARE_EXCEPTION:
1761 e = exceptions_fillinstacktrace();
1764 case EXCEPTION_HARDWARE_PATCHER:
1765 e = patcher_handler(xpc);
1769 /* let's try to get a backtrace */
1771 codegen_get_pv_from_pc(xpc);
1773 /* if that does not work, print more debug info */
1775 log_println("exceptions_new_hardware_exception: unknown exception type %d", type);
1777 #if SIZEOF_VOID_P == 8
1778 log_println("PC=0x%016lx", xpc);
1780 log_println("PC=0x%08x", xpc);
1783 #if defined(ENABLE_DISASSEMBLER)
1784 log_println("machine instruction at PC:");
1788 vm_abort("Exiting...");
1790 /* keep compiler happy */
1795 /* remove stackframeinfo */
1797 stacktrace_remove_stackframeinfo(&sfi);
1799 /* return the exception object */
1805 /* exceptions_handle_exception *************************************************
1807 Try to find an exception handler for the given exception and return it.
1808 If no handler is found, exit the monitor of the method (if any)
1812 xptr.........the exception object
1813 xpc..........PC of where the exception was thrown
1814 pv...........Procedure Value of the current method
1815 sp...........current stack pointer
1818 the address of the first matching exception handler, or
1819 NULL if no handler was found
1821 *******************************************************************************/
1823 #if defined(ENABLE_JIT)
1824 u1 *exceptions_handle_exception(java_objectheader *xptr, u1 *xpc, u1 *pv, u1 *sp)
1829 dseg_exception_entry *ex;
1830 s4 exceptiontablelength;
1832 classref_or_classinfo cr;
1834 #if defined(ENABLE_THREADS)
1835 java_objectheader *o;
1839 /* Addresses are 31 bit integers */
1840 # define ADDR_MASK(x) (u1 *)((u4)(x) & 0x7FFFFFFF)
1842 # define ADDR_MASK(x) (x)
1845 xpc = ADDR_MASK(xpc);
1847 /* get info from the method header */
1849 code = *((codeinfo **) (pv + CodeinfoPointer));
1850 issync = *((s4 *) (pv + IsSync));
1851 ex = (dseg_exception_entry *) (pv + ExTableStart);
1852 exceptiontablelength = *((s4 *) (pv + ExTableSize));
1854 /* Get the methodinfo pointer from the codeinfo pointer. For
1855 asm_vm_call_method the codeinfo pointer is NULL. */
1857 m = (code == NULL) ? NULL : code->m;
1859 #if !defined(NDEBUG)
1860 /* print exception trace */
1862 if (opt_verbose || opt_verbosecall || opt_TraceExceptions)
1863 builtin_trace_exception(xptr, m, xpc, 1);
1866 #if defined(ENABLE_VMLOG)
1867 vmlog_cacao_throw(xptr);
1870 for (i = 0; i < exceptiontablelength; i++) {
1871 /* ATTENTION: keep this here, as we need to decrement the
1872 pointer before the loop executes! */
1876 /* If the start and end PC is NULL, this means we have the
1877 special case of asm_vm_call_method. So, just return the
1878 proper exception handler. */
1880 if ((ex->startpc == NULL) && (ex->endpc == NULL))
1881 return (u1 *) (ptrint) &asm_vm_call_method_exception_handler;
1883 /* is the xpc is the current catch range */
1885 if ((ADDR_MASK(ex->startpc) <= xpc) && (xpc < ADDR_MASK(ex->endpc))) {
1888 /* NULL catches everything */
1890 if (cr.any == NULL) {
1891 #if !defined(NDEBUG)
1892 /* Print stacktrace of exception when caught. */
1894 #if defined(ENABLE_VMLOG)
1895 vmlog_cacao_catch(xptr);
1898 if (opt_TraceExceptions) {
1899 exceptions_print_exception(xptr);
1900 stacktrace_print_trace(xptr);
1904 return ex->handlerpc;
1907 /* resolve or load/link the exception class */
1909 if (IS_CLASSREF(cr)) {
1910 /* The exception class reference is unresolved. */
1911 /* We have to do _eager_ resolving here. While the class of */
1912 /* the exception object is guaranteed to be loaded, it may */
1913 /* well have been loaded by a different loader than the */
1914 /* defining loader of m's class, which is the one we must */
1915 /* use to resolve the catch class. Thus lazy resolving */
1916 /* might fail, even if the result of the resolution would */
1917 /* be an already loaded class. */
1919 c = resolve_classref_eager(cr.ref);
1922 /* Exception resolving the exception class, argh! */
1926 /* Ok, we resolved it. Enter it in the table, so we don't */
1927 /* have to do this again. */
1928 /* XXX this write should be atomic. Is it? */
1930 ex->catchtype.cls = c;
1934 /* XXX I don't think this case can ever happen. -Edwin */
1935 if (!(c->state & CLASS_LOADED))
1936 /* use the methods' classloader */
1937 if (!load_class_from_classloader(c->name,
1938 m->class->classloader))
1941 /* XXX I think, if it is not linked, we can be sure that */
1942 /* the exception object is no (indirect) instance of it, no? */
1944 if (!(c->state & CLASS_LINKED))
1949 /* is the thrown exception an instance of the catch class? */
1951 if (builtin_instanceof(xptr, c)) {
1952 #if !defined(NDEBUG)
1953 /* Print stacktrace of exception when caught. */
1955 #if defined(ENABLE_VMLOG)
1956 vmlog_cacao_catch(xptr);
1959 if (opt_TraceExceptions) {
1960 exceptions_print_exception(xptr);
1961 stacktrace_print_trace(xptr);
1965 return ex->handlerpc;
1970 #if defined(ENABLE_THREADS)
1971 /* is this method synchronized? */
1974 /* get synchronization object */
1976 # if defined(__MIPS__) && (SIZEOF_VOID_P == 4)
1977 /* XXX change this if we ever want to use 4-byte stackslots */
1978 o = *((java_objectheader **) (sp + issync - 8));
1980 o = *((java_objectheader **) (sp + issync - SIZEOF_VOID_P));
1985 lock_monitor_exit(o);
1989 /* none of the exceptions catch this one */
1991 #if defined(ENABLE_VMLOG)
1992 vmlog_cacao_unwnd_method(m);
1997 #endif /* defined(ENABLE_JIT) */
2000 /* exceptions_print_exception **************************************************
2002 Prints an exception, the detail message and the cause, if
2003 available, with CACAO internal functions to stdout.
2005 *******************************************************************************/
2007 void exceptions_print_exception(java_objectheader *xptr)
2009 java_lang_Throwable *t;
2010 #if defined(ENABLE_JAVASE)
2011 java_lang_Throwable *cause;
2015 t = (java_lang_Throwable *) xptr;
2022 #if defined(ENABLE_JAVASE)
2026 /* print the root exception */
2028 utf_display_printable_ascii_classname(t->header.vftbl->class->name);
2030 if (t->detailMessage != NULL) {
2031 u = javastring_toutf((java_objectheader *) t->detailMessage, false);
2034 utf_display_printable_ascii(u);
2039 #if defined(ENABLE_JAVASE)
2040 /* print the cause if available */
2042 if ((cause != NULL) && (cause != t)) {
2043 printf("Caused by: ");
2044 utf_display_printable_ascii_classname(cause->header.vftbl->class->name);
2046 if (cause->detailMessage != NULL) {
2047 u = javastring_toutf((java_objectheader *) cause->detailMessage,
2051 utf_display_printable_ascii(u);
2060 /* exceptions_print_current_exception ******************************************
2062 Prints the current pending exception, the detail message and the
2063 cause, if available, with CACAO internal functions to stdout.
2065 *******************************************************************************/
2067 void exceptions_print_current_exception(void)
2069 java_objectheader *o;
2071 o = exceptions_get_exception();
2073 exceptions_print_exception(o);
2077 /* exceptions_print_stacktrace *************************************************
2079 Prints a pending exception with Throwable.printStackTrace(). If
2080 there happens an exception during printStackTrace(), we print the
2081 thrown exception and the original one.
2083 NOTE: This function calls Java code.
2085 *******************************************************************************/
2087 void exceptions_print_stacktrace(void)
2089 java_objectheader *oxptr;
2090 java_objectheader *xptr;
2094 /* get original exception */
2096 oxptr = exceptions_get_and_clear_exception();
2099 vm_abort("exceptions_print_stacktrace: no exception thrown");
2101 /* clear exception, because we are calling jit code again */
2103 c = oxptr->vftbl->class;
2105 /* find the printStackTrace() method */
2107 m = class_resolveclassmethod(c,
2108 utf_printStackTrace,
2110 class_java_lang_Object,
2114 vm_abort("exceptions_print_stacktrace: printStackTrace()V not found");
2116 /* print compatibility message */
2118 fprintf(stderr, "Exception in thread \"main\" ");
2120 /* print the stacktrace */
2122 (void) vm_call_method(m, oxptr);
2124 /* This normally means, we are EXTREMLY out of memory or
2125 have a serious problem while printStackTrace. But may
2126 be another exception, so print it. */
2128 xptr = exceptions_get_exception();
2131 fprintf(stderr, "Exception while printStackTrace(): ");
2133 /* now print original exception */
2135 exceptions_print_exception(xptr);
2136 stacktrace_print_trace(xptr);
2138 /* now print original exception */
2140 fprintf(stderr, "Original exception was: ");
2141 exceptions_print_exception(oxptr);
2142 stacktrace_print_trace(oxptr);
2150 * These are local overrides for various environment variables in Emacs.
2151 * Please do not remove this and leave it at the end of the file, where
2152 * Emacs will automagically detect them.
2153 * ---------------------------------------------------------------------
2156 * indent-tabs-mode: t
2160 * vim:noexpandtab:sw=4:ts=4: