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 8178 2007-07-05 11:13:20Z 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)
95 #if !(defined(__ARM__) && defined(__LINUX__))
96 /* On arm-linux the first memory page can't be mmap'ed, as it
97 contains the exception vectors. */
101 /* mmap a memory page at address 0x0, so our hardware-exceptions
104 pagesize = getpagesize();
106 (void) memory_mmap_anon(NULL, pagesize, PROT_NONE, MAP_PRIVATE | MAP_FIXED);
109 /* check if we get into trouble with our hardware-exceptions */
111 if (OFFSET(java_bytearray, data) <= EXCEPTION_HARDWARE_LARGEST)
112 vm_abort("signal_init: array-data offset is less or equal the maximum hardware-exception displacement: %d <= %d", OFFSET(java_bytearray, data), EXCEPTION_HARDWARE_LARGEST);
114 /* java/lang/Throwable */
116 if (!(class_java_lang_Throwable =
117 load_class_bootstrap(utf_java_lang_Throwable)) ||
118 !link_class(class_java_lang_Throwable))
121 /* java/lang/Error */
123 if (!(class_java_lang_Error = load_class_bootstrap(utf_java_lang_Error)) ||
124 !link_class(class_java_lang_Error))
127 #if defined(ENABLE_JAVASE)
128 /* java/lang/LinkageError */
130 if (!(class_java_lang_LinkageError =
131 load_class_bootstrap(utf_java_lang_LinkageError)) ||
132 !link_class(class_java_lang_LinkageError))
136 /* java/lang/NoClassDefFoundError */
138 if (!(class_java_lang_NoClassDefFoundError =
139 load_class_bootstrap(utf_java_lang_NoClassDefFoundError)) ||
140 !link_class(class_java_lang_NoClassDefFoundError))
143 /* java/lang/OutOfMemoryError */
145 if (!(class_java_lang_OutOfMemoryError =
146 load_class_bootstrap(utf_java_lang_OutOfMemoryError)) ||
147 !link_class(class_java_lang_OutOfMemoryError))
150 /* java/lang/VirtualMachineError */
152 if (!(class_java_lang_VirtualMachineError =
153 load_class_bootstrap(utf_java_lang_VirtualMachineError)) ||
154 !link_class(class_java_lang_VirtualMachineError))
158 /* java/lang/Exception */
160 if (!(class_java_lang_Exception =
161 load_class_bootstrap(utf_java_lang_Exception)) ||
162 !link_class(class_java_lang_Exception))
165 /* java/lang/ClassCastException */
167 if (!(class_java_lang_ClassCastException =
168 load_class_bootstrap(utf_java_lang_ClassCastException)) ||
169 !link_class(class_java_lang_ClassCastException))
172 /* java/lang/ClassNotFoundException */
174 if (!(class_java_lang_ClassNotFoundException =
175 load_class_bootstrap(utf_java_lang_ClassNotFoundException)) ||
176 !link_class(class_java_lang_ClassNotFoundException))
179 /* java/lang/NullPointerException */
181 if (!(class_java_lang_NullPointerException =
182 load_class_bootstrap(utf_java_lang_NullPointerException)) ||
183 !link_class(class_java_lang_NullPointerException))
187 #if defined(WITH_CLASSPATH_GNU)
188 /* java/lang/VMThrowable */
190 if (!(class_java_lang_VMThrowable =
191 load_class_bootstrap(utf_java_lang_VMThrowable)) ||
192 !link_class(class_java_lang_VMThrowable))
200 /* exceptions_get_exception ****************************************************
202 Returns the current exception pointer of the current thread.
204 *******************************************************************************/
206 java_objectheader *exceptions_get_exception(void)
208 /* return the exception */
210 return *exceptionptr;
214 /* exceptions_set_exception ****************************************************
216 Sets the exception pointer of the current thread.
218 *******************************************************************************/
220 void exceptions_set_exception(java_objectheader *o)
222 /* set the exception */
228 /* exceptions_clear_exception **************************************************
230 Clears the current exception pointer of the current thread.
232 *******************************************************************************/
234 void exceptions_clear_exception(void)
236 exceptions_set_exception(NULL);
240 /* exceptions_get_and_clear_exception ******************************************
242 Gets the exception pointer of the current thread and clears it.
243 This function may return NULL.
245 *******************************************************************************/
247 java_objectheader *exceptions_get_and_clear_exception(void)
249 java_objectheader *o;
251 /* get the exception */
253 o = exceptions_get_exception();
255 /* and clear the exception */
257 exceptions_clear_exception();
259 /* return the exception */
265 /* exceptions_new_class ********************************************************
267 Creates an exception object from the given class and initalizes it.
270 class....class pointer
272 *******************************************************************************/
274 static java_objectheader *exceptions_new_class(classinfo *c)
276 java_objectheader *o;
278 o = native_new_and_init(c);
281 return exceptions_get_exception();
287 /* exceptions_new_utf **********************************************************
289 Creates an exception object with the given name and initalizes it.
292 classname....class name in UTF-8
294 *******************************************************************************/
296 static java_objectheader *exceptions_new_utf(utf *classname)
299 java_objectheader *o;
301 c = load_class_bootstrap(classname);
304 return exceptions_get_exception();
306 o = exceptions_new_class(c);
312 /* exceptions_throw_class ******************************************************
314 Creates an exception object from the given class, initalizes and
318 class....class pointer
320 *******************************************************************************/
322 static void exceptions_throw_class(classinfo *c)
324 java_objectheader *o;
326 o = exceptions_new_class(c);
331 exceptions_set_exception(o);
335 /* exceptions_throw_utf ********************************************************
337 Creates an exception object with the given name, initalizes and
341 classname....class name in UTF-8
343 *******************************************************************************/
345 static void exceptions_throw_utf(utf *classname)
349 c = load_class_bootstrap(classname);
354 exceptions_throw_class(c);
358 /* exceptions_throw_utf_throwable **********************************************
360 Creates an exception object with the given name and initalizes it
361 with the given java/lang/Throwable exception.
364 classname....class name in UTF-8
365 cause........the given Throwable
367 *******************************************************************************/
369 static void exceptions_throw_utf_throwable(utf *classname,
370 java_objectheader *cause)
373 java_objectheader *o;
375 java_lang_Throwable *object;
377 object = (java_lang_Throwable *) cause;
379 c = load_class_bootstrap(classname);
391 /* call initializer */
393 m = class_resolveclassmethod(c,
395 utf_java_lang_Throwable__void,
402 (void) vm_call_method(m, o, cause);
404 exceptions_set_exception(o);
408 /* exceptions_throw_utf_exception **********************************************
410 Creates an exception object with the given name and initalizes it
411 with the given java/lang/Exception exception.
414 classname....class name in UTF-8
415 exception....the given Exception
417 *******************************************************************************/
419 static void exceptions_throw_utf_exception(utf *classname,
420 java_objectheader *exception)
423 java_objectheader *o;
426 c = load_class_bootstrap(classname);
438 /* call initializer */
440 m = class_resolveclassmethod(c,
442 utf_java_lang_Exception__V,
449 (void) vm_call_method(m, o, exception);
451 exceptions_set_exception(o);
455 /* exceptions_throw_utf_cause **************************************************
457 Creates an exception object with the given name and initalizes it
458 with the given java/lang/Throwable exception with initCause.
461 classname....class name in UTF-8
462 cause........the given Throwable
464 *******************************************************************************/
466 static void exceptions_throw_utf_cause(utf *classname, java_objectheader *cause)
469 java_objectheader *o;
471 java_lang_Throwable *object;
473 object = (java_lang_Throwable *) cause;
475 c = load_class_bootstrap(classname);
487 /* call initializer */
489 m = class_resolveclassmethod(c,
491 utf_java_lang_String__void,
498 (void) vm_call_method(m, o, object->detailMessage);
502 m = class_resolveclassmethod(c,
504 utf_java_lang_Throwable__java_lang_Throwable,
511 (void) vm_call_method(m, o, cause);
513 exceptions_set_exception(o);
517 /* exceptions_new_utf_javastring ***********************************************
519 Creates an exception object with the given name and initalizes it
520 with the given java/lang/String message.
523 classname....class name in UTF-8
524 message......the message as a java.lang.String
527 an exception pointer (in any case -- either it is the newly created
528 exception, or an exception thrown while trying to create it).
530 *******************************************************************************/
532 static java_objectheader *exceptions_new_utf_javastring(utf *classname,
533 java_objectheader *message)
535 java_objectheader *o;
538 c = load_class_bootstrap(classname);
541 return exceptions_get_exception();
543 o = native_new_and_init_string(c, message);
546 return exceptions_get_exception();
552 /* exceptions_new_class_utf ****************************************************
554 Creates an exception object of the given class and initalizes it.
557 c..........class pointer
558 message....the message as UTF-8 string
560 *******************************************************************************/
562 static java_objectheader *exceptions_new_class_utf(classinfo *c, utf *message)
564 java_objectheader *o;
565 java_objectheader *s;
567 s = javastring_new(message);
570 return exceptions_get_exception();
572 o = native_new_and_init_string(c, s);
575 return exceptions_get_exception();
581 /* exceptions_new_utf_utf ******************************************************
583 Creates an exception object with the given name and initalizes it
584 with the given utf message.
587 classname....class name in UTF-8
588 message......the message as an utf *
591 an exception pointer (in any case -- either it is the newly created
592 exception, or an exception thrown while trying to create it).
594 *******************************************************************************/
596 static java_objectheader *exceptions_new_utf_utf(utf *classname, utf *message)
599 java_objectheader *o;
601 c = load_class_bootstrap(classname);
604 return exceptions_get_exception();
606 o = exceptions_new_class_utf(c, message);
612 /* exceptions_throw_class_utf **************************************************
614 Creates an exception object of the given class, initalizes and
615 throws it with the given utf message.
618 c..........class pointer
619 message....the message as an UTF-8
621 *******************************************************************************/
623 static void exceptions_throw_class_utf(classinfo *c, utf *message)
625 java_objectheader *o;
627 o = exceptions_new_class_utf(c, message);
629 exceptions_set_exception(o);
633 /* exceptions_throw_utf_utf ****************************************************
635 Creates an exception object with the given name, initalizes and
636 throws it with the given utf message.
639 classname....class name in UTF-8
640 message......the message as an utf *
642 *******************************************************************************/
644 static void exceptions_throw_utf_utf(utf *classname, utf *message)
646 java_objectheader *o;
648 o = exceptions_new_utf_utf(classname, message);
650 exceptions_set_exception(o);
654 /* exceptions_new_abstractmethoderror ****************************************
656 Generates a java.lang.AbstractMethodError for the VM.
658 *******************************************************************************/
660 java_objectheader *exceptions_new_abstractmethoderror(void)
662 java_objectheader *o;
664 o = exceptions_new_utf(utf_java_lang_AbstractMethodError);
670 /* exceptions_new_error ********************************************************
672 Generates a java.lang.Error for the VM.
674 *******************************************************************************/
676 #if defined(ENABLE_JAVAME_CLDC1_1)
677 static java_objectheader *exceptions_new_error(utf *message)
679 java_objectheader *o;
681 o = exceptions_new_class_utf(class_java_lang_Error, message);
688 /* exceptions_asm_new_abstractmethoderror **************************************
690 Generates a java.lang.AbstractMethodError for
691 asm_abstractmethoderror.
693 *******************************************************************************/
695 java_objectheader *exceptions_asm_new_abstractmethoderror(u1 *sp, u1 *ra)
698 java_objectheader *e;
700 /* create the stackframeinfo (XPC is equal to RA) */
702 stacktrace_create_extern_stackframeinfo(&sfi, NULL, sp, ra, ra);
704 /* create the exception */
706 #if defined(ENABLE_JAVASE)
707 e = exceptions_new_abstractmethoderror();
709 e = exceptions_new_error(utf_java_lang_AbstractMethodError);
712 /* remove the stackframeinfo */
714 stacktrace_remove_stackframeinfo(&sfi);
720 /* exceptions_new_arraystoreexception ******************************************
722 Generates a java.lang.ArrayStoreException for the VM.
724 *******************************************************************************/
726 java_objectheader *exceptions_new_arraystoreexception(void)
728 java_objectheader *o;
730 o = exceptions_new_utf(utf_java_lang_ArrayStoreException);
736 /* exceptions_throw_abstractmethoderror ****************************************
738 Generates and throws a java.lang.AbstractMethodError for the VM.
740 *******************************************************************************/
742 void exceptions_throw_abstractmethoderror(void)
744 exceptions_throw_utf(utf_java_lang_AbstractMethodError);
748 /* exceptions_throw_classcircularityerror **************************************
750 Generates and throws a java.lang.ClassCircularityError for the
754 c....the class in which the error was found
756 *******************************************************************************/
758 void exceptions_throw_classcircularityerror(classinfo *c)
760 exceptions_throw_utf_utf(utf_java_lang_ClassCircularityError, c->name);
764 /* exceptions_throw_classformaterror *******************************************
766 Generates and throws a java.lang.ClassFormatError for the VM.
769 c............the class in which the error was found
770 message......UTF-8 format string
772 *******************************************************************************/
774 void exceptions_throw_classformaterror(classinfo *c, const char *message, ...)
781 /* calculate message length */
786 msglen += utf_bytes(c->name) + strlen(" (");
788 va_start(ap, message);
789 msglen += get_variable_message_length(message, ap);
793 msglen += strlen(")");
795 msglen += strlen("0");
797 /* allocate a buffer */
799 msg = MNEW(char, msglen);
801 /* print message into allocated buffer */
804 utf_copy_classname(msg, c->name);
808 va_start(ap, message);
809 vsprintf(msg + strlen(msg), message, ap);
815 u = utf_new_char(msg);
819 MFREE(msg, char, msglen);
821 /* throw exception */
823 exceptions_throw_utf_utf(utf_java_lang_ClassFormatError, u);
827 /* exceptions_throw_classnotfoundexception *************************************
829 Generates and throws a java.lang.ClassNotFoundException for the
833 name.........name of the class not found as a utf *
835 *******************************************************************************/
837 void exceptions_throw_classnotfoundexception(utf *name)
839 /* we use class here, as this one is rather frequent */
841 exceptions_throw_class_utf(class_java_lang_ClassNotFoundException, name);
845 /* exceptions_throw_noclassdeffounderror ***************************************
847 Generates and throws a java.lang.NoClassDefFoundError.
850 name.........name of the class not found as a utf *
852 *******************************************************************************/
854 void exceptions_throw_noclassdeffounderror(utf *name)
857 vm_abort("java.lang.NoClassDefFoundError: %s", name->text);
859 exceptions_throw_class_utf(class_java_lang_NoClassDefFoundError, name);
863 /* exceptions_throw_noclassdeffounderror_cause *********************************
865 Generates and throws a java.lang.NoClassDefFoundError with the
868 *******************************************************************************/
870 void exceptions_throw_noclassdeffounderror_cause(java_objectheader *cause)
872 exceptions_throw_utf_cause(utf_java_lang_NoClassDefFoundError, cause);
876 /* exceptions_throw_noclassdeffounderror_wrong_name ****************************
878 Generates and throws a java.lang.NoClassDefFoundError with a
882 name.........name of the class not found as a utf *
884 *******************************************************************************/
886 void exceptions_throw_noclassdeffounderror_wrong_name(classinfo *c, utf *name)
892 msglen = utf_bytes(c->name) + strlen(" (wrong name: ") +
893 utf_bytes(name) + strlen(")") + strlen("0");
895 msg = MNEW(char, msglen);
897 utf_copy_classname(msg, c->name);
898 strcat(msg, " (wrong name: ");
899 utf_cat_classname(msg, name);
902 u = utf_new_char(msg);
904 MFREE(msg, char, msglen);
906 exceptions_throw_noclassdeffounderror(u);
910 /* exceptions_throw_exceptionininitializererror ********************************
912 Generates and throws a java.lang.ExceptionInInitializerError for
916 cause......cause exception object
918 *******************************************************************************/
920 void exceptions_throw_exceptionininitializererror(java_objectheader *cause)
922 exceptions_throw_utf_throwable(utf_java_lang_ExceptionInInitializerError,
927 /* exceptions_throw_incompatibleclasschangeerror *******************************
929 Generates and throws a java.lang.IncompatibleClassChangeError for
933 message......UTF-8 message format string
935 *******************************************************************************/
937 void exceptions_throw_incompatibleclasschangeerror(classinfo *c, const char *message)
943 /* calculate exception message length */
945 msglen = utf_bytes(c->name) + strlen(message) + strlen("0");
947 /* allocate memory */
949 msg = MNEW(char, msglen);
951 utf_copy_classname(msg, c->name);
952 strcat(msg, message);
954 u = utf_new_char(msg);
958 MFREE(msg, char, msglen);
960 /* throw exception */
962 exceptions_throw_utf_utf(utf_java_lang_IncompatibleClassChangeError, u);
966 /* exceptions_throw_instantiationerror *****************************************
968 Generates and throws a java.lang.InstantiationError for the VM.
970 *******************************************************************************/
972 void exceptions_throw_instantiationerror(classinfo *c)
974 exceptions_throw_utf_utf(utf_java_lang_InstantiationError, c->name);
978 /* exceptions_throw_internalerror **********************************************
980 Generates and throws a java.lang.InternalError for the VM.
983 message......UTF-8 message format string
985 *******************************************************************************/
987 void exceptions_throw_internalerror(const char *message, ...)
994 /* calculate exception message length */
996 va_start(ap, message);
997 msglen = get_variable_message_length(message, ap);
1000 /* allocate memory */
1002 msg = MNEW(char, msglen);
1004 /* generate message */
1006 va_start(ap, message);
1007 vsprintf(msg, message, ap);
1010 u = utf_new_char(msg);
1014 MFREE(msg, char, msglen);
1016 /* throw exception */
1018 exceptions_throw_utf_utf(utf_java_lang_InternalError, u);
1022 /* exceptions_throw_linkageerror ***********************************************
1024 Generates and throws java.lang.LinkageError with an error message.
1027 message......UTF-8 message
1028 c............class related to the error. If this is != NULL
1029 the name of c is appended to the error message.
1031 *******************************************************************************/
1033 void exceptions_throw_linkageerror(const char *message, classinfo *c)
1035 java_objectheader *o;
1039 /* calculate exception message length */
1041 msglen = strlen(message) + 1;
1044 msglen += utf_bytes(c->name);
1046 /* allocate memory */
1048 msg = MNEW(char, msglen);
1050 /* generate message */
1052 strcpy(msg,message);
1055 utf_cat_classname(msg, c->name);
1057 o = native_new_and_init_string(class_java_lang_LinkageError,
1058 javastring_new_from_utf_string(msg));
1062 MFREE(msg, char, msglen);
1067 exceptions_set_exception(o);
1071 /* exceptions_throw_nosuchfielderror *******************************************
1073 Generates and throws a java.lang.NoSuchFieldError with an error
1077 c............class in which the field was not found
1078 name.........name of the field
1080 *******************************************************************************/
1082 void exceptions_throw_nosuchfielderror(classinfo *c, utf *name)
1088 /* calculate exception message length */
1090 msglen = utf_bytes(c->name) + strlen(".") + utf_bytes(name) + strlen("0");
1092 /* allocate memory */
1094 msg = MNEW(char, msglen);
1096 /* generate message */
1098 utf_copy_classname(msg, c->name);
1102 u = utf_new_char(msg);
1106 MFREE(msg, char, msglen);
1108 exceptions_throw_utf_utf(utf_java_lang_NoSuchFieldError, u);
1112 /* exceptions_throw_nosuchmethoderror ******************************************
1114 Generates and throws a java.lang.NoSuchMethodError with an error
1118 c............class in which the method was not found
1119 name.........name of the method
1120 desc.........descriptor of the method
1122 *******************************************************************************/
1124 void exceptions_throw_nosuchmethoderror(classinfo *c, utf *name, utf *desc)
1130 /* calculate exception message length */
1132 msglen = utf_bytes(c->name) + strlen(".") + utf_bytes(name) +
1133 utf_bytes(desc) + strlen("0");
1135 /* allocate memory */
1137 msg = MNEW(char, msglen);
1139 /* generate message */
1141 utf_copy_classname(msg, c->name);
1146 u = utf_new_char(msg);
1150 MFREE(msg, char, msglen);
1152 #if defined(ENABLE_JAVASE)
1153 exceptions_throw_utf_utf(utf_java_lang_NoSuchMethodError, u);
1155 exceptions_throw_class_utf(class_java_lang_Error, u);
1160 /* exceptions_throw_outofmemoryerror *******************************************
1162 Generates and throws an java.lang.OutOfMemoryError for the VM.
1164 *******************************************************************************/
1166 void exceptions_throw_outofmemoryerror(void)
1168 exceptions_throw_class(class_java_lang_OutOfMemoryError);
1172 /* exceptions_throw_unsatisfiedlinkerror ***************************************
1174 Generates and throws a java.lang.UnsatisfiedLinkError for the
1178 name......UTF-8 name string
1180 *******************************************************************************/
1182 void exceptions_throw_unsatisfiedlinkerror(utf *name)
1184 #if defined(ENABLE_JAVASE)
1185 exceptions_throw_utf_utf(utf_java_lang_UnsatisfiedLinkError, name);
1187 exceptions_throw_class_utf(class_java_lang_Error, name);
1192 /* exceptions_throw_unsupportedclassversionerror *******************************
1194 Generates and throws a java.lang.UnsupportedClassVersionError for
1198 c............class in which the method was not found
1199 message......UTF-8 format string
1201 *******************************************************************************/
1203 void exceptions_throw_unsupportedclassversionerror(classinfo *c, u4 ma, u4 mi)
1209 /* calculate exception message length */
1212 utf_bytes(c->name) +
1213 strlen(" (Unsupported major.minor version 00.0)") +
1216 /* allocate memory */
1218 msg = MNEW(char, msglen);
1220 /* generate message */
1222 utf_copy_classname(msg, c->name);
1223 sprintf(msg + strlen(msg), " (Unsupported major.minor version %d.%d)",
1226 u = utf_new_char(msg);
1230 MFREE(msg, char, msglen);
1232 /* throw exception */
1234 exceptions_throw_utf_utf(utf_java_lang_UnsupportedClassVersionError, u);
1238 /* exceptions_throw_verifyerror ************************************************
1240 Generates and throws a java.lang.VerifyError for the JIT compiler.
1243 m............method in which the error was found
1244 message......UTF-8 format string
1246 *******************************************************************************/
1248 void exceptions_throw_verifyerror(methodinfo *m, const char *message, ...)
1255 /* calculate exception message length */
1261 strlen("(class: ") + utf_bytes(m->class->name) +
1262 strlen(", method: ") + utf_bytes(m->name) +
1263 strlen(" signature: ") + utf_bytes(m->descriptor) +
1264 strlen(") ") + strlen("0");
1266 va_start(ap, message);
1267 msglen += get_variable_message_length(message, ap);
1270 /* allocate memory */
1272 msg = MNEW(char, msglen);
1274 /* generate message */
1277 strcpy(msg, "(class: ");
1278 utf_cat_classname(msg, m->class->name);
1279 strcat(msg, ", method: ");
1280 utf_cat(msg, m->name);
1281 strcat(msg, " signature: ");
1282 utf_cat(msg, m->descriptor);
1286 va_start(ap, message);
1287 vsprintf(msg + strlen(msg), message, ap);
1290 u = utf_new_char(msg);
1294 MFREE(msg, char, msglen);
1296 /* throw exception */
1298 exceptions_throw_utf_utf(utf_java_lang_VerifyError, u);
1302 /* exceptions_throw_verifyerror_for_stack **************************************
1304 throws a java.lang.VerifyError for an invalid stack slot type
1307 m............method in which the error was found
1308 type.........the expected type
1311 an exception pointer (in any case -- either it is the newly created
1312 exception, or an exception thrown while trying to create it).
1314 *******************************************************************************/
1316 void exceptions_throw_verifyerror_for_stack(methodinfo *m, int type)
1323 /* calculate exception message length */
1328 msglen = strlen("(class: ") + utf_bytes(m->class->name) +
1329 strlen(", method: ") + utf_bytes(m->name) +
1330 strlen(" signature: ") + utf_bytes(m->descriptor) +
1331 strlen(") Expecting to find longest-------typename on stack")
1334 /* allocate memory */
1336 msg = MNEW(char, msglen);
1338 /* generate message */
1341 strcpy(msg, "(class: ");
1342 utf_cat_classname(msg, m->class->name);
1343 strcat(msg, ", method: ");
1344 utf_cat(msg, m->name);
1345 strcat(msg, " signature: ");
1346 utf_cat(msg, m->descriptor);
1353 strcat(msg, "Expecting to find ");
1356 case TYPE_INT: typename = "integer"; break;
1357 case TYPE_LNG: typename = "long"; break;
1358 case TYPE_FLT: typename = "float"; break;
1359 case TYPE_DBL: typename = "double"; break;
1360 case TYPE_ADR: typename = "object/array"; break;
1361 case TYPE_RET: typename = "returnAddress"; break;
1362 default: typename = "<INVALID>"; assert(0); break;
1365 strcat(msg, typename);
1366 strcat(msg, " on stack");
1368 u = utf_new_char(msg);
1372 MFREE(msg, char, msglen);
1374 /* throw exception */
1376 exceptions_throw_utf_utf(utf_java_lang_VerifyError, u);
1380 /* exceptions_new_arithmeticexception ******************************************
1382 Generates a java.lang.ArithmeticException for the JIT compiler.
1384 *******************************************************************************/
1386 java_objectheader *exceptions_new_arithmeticexception(void)
1388 java_objectheader *o;
1390 o = exceptions_new_utf_utf(utf_java_lang_ArithmeticException,
1391 utf_division_by_zero);
1397 /* exceptions_new_arrayindexoutofboundsexception *******************************
1399 Generates a java.lang.ArrayIndexOutOfBoundsException for the VM
1402 *******************************************************************************/
1404 java_objectheader *exceptions_new_arrayindexoutofboundsexception(s4 index)
1406 java_objectheader *o;
1408 java_objectheader *s;
1410 /* convert the index into a String, like Sun does */
1412 m = class_resolveclassmethod(class_java_lang_String,
1413 utf_new_char("valueOf"),
1414 utf_new_char("(I)Ljava/lang/String;"),
1415 class_java_lang_Object,
1419 return exceptions_get_exception();
1421 s = vm_call_method(m, NULL, index);
1424 return exceptions_get_exception();
1426 o = exceptions_new_utf_javastring(utf_java_lang_ArrayIndexOutOfBoundsException,
1430 return exceptions_get_exception();
1436 /* exceptions_throw_arrayindexoutofboundsexception *****************************
1438 Generates and throws a java.lang.ArrayIndexOutOfBoundsException for
1441 *******************************************************************************/
1443 void exceptions_throw_arrayindexoutofboundsexception(void)
1445 exceptions_throw_utf(utf_java_lang_ArrayIndexOutOfBoundsException);
1449 /* exceptions_throw_arraystoreexception ****************************************
1451 Generates and throws a java.lang.ArrayStoreException for the VM.
1453 *******************************************************************************/
1455 void exceptions_throw_arraystoreexception(void)
1457 exceptions_throw_utf(utf_java_lang_ArrayStoreException);
1458 /* e = native_new_and_init(class_java_lang_ArrayStoreException); */
1462 /* exceptions_new_classcastexception *******************************************
1464 Generates a java.lang.ClassCastException for the JIT compiler.
1466 *******************************************************************************/
1468 java_objectheader *exceptions_new_classcastexception(java_objectheader *o)
1470 java_objectheader *e;
1473 classname = o->vftbl->class->name;
1475 e = exceptions_new_class_utf(class_java_lang_ClassCastException, classname);
1481 /* exceptions_throw_clonenotsupportedexception *********************************
1483 Generates and throws a java.lang.CloneNotSupportedException for the
1486 *******************************************************************************/
1488 void exceptions_throw_clonenotsupportedexception(void)
1490 exceptions_throw_utf(utf_java_lang_CloneNotSupportedException);
1494 /* exceptions_throw_illegalaccessexception *************************************
1496 Generates and throws a java.lang.IllegalAccessException for the VM.
1498 *******************************************************************************/
1500 void exceptions_throw_illegalaccessexception(utf *message)
1502 exceptions_throw_utf_utf(utf_java_lang_IllegalAccessException, message);
1506 /* exceptions_throw_illegalargumentexception ***********************************
1508 Generates and throws a java.lang.IllegalArgumentException for the
1511 *******************************************************************************/
1513 void exceptions_throw_illegalargumentexception(void)
1515 exceptions_throw_utf(utf_java_lang_IllegalArgumentException);
1519 /* exceptions_throw_illegalmonitorstateexception *******************************
1521 Generates and throws a java.lang.IllegalMonitorStateException for
1524 *******************************************************************************/
1526 void exceptions_throw_illegalmonitorstateexception(void)
1528 exceptions_throw_utf(utf_java_lang_IllegalMonitorStateException);
1532 /* exceptions_throw_instantiationexception *************************************
1534 Generates and throws a java.lang.InstantiationException for the VM.
1536 *******************************************************************************/
1538 void exceptions_throw_instantiationexception(classinfo *c)
1540 exceptions_throw_utf_utf(utf_java_lang_InstantiationException, c->name);
1544 /* exceptions_throw_interruptedexception ***************************************
1546 Generates and throws a java.lang.InterruptedException for the VM.
1548 *******************************************************************************/
1550 void exceptions_throw_interruptedexception(void)
1552 exceptions_throw_utf(utf_java_lang_InterruptedException);
1556 /* exceptions_throw_invocationtargetexception **********************************
1558 Generates and throws a java.lang.reflect.InvocationTargetException
1562 cause......cause exception object
1564 *******************************************************************************/
1566 void exceptions_throw_invocationtargetexception(java_objectheader *cause)
1568 exceptions_throw_utf_throwable(utf_java_lang_reflect_InvocationTargetException,
1573 /* exceptions_throw_negativearraysizeexception *********************************
1575 Generates and throws a java.lang.NegativeArraySizeException for the
1578 *******************************************************************************/
1580 void exceptions_throw_negativearraysizeexception(void)
1582 exceptions_throw_utf(utf_java_lang_NegativeArraySizeException);
1586 /* exceptions_new_nullpointerexception *****************************************
1588 Generates a java.lang.NullPointerException for the VM system.
1590 *******************************************************************************/
1592 java_objectheader *exceptions_new_nullpointerexception(void)
1594 java_objectheader *o;
1596 o = exceptions_new_class(class_java_lang_NullPointerException);
1602 /* exceptions_throw_nullpointerexception ***************************************
1604 Generates a java.lang.NullPointerException for the VM system and
1605 throw it in the VM system.
1607 *******************************************************************************/
1609 void exceptions_throw_nullpointerexception(void)
1611 exceptions_throw_class(class_java_lang_NullPointerException);
1615 /* exceptions_throw_privilegedactionexception **********************************
1617 Generates and throws a java.security.PrivilegedActionException.
1619 *******************************************************************************/
1621 void exceptions_throw_privilegedactionexception(java_objectheader *exception)
1623 exceptions_throw_utf_exception(utf_java_security_PrivilegedActionException,
1628 /* exceptions_throw_stringindexoutofboundsexception ****************************
1630 Generates and throws a java.lang.StringIndexOutOfBoundsException
1633 *******************************************************************************/
1635 void exceptions_throw_stringindexoutofboundsexception(void)
1637 exceptions_throw_utf(utf_java_lang_StringIndexOutOfBoundsException);
1641 /* exceptions_classnotfoundexception_to_noclassdeffounderror *******************
1643 Check the exception for a ClassNotFoundException. If it is one,
1644 convert it to a NoClassDefFoundError.
1646 *******************************************************************************/
1648 void exceptions_classnotfoundexception_to_noclassdeffounderror(void)
1650 java_objectheader *o;
1651 java_objectheader *cause;
1652 java_lang_Throwable *object;
1653 java_objectheader *s;
1657 cause = exceptions_get_exception();
1659 /* convert ClassNotFoundException's to NoClassDefFoundError's */
1661 if (builtin_instanceof(cause, class_java_lang_ClassNotFoundException)) {
1662 /* clear exception, because we are calling jit code again */
1664 exceptions_clear_exception();
1666 /* create new error */
1668 object = (java_lang_Throwable *) cause;
1669 s = (java_objectheader *) object->detailMessage;
1671 o = exceptions_new_utf_javastring(utf_java_lang_NoClassDefFoundError,
1674 /* we had an exception while creating the error */
1676 if (exceptions_get_exception())
1679 /* set new exception */
1681 exceptions_set_exception(o);
1686 /* exceptions_fillinstacktrace *************************************************
1688 Calls the fillInStackTrace-method of the currently thrown
1691 *******************************************************************************/
1693 java_objectheader *exceptions_fillinstacktrace(void)
1695 java_objectheader *o;
1700 o = exceptions_get_and_clear_exception();
1704 /* resolve methodinfo pointer from exception object */
1706 #if defined(ENABLE_JAVASE)
1707 m = class_resolvemethod(o->vftbl->class,
1708 utf_fillInStackTrace,
1709 utf_void__java_lang_Throwable);
1710 #elif defined(ENABLE_JAVAME_CLDC1_1)
1711 m = class_resolvemethod(o->vftbl->class,
1712 utf_fillInStackTrace,
1715 #error IMPLEMENT ME!
1720 (void) vm_call_method(m, o);
1722 /* return exception object */
1728 /* exceptions_new_hardware_exception *******************************************
1730 Creates the correct exception for a hardware-exception thrown and
1731 caught by a signal handler.
1733 *******************************************************************************/
1735 java_objectheader *exceptions_new_hardware_exception(u1 *pv, u1 *sp, u1 *ra, u1 *xpc, s4 type, ptrint val, stackframeinfo *sfi)
1737 java_objectheader *e;
1738 java_objectheader *o;
1741 /* create stackframeinfo */
1743 stacktrace_create_extern_stackframeinfo(sfi, pv, sp, ra, xpc);
1746 case EXCEPTION_HARDWARE_NULLPOINTER:
1747 e = exceptions_new_nullpointerexception();
1750 case EXCEPTION_HARDWARE_ARITHMETIC:
1751 e = exceptions_new_arithmeticexception();
1754 case EXCEPTION_HARDWARE_ARRAYINDEXOUTOFBOUNDS:
1756 e = exceptions_new_arrayindexoutofboundsexception(index);
1759 case EXCEPTION_HARDWARE_CLASSCAST:
1760 o = (java_objectheader *) val;
1761 e = exceptions_new_classcastexception(o);
1764 case EXCEPTION_HARDWARE_EXCEPTION:
1765 e = exceptions_fillinstacktrace();
1768 case EXCEPTION_HARDWARE_PATCHER:
1769 e = patcher_handler(xpc);
1773 /* let's try to get a backtrace */
1775 codegen_get_pv_from_pc(xpc);
1777 /* if that does not work, print more debug info */
1779 log_println("exceptions_new_hardware_exception: unknown exception type %d", type);
1781 #if SIZEOF_VOID_P == 8
1782 log_println("PC=0x%016lx", xpc);
1784 log_println("PC=0x%08x", xpc);
1787 #if defined(ENABLE_DISASSEMBLER)
1788 log_println("machine instruction at PC:");
1792 vm_abort("Exiting...");
1794 /* keep compiler happy */
1799 /* remove stackframeinfo */
1801 stacktrace_remove_stackframeinfo(sfi);
1803 /* return the exception object */
1809 /* exceptions_handle_exception *************************************************
1811 Try to find an exception handler for the given exception and return it.
1812 If no handler is found, exit the monitor of the method (if any)
1816 xptr.........the exception object
1817 xpc..........PC of where the exception was thrown
1818 pv...........Procedure Value of the current method
1819 sp...........current stack pointer
1822 the address of the first matching exception handler, or
1823 NULL if no handler was found
1825 *******************************************************************************/
1827 #if defined(ENABLE_JIT)
1828 u1 *exceptions_handle_exception(java_objectheader *xptr, u1 *xpc, u1 *pv, u1 *sp)
1833 dseg_exception_entry *ex;
1834 s4 exceptiontablelength;
1836 classref_or_classinfo cr;
1838 #if defined(ENABLE_THREADS)
1839 java_objectheader *o;
1843 /* Addresses are 31 bit integers */
1844 # define ADDR_MASK(x) (u1 *)((u4)(x) & 0x7FFFFFFF)
1846 # define ADDR_MASK(x) (x)
1849 xpc = ADDR_MASK(xpc);
1851 /* get info from the method header */
1853 code = *((codeinfo **) (pv + CodeinfoPointer));
1854 issync = *((s4 *) (pv + IsSync));
1855 ex = (dseg_exception_entry *) (pv + ExTableStart);
1856 exceptiontablelength = *((s4 *) (pv + ExTableSize));
1858 /* Get the methodinfo pointer from the codeinfo pointer. For
1859 asm_vm_call_method the codeinfo pointer is NULL. */
1861 m = (code == NULL) ? NULL : code->m;
1863 #if !defined(NDEBUG)
1864 /* print exception trace */
1866 if (opt_verbose || opt_verbosecall || opt_TraceExceptions)
1867 builtin_trace_exception(xptr, m, xpc, 1);
1870 #if defined(ENABLE_VMLOG)
1871 vmlog_cacao_throw(xptr);
1874 for (i = 0; i < exceptiontablelength; i++) {
1875 /* ATTENTION: keep this here, as we need to decrement the
1876 pointer before the loop executes! */
1880 /* If the start and end PC is NULL, this means we have the
1881 special case of asm_vm_call_method. So, just return the
1882 proper exception handler. */
1884 if ((ex->startpc == NULL) && (ex->endpc == NULL))
1885 return (u1 *) (ptrint) &asm_vm_call_method_exception_handler;
1887 /* is the xpc is the current catch range */
1889 if ((ADDR_MASK(ex->startpc) <= xpc) && (xpc < ADDR_MASK(ex->endpc))) {
1892 /* NULL catches everything */
1894 if (cr.any == NULL) {
1895 #if !defined(NDEBUG)
1896 /* Print stacktrace of exception when caught. */
1898 #if defined(ENABLE_VMLOG)
1899 vmlog_cacao_catch(xptr);
1902 if (opt_TraceExceptions) {
1903 exceptions_print_exception(xptr);
1904 stacktrace_print_trace(xptr);
1908 return ex->handlerpc;
1911 /* resolve or load/link the exception class */
1913 if (IS_CLASSREF(cr)) {
1914 /* The exception class reference is unresolved. */
1915 /* We have to do _eager_ resolving here. While the class of */
1916 /* the exception object is guaranteed to be loaded, it may */
1917 /* well have been loaded by a different loader than the */
1918 /* defining loader of m's class, which is the one we must */
1919 /* use to resolve the catch class. Thus lazy resolving */
1920 /* might fail, even if the result of the resolution would */
1921 /* be an already loaded class. */
1923 c = resolve_classref_eager(cr.ref);
1926 /* Exception resolving the exception class, argh! */
1930 /* Ok, we resolved it. Enter it in the table, so we don't */
1931 /* have to do this again. */
1932 /* XXX this write should be atomic. Is it? */
1934 ex->catchtype.cls = c;
1938 /* XXX I don't think this case can ever happen. -Edwin */
1939 if (!(c->state & CLASS_LOADED))
1940 /* use the methods' classloader */
1941 if (!load_class_from_classloader(c->name,
1942 m->class->classloader))
1945 /* XXX I think, if it is not linked, we can be sure that */
1946 /* the exception object is no (indirect) instance of it, no? */
1948 if (!(c->state & CLASS_LINKED))
1953 /* is the thrown exception an instance of the catch class? */
1955 if (builtin_instanceof(xptr, c)) {
1956 #if !defined(NDEBUG)
1957 /* Print stacktrace of exception when caught. */
1959 #if defined(ENABLE_VMLOG)
1960 vmlog_cacao_catch(xptr);
1963 if (opt_TraceExceptions) {
1964 exceptions_print_exception(xptr);
1965 stacktrace_print_trace(xptr);
1969 return ex->handlerpc;
1974 #if defined(ENABLE_THREADS)
1975 /* is this method synchronized? */
1978 /* get synchronization object */
1980 # if defined(__MIPS__) && (SIZEOF_VOID_P == 4)
1981 /* XXX change this if we ever want to use 4-byte stackslots */
1982 o = *((java_objectheader **) (sp + issync - 8));
1984 o = *((java_objectheader **) (sp + issync - SIZEOF_VOID_P));
1989 lock_monitor_exit(o);
1993 /* none of the exceptions catch this one */
1995 #if defined(ENABLE_VMLOG)
1996 vmlog_cacao_unwnd_method(m);
2001 #endif /* defined(ENABLE_JIT) */
2004 /* exceptions_print_exception **************************************************
2006 Prints an exception, the detail message and the cause, if
2007 available, with CACAO internal functions to stdout.
2009 *******************************************************************************/
2011 void exceptions_print_exception(java_objectheader *xptr)
2013 java_lang_Throwable *t;
2014 #if defined(ENABLE_JAVASE)
2015 java_lang_Throwable *cause;
2019 t = (java_lang_Throwable *) xptr;
2026 #if defined(ENABLE_JAVASE)
2030 /* print the root exception */
2032 utf_display_printable_ascii_classname(t->header.vftbl->class->name);
2034 if (t->detailMessage != NULL) {
2035 u = javastring_toutf((java_objectheader *) t->detailMessage, false);
2038 utf_display_printable_ascii(u);
2043 #if defined(ENABLE_JAVASE)
2044 /* print the cause if available */
2046 if ((cause != NULL) && (cause != t)) {
2047 printf("Caused by: ");
2048 utf_display_printable_ascii_classname(cause->header.vftbl->class->name);
2050 if (cause->detailMessage != NULL) {
2051 u = javastring_toutf((java_objectheader *) cause->detailMessage,
2055 utf_display_printable_ascii(u);
2064 /* exceptions_print_current_exception ******************************************
2066 Prints the current pending exception, the detail message and the
2067 cause, if available, with CACAO internal functions to stdout.
2069 *******************************************************************************/
2071 void exceptions_print_current_exception(void)
2073 java_objectheader *o;
2075 o = exceptions_get_exception();
2077 exceptions_print_exception(o);
2081 /* exceptions_print_stacktrace *************************************************
2083 Prints a pending exception with Throwable.printStackTrace(). If
2084 there happens an exception during printStackTrace(), we print the
2085 thrown exception and the original one.
2087 NOTE: This function calls Java code.
2089 *******************************************************************************/
2091 void exceptions_print_stacktrace(void)
2093 java_objectheader *oxptr;
2094 java_objectheader *xptr;
2098 /* get original exception */
2100 oxptr = exceptions_get_and_clear_exception();
2103 vm_abort("exceptions_print_stacktrace: no exception thrown");
2105 /* clear exception, because we are calling jit code again */
2107 c = oxptr->vftbl->class;
2109 /* find the printStackTrace() method */
2111 m = class_resolveclassmethod(c,
2112 utf_printStackTrace,
2114 class_java_lang_Object,
2118 vm_abort("exceptions_print_stacktrace: printStackTrace()V not found");
2120 /* print compatibility message */
2122 fprintf(stderr, "Exception in thread \"main\" ");
2124 /* print the stacktrace */
2126 (void) vm_call_method(m, oxptr);
2128 /* This normally means, we are EXTREMLY out of memory or
2129 have a serious problem while printStackTrace. But may
2130 be another exception, so print it. */
2132 xptr = exceptions_get_exception();
2135 fprintf(stderr, "Exception while printStackTrace(): ");
2137 /* now print original exception */
2139 exceptions_print_exception(xptr);
2140 stacktrace_print_trace(xptr);
2142 /* now print original exception */
2144 fprintf(stderr, "Original exception was: ");
2145 exceptions_print_exception(oxptr);
2146 stacktrace_print_trace(oxptr);
2154 * These are local overrides for various environment variables in Emacs.
2155 * Please do not remove this and leave it at the end of the file, where
2156 * Emacs will automagically detect them.
2157 * ---------------------------------------------------------------------
2160 * indent-tabs-mode: t
2164 * vim:noexpandtab:sw=4:ts=4: