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 8062 2007-06-11 08:12:14Z twisti $
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/stacktrace.h"
69 #include "vmcore/class.h"
70 #include "vmcore/loader.h"
71 #include "vmcore/method.h"
72 #include "vmcore/options.h"
74 #if defined(ENABLE_VMLOG)
75 #include <vmlog_cacao.h>
79 /* for raising exceptions from native methods *********************************/
81 #if !defined(ENABLE_THREADS)
82 java_objectheader *_no_threads_exceptionptr = NULL;
86 /* init_system_exceptions ******************************************************
88 Load and link exceptions used in the system.
90 *******************************************************************************/
92 bool exceptions_init(void)
96 /* mmap a memory page at address 0x0, so our hardware-exceptions
99 pagesize = getpagesize();
101 (void) memory_mmap_anon(NULL, pagesize, PROT_NONE, MAP_PRIVATE | MAP_FIXED);
103 /* check if we get into trouble with our hardware-exceptions */
105 if (OFFSET(java_bytearray, data) <= EXCEPTION_HARDWARE_PATCHER)
106 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);
108 /* java/lang/Throwable */
110 if (!(class_java_lang_Throwable =
111 load_class_bootstrap(utf_java_lang_Throwable)) ||
112 !link_class(class_java_lang_Throwable))
115 /* java/lang/Error */
117 if (!(class_java_lang_Error = load_class_bootstrap(utf_java_lang_Error)) ||
118 !link_class(class_java_lang_Error))
121 #if defined(ENABLE_JAVASE)
122 /* java/lang/LinkageError */
124 if (!(class_java_lang_LinkageError =
125 load_class_bootstrap(utf_java_lang_LinkageError)) ||
126 !link_class(class_java_lang_LinkageError))
130 /* java/lang/NoClassDefFoundError */
132 if (!(class_java_lang_NoClassDefFoundError =
133 load_class_bootstrap(utf_java_lang_NoClassDefFoundError)) ||
134 !link_class(class_java_lang_NoClassDefFoundError))
137 /* java/lang/OutOfMemoryError */
139 if (!(class_java_lang_OutOfMemoryError =
140 load_class_bootstrap(utf_java_lang_OutOfMemoryError)) ||
141 !link_class(class_java_lang_OutOfMemoryError))
144 /* java/lang/VirtualMachineError */
146 if (!(class_java_lang_VirtualMachineError =
147 load_class_bootstrap(utf_java_lang_VirtualMachineError)) ||
148 !link_class(class_java_lang_VirtualMachineError))
152 /* java/lang/Exception */
154 if (!(class_java_lang_Exception =
155 load_class_bootstrap(utf_java_lang_Exception)) ||
156 !link_class(class_java_lang_Exception))
159 /* java/lang/ClassCastException */
161 if (!(class_java_lang_ClassCastException =
162 load_class_bootstrap(utf_java_lang_ClassCastException)) ||
163 !link_class(class_java_lang_ClassCastException))
166 /* java/lang/ClassNotFoundException */
168 if (!(class_java_lang_ClassNotFoundException =
169 load_class_bootstrap(utf_java_lang_ClassNotFoundException)) ||
170 !link_class(class_java_lang_ClassNotFoundException))
173 /* java/lang/NullPointerException */
175 if (!(class_java_lang_NullPointerException =
176 load_class_bootstrap(utf_java_lang_NullPointerException)) ||
177 !link_class(class_java_lang_NullPointerException))
181 #if defined(WITH_CLASSPATH_GNU)
182 /* java/lang/VMThrowable */
184 if (!(class_java_lang_VMThrowable =
185 load_class_bootstrap(utf_java_lang_VMThrowable)) ||
186 !link_class(class_java_lang_VMThrowable))
194 /* exceptions_new_class ********************************************************
196 Creates an exception object from the given class and initalizes it.
199 class....class pointer
201 *******************************************************************************/
203 static java_objectheader *exceptions_new_class(classinfo *c)
205 java_objectheader *o;
207 o = native_new_and_init(c);
210 return *exceptionptr;
216 /* exceptions_new_utf **********************************************************
218 Creates an exception object with the given name and initalizes it.
221 classname....class name in UTF-8
223 *******************************************************************************/
225 static java_objectheader *exceptions_new_utf(utf *classname)
228 java_objectheader *o;
230 c = load_class_bootstrap(classname);
233 return *exceptionptr;
235 o = exceptions_new_class(c);
241 /* exceptions_throw_class ******************************************************
243 Creates an exception object from the given class, initalizes and
247 class....class pointer
249 *******************************************************************************/
251 static void exceptions_throw_class(classinfo *c)
253 java_objectheader *o;
255 o = exceptions_new_class(c);
264 /* exceptions_throw_utf ********************************************************
266 Creates an exception object with the given name, initalizes and
270 classname....class name in UTF-8
272 *******************************************************************************/
274 static void exceptions_throw_utf(utf *classname)
278 c = load_class_bootstrap(classname);
283 exceptions_throw_class(c);
287 /* exceptions_throw_utf_throwable **********************************************
289 Creates an exception object with the given name and initalizes it
290 with the given java/lang/Throwable exception.
293 classname....class name in UTF-8
294 cause........the given Throwable
296 *******************************************************************************/
298 static void exceptions_throw_utf_throwable(utf *classname,
299 java_objectheader *cause)
302 java_objectheader *o;
304 java_lang_Throwable *object;
306 object = (java_lang_Throwable *) cause;
308 c = load_class_bootstrap(classname);
320 /* call initializer */
322 m = class_findmethod(c, utf_init, utf_java_lang_String__void);
327 (void) vm_call_method(m, o, object->detailMessage);
331 m = class_resolvemethod(c,
333 utf_java_lang_Throwable__java_lang_Throwable);
338 (void) vm_call_method(m, o, cause);
340 exceptions_set_exception(o);
344 /* exceptions_throw_utf_exception **********************************************
346 Creates an exception object with the given name and initalizes it
347 with the given java/lang/Exception exception.
350 classname....class name in UTF-8
351 exception....the given Exception
353 *******************************************************************************/
355 static void exceptions_throw_utf_exception(utf *classname,
356 java_objectheader *exception)
359 java_objectheader *o;
362 c = load_class_bootstrap(classname);
374 /* call initializer */
376 m = class_findmethod(c, utf_init, utf_java_lang_Exception__V);
381 (void) vm_call_method(m, o, exception);
383 exceptions_set_exception(o);
387 /* exceptions_new_utf_javastring ***********************************************
389 Creates an exception object with the given name and initalizes it
390 with the given java/lang/String message.
393 classname....class name in UTF-8
394 message......the message as a java.lang.String
397 an exception pointer (in any case -- either it is the newly created
398 exception, or an exception thrown while trying to create it).
400 *******************************************************************************/
402 static java_objectheader *exceptions_new_utf_javastring(utf *classname,
403 java_objectheader *message)
405 java_objectheader *o;
408 c = load_class_bootstrap(classname);
411 return *exceptionptr;
413 o = native_new_and_init_string(c, message);
416 return *exceptionptr;
422 /* exceptions_new_class_utf ****************************************************
424 Creates an exception object of the given class and initalizes it.
427 c..........class pointer
428 message....the message as UTF-8 string
430 *******************************************************************************/
432 static java_objectheader *exceptions_new_class_utf(classinfo *c, utf *message)
434 java_objectheader *o;
435 java_objectheader *s;
437 s = javastring_new(message);
440 return *exceptionptr;
442 o = native_new_and_init_string(c, s);
445 return *exceptionptr;
451 /* exceptions_new_utf_utf ******************************************************
453 Creates an exception object with the given name and initalizes it
454 with the given utf message.
457 classname....class name in UTF-8
458 message......the message as an utf *
461 an exception pointer (in any case -- either it is the newly created
462 exception, or an exception thrown while trying to create it).
464 *******************************************************************************/
466 static java_objectheader *exceptions_new_utf_utf(utf *classname, utf *message)
469 java_objectheader *o;
471 c = load_class_bootstrap(classname);
474 return *exceptionptr;
476 o = exceptions_new_class_utf(c, message);
482 /* exceptions_throw_class_utf **************************************************
484 Creates an exception object of the given class, initalizes and
485 throws it with the given utf message.
488 c..........class pointer
489 message....the message as an UTF-8
491 *******************************************************************************/
493 static void exceptions_throw_class_utf(classinfo *c, utf *message)
495 *exceptionptr = exceptions_new_class_utf(c, message);
499 /* exceptions_throw_utf_utf ****************************************************
501 Creates an exception object with the given name, initalizes and
502 throws it with the given utf message.
505 classname....class name in UTF-8
506 message......the message as an utf *
508 *******************************************************************************/
510 static void exceptions_throw_utf_utf(utf *classname, utf *message)
512 *exceptionptr = exceptions_new_utf_utf(classname, message);
516 /* exceptions_new_abstractmethoderror ****************************************
518 Generates a java.lang.AbstractMethodError for the VM.
520 *******************************************************************************/
522 java_objectheader *exceptions_new_abstractmethoderror(void)
524 java_objectheader *o;
526 o = exceptions_new_utf(utf_java_lang_AbstractMethodError);
532 /* exceptions_new_error ********************************************************
534 Generates a java.lang.Error for the VM.
536 *******************************************************************************/
538 #if defined(ENABLE_JAVAME_CLDC1_1)
539 static java_objectheader *exceptions_new_error(utf *message)
541 java_objectheader *o;
543 o = exceptions_new_class_utf(class_java_lang_Error, message);
550 /* exceptions_asm_new_abstractmethoderror **************************************
552 Generates a java.lang.AbstractMethodError for
553 asm_abstractmethoderror.
555 *******************************************************************************/
557 java_objectheader *exceptions_asm_new_abstractmethoderror(u1 *sp, u1 *ra)
560 java_objectheader *e;
562 /* create the stackframeinfo (XPC is equal to RA) */
564 stacktrace_create_extern_stackframeinfo(&sfi, NULL, sp, ra, ra);
566 /* create the exception */
568 #if defined(ENABLE_JAVASE)
569 e = exceptions_new_abstractmethoderror();
571 e = exceptions_new_error(utf_java_lang_AbstractMethodError);
574 /* remove the stackframeinfo */
576 stacktrace_remove_stackframeinfo(&sfi);
582 /* exceptions_new_arraystoreexception ******************************************
584 Generates a java.lang.ArrayStoreException for the VM.
586 *******************************************************************************/
588 java_objectheader *exceptions_new_arraystoreexception(void)
590 java_objectheader *o;
592 o = exceptions_new_utf(utf_java_lang_ArrayStoreException);
598 /* exceptions_throw_abstractmethoderror ****************************************
600 Generates and throws a java.lang.AbstractMethodError for the VM.
602 *******************************************************************************/
604 void exceptions_throw_abstractmethoderror(void)
606 exceptions_throw_utf(utf_java_lang_AbstractMethodError);
610 /* exceptions_throw_classcircularityerror **************************************
612 Generates and throws a java.lang.ClassCircularityError for the
616 c....the class in which the error was found
618 *******************************************************************************/
620 void exceptions_throw_classcircularityerror(classinfo *c)
622 exceptions_throw_utf_utf(utf_java_lang_ClassCircularityError, c->name);
626 /* exceptions_throw_classformaterror *******************************************
628 Generates and throws a java.lang.ClassFormatError for the VM.
631 c............the class in which the error was found
632 message......UTF-8 format string
634 *******************************************************************************/
636 void exceptions_throw_classformaterror(classinfo *c, const char *message, ...)
643 /* calculate message length */
648 msglen += utf_bytes(c->name) + strlen(" (");
650 va_start(ap, message);
651 msglen += get_variable_message_length(message, ap);
655 msglen += strlen(")");
657 msglen += strlen("0");
659 /* allocate a buffer */
661 msg = MNEW(char, msglen);
663 /* print message into allocated buffer */
666 utf_copy_classname(msg, c->name);
670 va_start(ap, message);
671 vsprintf(msg + strlen(msg), message, ap);
677 u = utf_new_char(msg);
681 MFREE(msg, char, msglen);
683 /* throw exception */
685 exceptions_throw_utf_utf(utf_java_lang_ClassFormatError, u);
689 /* exceptions_throw_classnotfoundexception *************************************
691 Generates and throws a java.lang.ClassNotFoundException for the
695 name.........name of the class not found as a utf *
697 *******************************************************************************/
699 void exceptions_throw_classnotfoundexception(utf *name)
701 /* we use class here, as this one is rather frequent */
703 exceptions_throw_class_utf(class_java_lang_ClassNotFoundException, name);
707 /* exceptions_throw_noclassdeffounderror ***************************************
709 Generates and throws a java.lang.NoClassDefFoundError.
712 name.........name of the class not found as a utf *
714 *******************************************************************************/
716 void exceptions_throw_noclassdeffounderror(utf *name)
719 vm_abort("java.lang.NoClassDefFoundError: %s", name->text);
721 exceptions_throw_class_utf(class_java_lang_NoClassDefFoundError, name);
725 /* exceptions_throw_noclassdeffounderror_cause *********************************
727 Generates and throws a java.lang.NoClassDefFoundError with the
730 *******************************************************************************/
732 void exceptions_throw_noclassdeffounderror_cause(java_objectheader *cause)
734 exceptions_throw_utf_throwable(utf_java_lang_NoClassDefFoundError, cause);
738 /* exceptions_throw_noclassdeffounderror_wrong_name ****************************
740 Generates and throws a java.lang.NoClassDefFoundError with a
744 name.........name of the class not found as a utf *
746 *******************************************************************************/
748 void exceptions_throw_noclassdeffounderror_wrong_name(classinfo *c, utf *name)
754 msglen = utf_bytes(c->name) + strlen(" (wrong name: ") +
755 utf_bytes(name) + strlen(")") + strlen("0");
757 msg = MNEW(char, msglen);
759 utf_copy_classname(msg, c->name);
760 strcat(msg, " (wrong name: ");
761 utf_cat_classname(msg, name);
764 u = utf_new_char(msg);
766 MFREE(msg, char, msglen);
768 exceptions_throw_noclassdeffounderror(u);
772 /* exceptions_throw_exceptionininitializererror ********************************
774 Generates and throws a java.lang.ExceptionInInitializerError for
778 cause......cause exception object
780 *******************************************************************************/
782 void exceptions_throw_exceptionininitializererror(java_objectheader *cause)
784 exceptions_throw_utf_throwable(utf_java_lang_ExceptionInInitializerError,
789 /* exceptions_throw_incompatibleclasschangeerror *******************************
791 Generates and throws a java.lang.IncompatibleClassChangeError for
795 message......UTF-8 message format string
797 *******************************************************************************/
799 void exceptions_throw_incompatibleclasschangeerror(classinfo *c, const char *message)
805 /* calculate exception message length */
807 msglen = utf_bytes(c->name) + strlen(message) + strlen("0");
809 /* allocate memory */
811 msg = MNEW(char, msglen);
813 utf_copy_classname(msg, c->name);
814 strcat(msg, message);
816 u = utf_new_char(msg);
820 MFREE(msg, char, msglen);
822 /* throw exception */
824 exceptions_throw_utf_utf(utf_java_lang_IncompatibleClassChangeError, u);
828 /* exceptions_throw_instantiationerror *****************************************
830 Generates and throws a java.lang.InstantiationError for the VM.
832 *******************************************************************************/
834 void exceptions_throw_instantiationerror(classinfo *c)
836 exceptions_throw_utf_utf(utf_java_lang_InstantiationError, c->name);
840 /* exceptions_throw_internalerror **********************************************
842 Generates and throws a java.lang.InternalError for the VM.
845 message......UTF-8 message format string
847 *******************************************************************************/
849 void exceptions_throw_internalerror(const char *message, ...)
856 /* calculate exception message length */
858 va_start(ap, message);
859 msglen = get_variable_message_length(message, ap);
862 /* allocate memory */
864 msg = MNEW(char, msglen);
866 /* generate message */
868 va_start(ap, message);
869 vsprintf(msg, message, ap);
872 u = utf_new_char(msg);
876 MFREE(msg, char, msglen);
878 /* throw exception */
880 exceptions_throw_utf_utf(utf_java_lang_InternalError, u);
884 /* exceptions_throw_linkageerror ***********************************************
886 Generates and throws java.lang.LinkageError with an error message.
889 message......UTF-8 message
890 c............class related to the error. If this is != NULL
891 the name of c is appended to the error message.
893 *******************************************************************************/
895 void exceptions_throw_linkageerror(const char *message, classinfo *c)
897 java_objectheader *o;
901 /* calculate exception message length */
903 msglen = strlen(message) + 1;
906 msglen += utf_bytes(c->name);
908 /* allocate memory */
910 msg = MNEW(char, msglen);
912 /* generate message */
917 utf_cat_classname(msg, c->name);
919 o = native_new_and_init_string(class_java_lang_LinkageError,
920 javastring_new_from_utf_string(msg));
924 MFREE(msg, char, msglen);
933 /* exceptions_throw_nosuchfielderror *******************************************
935 Generates and throws a java.lang.NoSuchFieldError with an error
939 c............class in which the field was not found
940 name.........name of the field
942 *******************************************************************************/
944 void exceptions_throw_nosuchfielderror(classinfo *c, utf *name)
950 /* calculate exception message length */
952 msglen = utf_bytes(c->name) + strlen(".") + utf_bytes(name) + strlen("0");
954 /* allocate memory */
956 msg = MNEW(char, msglen);
958 /* generate message */
960 utf_copy_classname(msg, c->name);
964 u = utf_new_char(msg);
968 MFREE(msg, char, msglen);
970 exceptions_throw_utf_utf(utf_java_lang_NoSuchFieldError, u);
974 /* exceptions_throw_nosuchmethoderror ******************************************
976 Generates and throws a java.lang.NoSuchMethodError with an error
980 c............class in which the method was not found
981 name.........name of the method
982 desc.........descriptor of the method
984 *******************************************************************************/
986 void exceptions_throw_nosuchmethoderror(classinfo *c, utf *name, utf *desc)
992 /* calculate exception message length */
994 msglen = utf_bytes(c->name) + strlen(".") + utf_bytes(name) +
995 utf_bytes(desc) + strlen("0");
997 /* allocate memory */
999 msg = MNEW(char, msglen);
1001 /* generate message */
1003 utf_copy_classname(msg, c->name);
1008 u = utf_new_char(msg);
1012 MFREE(msg, char, msglen);
1014 #if defined(ENABLE_JAVASE)
1015 exceptions_throw_utf_utf(utf_java_lang_NoSuchMethodError, u);
1017 exceptions_throw_class_utf(class_java_lang_Error, u);
1022 /* exceptions_throw_outofmemoryerror *******************************************
1024 Generates and throws an java.lang.OutOfMemoryError for the VM.
1026 *******************************************************************************/
1028 void exceptions_throw_outofmemoryerror(void)
1030 exceptions_throw_class(class_java_lang_OutOfMemoryError);
1034 /* exceptions_throw_unsatisfiedlinkerror ***************************************
1036 Generates and throws a java.lang.UnsatisfiedLinkError for the
1040 name......UTF-8 name string
1042 *******************************************************************************/
1044 void exceptions_throw_unsatisfiedlinkerror(utf *name)
1046 #if defined(ENABLE_JAVASE)
1047 exceptions_throw_utf_utf(utf_java_lang_UnsatisfiedLinkError, name);
1049 exceptions_throw_class_utf(class_java_lang_Error, name);
1054 /* exceptions_throw_unsupportedclassversionerror *******************************
1056 Generates and throws a java.lang.UnsupportedClassVersionError for
1060 c............class in which the method was not found
1061 message......UTF-8 format string
1063 *******************************************************************************/
1065 void exceptions_throw_unsupportedclassversionerror(classinfo *c, u4 ma, u4 mi)
1071 /* calculate exception message length */
1074 utf_bytes(c->name) +
1075 strlen(" (Unsupported major.minor version 00.0)") +
1078 /* allocate memory */
1080 msg = MNEW(char, msglen);
1082 /* generate message */
1084 utf_copy_classname(msg, c->name);
1085 sprintf(msg + strlen(msg), " (Unsupported major.minor version %d.%d)",
1088 u = utf_new_char(msg);
1092 MFREE(msg, char, msglen);
1094 /* throw exception */
1096 exceptions_throw_utf_utf(utf_java_lang_UnsupportedClassVersionError, u);
1100 /* exceptions_throw_verifyerror ************************************************
1102 Generates and throws a java.lang.VerifyError for the JIT compiler.
1105 m............method in which the error was found
1106 message......UTF-8 format string
1108 *******************************************************************************/
1110 void exceptions_throw_verifyerror(methodinfo *m, const char *message, ...)
1117 /* calculate exception message length */
1123 strlen("(class: ") + utf_bytes(m->class->name) +
1124 strlen(", method: ") + utf_bytes(m->name) +
1125 strlen(" signature: ") + utf_bytes(m->descriptor) +
1126 strlen(") ") + strlen("0");
1128 va_start(ap, message);
1129 msglen += get_variable_message_length(message, ap);
1132 /* allocate memory */
1134 msg = MNEW(char, msglen);
1136 /* generate message */
1139 strcpy(msg, "(class: ");
1140 utf_cat_classname(msg, m->class->name);
1141 strcat(msg, ", method: ");
1142 utf_cat(msg, m->name);
1143 strcat(msg, " signature: ");
1144 utf_cat(msg, m->descriptor);
1148 va_start(ap, message);
1149 vsprintf(msg + strlen(msg), message, ap);
1152 u = utf_new_char(msg);
1156 MFREE(msg, char, msglen);
1158 /* throw exception */
1160 exceptions_throw_utf_utf(utf_java_lang_VerifyError, u);
1164 /* exceptions_throw_verifyerror_for_stack **************************************
1166 throws a java.lang.VerifyError for an invalid stack slot type
1169 m............method in which the error was found
1170 type.........the expected type
1173 an exception pointer (in any case -- either it is the newly created
1174 exception, or an exception thrown while trying to create it).
1176 *******************************************************************************/
1178 void exceptions_throw_verifyerror_for_stack(methodinfo *m, int type)
1185 /* calculate exception message length */
1190 msglen = strlen("(class: ") + utf_bytes(m->class->name) +
1191 strlen(", method: ") + utf_bytes(m->name) +
1192 strlen(" signature: ") + utf_bytes(m->descriptor) +
1193 strlen(") Expecting to find longest-------typename on stack")
1196 /* allocate memory */
1198 msg = MNEW(char, msglen);
1200 /* generate message */
1203 strcpy(msg, "(class: ");
1204 utf_cat_classname(msg, m->class->name);
1205 strcat(msg, ", method: ");
1206 utf_cat(msg, m->name);
1207 strcat(msg, " signature: ");
1208 utf_cat(msg, m->descriptor);
1215 strcat(msg, "Expecting to find ");
1218 case TYPE_INT: typename = "integer"; break;
1219 case TYPE_LNG: typename = "long"; break;
1220 case TYPE_FLT: typename = "float"; break;
1221 case TYPE_DBL: typename = "double"; break;
1222 case TYPE_ADR: typename = "object/array"; break;
1223 case TYPE_RET: typename = "returnAddress"; break;
1224 default: typename = "<INVALID>"; assert(0); break;
1227 strcat(msg, typename);
1228 strcat(msg, " on stack");
1230 u = utf_new_char(msg);
1234 MFREE(msg, char, msglen);
1236 /* throw exception */
1238 exceptions_throw_utf_utf(utf_java_lang_VerifyError, u);
1242 /* exceptions_new_arithmeticexception ******************************************
1244 Generates a java.lang.ArithmeticException for the JIT compiler.
1246 *******************************************************************************/
1248 java_objectheader *exceptions_new_arithmeticexception(void)
1250 java_objectheader *o;
1252 o = exceptions_new_utf_utf(utf_java_lang_ArithmeticException,
1253 utf_division_by_zero);
1259 /* exceptions_new_arrayindexoutofboundsexception *******************************
1261 Generates a java.lang.ArrayIndexOutOfBoundsException for the VM
1264 *******************************************************************************/
1266 java_objectheader *exceptions_new_arrayindexoutofboundsexception(s4 index)
1268 java_objectheader *o;
1270 java_objectheader *s;
1272 /* convert the index into a String, like Sun does */
1274 m = class_resolveclassmethod(class_java_lang_String,
1275 utf_new_char("valueOf"),
1276 utf_new_char("(I)Ljava/lang/String;"),
1277 class_java_lang_Object,
1281 return *exceptionptr;
1283 s = vm_call_method(m, NULL, index);
1286 return *exceptionptr;
1288 o = exceptions_new_utf_javastring(utf_java_lang_ArrayIndexOutOfBoundsException,
1292 return *exceptionptr;
1298 /* exceptions_throw_arrayindexoutofboundsexception *****************************
1300 Generates and throws a java.lang.ArrayIndexOutOfBoundsException for
1303 *******************************************************************************/
1305 void exceptions_throw_arrayindexoutofboundsexception(void)
1307 exceptions_throw_utf(utf_java_lang_ArrayIndexOutOfBoundsException);
1311 /* exceptions_throw_arraystoreexception ****************************************
1313 Generates and throws a java.lang.ArrayStoreException for the VM.
1315 *******************************************************************************/
1317 void exceptions_throw_arraystoreexception(void)
1319 exceptions_throw_utf(utf_java_lang_ArrayStoreException);
1320 /* e = native_new_and_init(class_java_lang_ArrayStoreException); */
1324 /* exceptions_new_classcastexception *******************************************
1326 Generates a java.lang.ClassCastException for the JIT compiler.
1328 *******************************************************************************/
1330 java_objectheader *exceptions_new_classcastexception(java_objectheader *o)
1332 java_objectheader *e;
1335 classname = o->vftbl->class->name;
1337 e = exceptions_new_class_utf(class_java_lang_ClassCastException, classname);
1343 /* exceptions_throw_clonenotsupportedexception *********************************
1345 Generates and throws a java.lang.CloneNotSupportedException for the
1348 *******************************************************************************/
1350 void exceptions_throw_clonenotsupportedexception(void)
1352 exceptions_throw_utf(utf_java_lang_CloneNotSupportedException);
1356 /* exceptions_throw_illegalaccessexception *************************************
1358 Generates and throws a java.lang.IllegalAccessException for the VM.
1360 *******************************************************************************/
1362 void exceptions_throw_illegalaccessexception(utf *message)
1364 exceptions_throw_utf_utf(utf_java_lang_IllegalAccessException, message);
1368 /* exceptions_throw_illegalargumentexception ***********************************
1370 Generates and throws a java.lang.IllegalArgumentException for the
1373 *******************************************************************************/
1375 void exceptions_throw_illegalargumentexception(void)
1377 exceptions_throw_utf(utf_java_lang_IllegalArgumentException);
1381 /* exceptions_throw_illegalmonitorstateexception *******************************
1383 Generates and throws a java.lang.IllegalMonitorStateException for
1386 *******************************************************************************/
1388 void exceptions_throw_illegalmonitorstateexception(void)
1390 exceptions_throw_utf(utf_java_lang_IllegalMonitorStateException);
1394 /* exceptions_throw_instantiationexception *************************************
1396 Generates and throws a java.lang.InstantiationException for the VM.
1398 *******************************************************************************/
1400 void exceptions_throw_instantiationexception(classinfo *c)
1402 exceptions_throw_utf_utf(utf_java_lang_InstantiationException, c->name);
1406 /* exceptions_throw_interruptedexception ***************************************
1408 Generates and throws a java.lang.InterruptedException for the VM.
1410 *******************************************************************************/
1412 void exceptions_throw_interruptedexception(void)
1414 exceptions_throw_utf(utf_java_lang_InterruptedException);
1418 /* exceptions_throw_invocationtargetexception **********************************
1420 Generates and throws a java.lang.reflect.InvocationTargetException
1424 cause......cause exception object
1426 *******************************************************************************/
1428 void exceptions_throw_invocationtargetexception(java_objectheader *cause)
1430 exceptions_throw_utf_throwable(utf_java_lang_reflect_InvocationTargetException,
1435 /* exceptions_throw_negativearraysizeexception *********************************
1437 Generates and throws a java.lang.NegativeArraySizeException for the
1440 *******************************************************************************/
1442 void exceptions_throw_negativearraysizeexception(void)
1444 exceptions_throw_utf(utf_java_lang_NegativeArraySizeException);
1448 /* exceptions_new_nullpointerexception *****************************************
1450 Generates a java.lang.NullPointerException for the VM system.
1452 *******************************************************************************/
1454 java_objectheader *exceptions_new_nullpointerexception(void)
1456 java_objectheader *o;
1458 o = exceptions_new_class(class_java_lang_NullPointerException);
1464 /* exceptions_throw_nullpointerexception ***************************************
1466 Generates a java.lang.NullPointerException for the VM system and
1467 throw it in the VM system.
1469 *******************************************************************************/
1471 void exceptions_throw_nullpointerexception(void)
1473 exceptions_throw_class(class_java_lang_NullPointerException);
1477 /* exceptions_throw_privilegedactionexception **********************************
1479 Generates and throws a java.security.PrivilegedActionException.
1481 *******************************************************************************/
1483 void exceptions_throw_privilegedactionexception(java_objectheader *exception)
1485 exceptions_throw_utf_exception(utf_java_security_PrivilegedActionException,
1490 /* exceptions_throw_stringindexoutofboundsexception ****************************
1492 Generates and throws a java.lang.StringIndexOutOfBoundsException
1495 *******************************************************************************/
1497 void exceptions_throw_stringindexoutofboundsexception(void)
1499 exceptions_throw_utf(utf_java_lang_StringIndexOutOfBoundsException);
1503 /* exceptions_classnotfoundexception_to_noclassdeffounderror *******************
1505 Check the *exceptionptr for a ClassNotFoundException. If it is one,
1506 convert it to a NoClassDefFoundError.
1508 *******************************************************************************/
1510 void exceptions_classnotfoundexception_to_noclassdeffounderror(void)
1512 java_objectheader *o;
1513 java_objectheader *cause;
1514 java_lang_Throwable *object;
1515 java_objectheader *s;
1519 cause = exceptions_get_exception();
1521 /* convert ClassNotFoundException's to NoClassDefFoundError's */
1523 if (builtin_instanceof(cause, class_java_lang_ClassNotFoundException)) {
1524 /* clear exception, because we are calling jit code again */
1526 exceptions_clear_exception();
1528 /* create new error */
1530 object = (java_lang_Throwable *) cause;
1531 s = (java_objectheader *) object->detailMessage;
1533 o = exceptions_new_utf_javastring(utf_java_lang_NoClassDefFoundError,
1536 /* we had an exception while creating the error */
1538 if (exceptions_get_exception())
1541 /* set new exception */
1543 exceptions_set_exception(o);
1548 /* exceptions_get_exception ****************************************************
1550 Returns the current exception pointer of the current thread.
1552 *******************************************************************************/
1554 java_objectheader *exceptions_get_exception(void)
1556 /* return the exception */
1558 return *exceptionptr;
1562 /* exceptions_set_exception ****************************************************
1564 Sets the exception pointer of the current thread.
1566 *******************************************************************************/
1568 void exceptions_set_exception(java_objectheader *o)
1570 /* set the exception */
1576 /* exceptions_clear_exception **************************************************
1578 Clears the current exception pointer of the current thread.
1580 *******************************************************************************/
1582 void exceptions_clear_exception(void)
1584 /* and clear the exception */
1586 *exceptionptr = NULL;
1590 /* exceptions_fillinstacktrace *************************************************
1592 Calls the fillInStackTrace-method of the currently thrown
1595 *******************************************************************************/
1597 java_objectheader *exceptions_fillinstacktrace(void)
1599 java_objectheader *o;
1607 /* clear exception */
1609 *exceptionptr = NULL;
1611 /* resolve methodinfo pointer from exception object */
1613 #if defined(ENABLE_JAVASE)
1614 m = class_resolvemethod(o->vftbl->class,
1615 utf_fillInStackTrace,
1616 utf_void__java_lang_Throwable);
1617 #elif defined(ENABLE_JAVAME_CLDC1_1)
1618 m = class_resolvemethod(o->vftbl->class,
1619 utf_fillInStackTrace,
1622 #error IMPLEMENT ME!
1627 (void) vm_call_method(m, o);
1629 /* return exception object */
1635 /* exceptions_get_and_clear_exception ******************************************
1637 Gets the exception pointer of the current thread and clears it.
1638 This function may return NULL.
1640 *******************************************************************************/
1642 java_objectheader *exceptions_get_and_clear_exception(void)
1644 java_objectheader **p;
1645 java_objectheader *e;
1647 /* get the pointer of the exception pointer */
1651 /* get the exception */
1655 /* and clear the exception */
1659 /* return the exception */
1665 /* exceptions_new_hardware_exception *******************************************
1667 Creates the correct exception for a hardware-exception thrown and
1668 caught by a signal handler.
1670 *******************************************************************************/
1672 java_objectheader *exceptions_new_hardware_exception(u1 *pv, u1 *sp, u1 *ra, u1 *xpc, s4 type, ptrint val)
1675 java_objectheader *e;
1676 java_objectheader *o;
1679 /* create stackframeinfo */
1681 stacktrace_create_extern_stackframeinfo(&sfi, pv, sp, ra, xpc);
1684 case EXCEPTION_HARDWARE_NULLPOINTER:
1685 e = exceptions_new_nullpointerexception();
1688 case EXCEPTION_HARDWARE_ARITHMETIC:
1689 e = exceptions_new_arithmeticexception();
1692 case EXCEPTION_HARDWARE_ARRAYINDEXOUTOFBOUNDS:
1694 e = exceptions_new_arrayindexoutofboundsexception(index);
1697 case EXCEPTION_HARDWARE_CLASSCAST:
1698 o = (java_objectheader *) val;
1699 e = exceptions_new_classcastexception(o);
1702 case EXCEPTION_HARDWARE_EXCEPTION:
1703 e = exceptions_fillinstacktrace();
1707 /* let's try to get a backtrace */
1709 codegen_get_pv_from_pc(xpc);
1711 /* if that does not work, print more debug info */
1713 log_println("exceptions_new_hardware_exception: unknown exception type %d", type);
1715 #if SIZEOF_VOID_P == 8
1716 log_println("PC=0x%016lx", xpc);
1718 log_println("PC=0x%08x", xpc);
1721 #if defined(ENABLE_DISASSEMBLER)
1722 log_println("machine instruction at PC:");
1726 vm_abort("Exiting...");
1728 /* keep compiler happy */
1733 /* remove stackframeinfo */
1735 stacktrace_remove_stackframeinfo(&sfi);
1737 /* return the exception object */
1743 /* exceptions_handle_exception *************************************************
1745 Try to find an exception handler for the given exception and return it.
1746 If no handler is found, exit the monitor of the method (if any)
1750 xptr.........the exception object
1751 xpc..........PC of where the exception was thrown
1752 pv...........Procedure Value of the current method
1753 sp...........current stack pointer
1756 the address of the first matching exception handler, or
1757 NULL if no handler was found
1759 *******************************************************************************/
1761 #if defined(ENABLE_JIT)
1762 u1 *exceptions_handle_exception(java_objectheader *xptr, u1 *xpc, u1 *pv, u1 *sp)
1767 dseg_exception_entry *ex;
1768 s4 exceptiontablelength;
1770 classref_or_classinfo cr;
1772 #if defined(ENABLE_THREADS)
1773 java_objectheader *o;
1777 /* Addresses are 31 bit integers */
1778 # define ADDR_MASK(x) (u1 *)((u4)(x) & 0x7FFFFFFF)
1780 # define ADDR_MASK(x) (x)
1783 xpc = ADDR_MASK(xpc);
1785 /* get info from the method header */
1787 code = *((codeinfo **) (pv + CodeinfoPointer));
1788 issync = *((s4 *) (pv + IsSync));
1789 ex = (dseg_exception_entry *) (pv + ExTableStart);
1790 exceptiontablelength = *((s4 *) (pv + ExTableSize));
1792 /* Get the methodinfo pointer from the codeinfo pointer. For
1793 asm_vm_call_method the codeinfo pointer is NULL. */
1795 m = (code == NULL) ? NULL : code->m;
1797 #if !defined(NDEBUG)
1798 /* print exception trace */
1800 if (opt_verbose || opt_verbosecall || opt_verboseexception)
1801 builtin_trace_exception(xptr, m, xpc, 1);
1804 #if defined(ENABLE_VMLOG)
1805 vmlog_cacao_throw(xptr);
1808 for (i = 0; i < exceptiontablelength; i++) {
1809 /* ATTENTION: keep this here, as we need to decrement the
1810 pointer before the loop executes! */
1814 /* If the start and end PC is NULL, this means we have the
1815 special case of asm_vm_call_method. So, just return the
1816 proper exception handler. */
1818 if ((ex->startpc == NULL) && (ex->endpc == NULL))
1819 return (u1 *) (ptrint) &asm_vm_call_method_exception_handler;
1821 /* is the xpc is the current catch range */
1823 if ((ADDR_MASK(ex->startpc) <= xpc) && (xpc < ADDR_MASK(ex->endpc))) {
1826 /* NULL catches everything */
1828 if (cr.any == NULL) {
1829 #if !defined(NDEBUG)
1830 /* Print stacktrace of exception when caught. */
1832 #if defined(ENABLE_VMLOG)
1833 vmlog_cacao_catch(xptr);
1836 if (opt_verboseexception) {
1837 exceptions_print_exception(xptr);
1838 stacktrace_print_trace(xptr);
1842 return ex->handlerpc;
1845 /* resolve or load/link the exception class */
1847 if (IS_CLASSREF(cr)) {
1848 /* The exception class reference is unresolved. */
1849 /* We have to do _eager_ resolving here. While the class of */
1850 /* the exception object is guaranteed to be loaded, it may */
1851 /* well have been loaded by a different loader than the */
1852 /* defining loader of m's class, which is the one we must */
1853 /* use to resolve the catch class. Thus lazy resolving */
1854 /* might fail, even if the result of the resolution would */
1855 /* be an already loaded class. */
1857 c = resolve_classref_eager(cr.ref);
1860 /* Exception resolving the exception class, argh! */
1864 /* Ok, we resolved it. Enter it in the table, so we don't */
1865 /* have to do this again. */
1866 /* XXX this write should be atomic. Is it? */
1868 ex->catchtype.cls = c;
1872 /* XXX I don't think this case can ever happen. -Edwin */
1873 if (!(c->state & CLASS_LOADED))
1874 /* use the methods' classloader */
1875 if (!load_class_from_classloader(c->name,
1876 m->class->classloader))
1879 /* XXX I think, if it is not linked, we can be sure that */
1880 /* the exception object is no (indirect) instance of it, no? */
1882 if (!(c->state & CLASS_LINKED))
1887 /* is the thrown exception an instance of the catch class? */
1889 if (builtin_instanceof(xptr, c)) {
1890 #if !defined(NDEBUG)
1891 /* Print stacktrace of exception when caught. */
1893 #if defined(ENABLE_VMLOG)
1894 vmlog_cacao_catch(xptr);
1897 if (opt_verboseexception) {
1898 exceptions_print_exception(xptr);
1899 stacktrace_print_trace(xptr);
1903 return ex->handlerpc;
1908 #if defined(ENABLE_THREADS)
1909 /* is this method synchronized? */
1912 /* get synchronization object */
1914 # if defined(__MIPS__) && (SIZEOF_VOID_P == 4)
1915 /* XXX change this if we ever want to use 4-byte stackslots */
1916 o = *((java_objectheader **) (sp + issync - 8));
1918 o = *((java_objectheader **) (sp + issync - SIZEOF_VOID_P));
1923 lock_monitor_exit(o);
1927 /* none of the exceptions catch this one */
1929 #if defined(ENABLE_VMLOG)
1930 vmlog_cacao_unwnd_method(m);
1935 #endif /* defined(ENABLE_JIT) */
1938 /* exceptions_print_exception **************************************************
1940 Prints an exception, the detail message and the cause, if
1941 available, with CACAO internal functions to stdout.
1943 *******************************************************************************/
1945 void exceptions_print_exception(java_objectheader *xptr)
1947 java_lang_Throwable *t;
1948 #if defined(ENABLE_JAVASE)
1949 java_lang_Throwable *cause;
1953 t = (java_lang_Throwable *) xptr;
1960 #if defined(ENABLE_JAVASE)
1964 /* print the root exception */
1966 utf_display_printable_ascii_classname(t->header.vftbl->class->name);
1968 if (t->detailMessage != NULL) {
1969 u = javastring_toutf((java_objectheader *) t->detailMessage, false);
1972 utf_display_printable_ascii(u);
1977 #if defined(ENABLE_JAVASE)
1978 /* print the cause if available */
1980 if ((cause != NULL) && (cause != t)) {
1981 printf("Caused by: ");
1982 utf_display_printable_ascii_classname(cause->header.vftbl->class->name);
1984 if (cause->detailMessage != NULL) {
1985 u = javastring_toutf((java_objectheader *) cause->detailMessage,
1989 utf_display_printable_ascii(u);
1998 /* exceptions_print_current_exception ******************************************
2000 Prints the current pending exception, the detail message and the
2001 cause, if available, with CACAO internal functions to stdout.
2003 *******************************************************************************/
2005 void exceptions_print_current_exception(void)
2007 java_objectheader *xptr;
2009 xptr = *exceptionptr;
2011 exceptions_print_exception(xptr);
2015 /* exceptions_print_stacktrace *************************************************
2017 Prints a pending exception with Throwable.printStackTrace(). If
2018 there happens an exception during printStackTrace(), we print the
2019 thrown exception and the original one.
2021 NOTE: This function calls Java code.
2023 *******************************************************************************/
2025 void exceptions_print_stacktrace(void)
2027 java_objectheader *oxptr;
2028 java_objectheader *xptr;
2032 /* get original exception */
2034 oxptr = exceptions_get_and_clear_exception();
2037 vm_abort("exceptions_print_stacktrace: no exception thrown");
2039 /* clear exception, because we are calling jit code again */
2041 c = oxptr->vftbl->class;
2043 /* find the printStackTrace() method */
2045 m = class_resolveclassmethod(c,
2046 utf_printStackTrace,
2048 class_java_lang_Object,
2052 vm_abort("exceptions_print_stacktrace: printStackTrace()V not found");
2054 /* print compatibility message */
2056 fprintf(stderr, "Exception in thread \"main\" ");
2058 /* print the stacktrace */
2060 (void) vm_call_method(m, oxptr);
2062 /* This normally means, we are EXTREMLY out of memory or
2063 have a serious problem while printStackTrace. But may
2064 be another exception, so print it. */
2066 xptr = exceptions_get_exception();
2069 fprintf(stderr, "Exception while printStackTrace(): ");
2071 /* now print original exception */
2073 exceptions_print_exception(xptr);
2074 stacktrace_print_trace(xptr);
2076 /* now print original exception */
2078 fprintf(stderr, "Original exception was: ");
2079 exceptions_print_exception(oxptr);
2080 stacktrace_print_trace(oxptr);
2088 * These are local overrides for various environment variables in Emacs.
2089 * Please do not remove this and leave it at the end of the file, where
2090 * Emacs will automagically detect them.
2091 * ---------------------------------------------------------------------
2094 * indent-tabs-mode: t
2098 * vim:noexpandtab:sw=4:ts=4: