1 /* src/vm/exceptions.c - exception related functions
3 Copyright (C) 1996-2005, 2006 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 Contact: cacao@cacaojvm.org
27 Authors: Christian Thalinger
29 Changes: Edwin Steiner
31 $Id: exceptions.c 5785 2006-10-15 22:25:54Z edwin $
45 #include "mm/memory.h"
46 #include "native/native.h"
47 #include "native/include/java_lang_String.h"
48 #include "native/include/java_lang_Throwable.h"
49 #include "toolbox/logging.h"
50 #include "toolbox/util.h"
52 #include "vm/exceptions.h"
53 #include "vm/global.h"
54 #include "vm/loader.h"
55 #include "vm/options.h"
56 #include "vm/stringlocal.h"
58 #include "vm/jit/asmpart.h"
59 #include "vm/jit/jit.h"
60 #include "vm/jit/methodheader.h"
63 /* for raising exceptions from native methods *********************************/
65 #if !defined(ENABLE_THREADS)
66 java_objectheader *_no_threads_exceptionptr = NULL;
70 /* init_system_exceptions ******************************************************
72 Load and link exceptions used in the system.
74 *******************************************************************************/
76 bool exceptions_init(void)
78 /* java/lang/Throwable */
80 if (!(class_java_lang_Throwable =
81 load_class_bootstrap(utf_java_lang_Throwable)) ||
82 !link_class(class_java_lang_Throwable))
86 /* java/lang/VMThrowable */
88 if (!(class_java_lang_VMThrowable =
89 load_class_bootstrap(utf_java_lang_VMThrowable)) ||
90 !link_class(class_java_lang_VMThrowable))
96 if (!(class_java_lang_Error = load_class_bootstrap(utf_java_lang_Error)) ||
97 !link_class(class_java_lang_Error))
100 /* java/lang/AbstractMethodError */
102 if (!(class_java_lang_AbstractMethodError =
103 load_class_bootstrap(utf_java_lang_AbstractMethodError)) ||
104 !link_class(class_java_lang_AbstractMethodError))
107 /* java/lang/LinkageError */
109 if (!(class_java_lang_LinkageError =
110 load_class_bootstrap(utf_java_lang_LinkageError)) ||
111 !link_class(class_java_lang_LinkageError))
114 /* java/lang/NoClassDefFoundError */
116 if (!(class_java_lang_NoClassDefFoundError =
117 load_class_bootstrap(utf_java_lang_NoClassDefFoundError)) ||
118 !link_class(class_java_lang_NoClassDefFoundError))
121 /* java/lang/NoSuchMethodError */
123 if (!(class_java_lang_NoSuchMethodError =
124 load_class_bootstrap(utf_java_lang_NoSuchMethodError)) ||
125 !link_class(class_java_lang_NoSuchMethodError))
128 /* java/lang/OutOfMemoryError */
130 if (!(class_java_lang_OutOfMemoryError =
131 load_class_bootstrap(utf_java_lang_OutOfMemoryError)) ||
132 !link_class(class_java_lang_OutOfMemoryError))
136 /* java/lang/Exception */
138 if (!(class_java_lang_Exception =
139 load_class_bootstrap(utf_java_lang_Exception)) ||
140 !link_class(class_java_lang_Exception))
143 /* java/lang/ClassCastException */
145 if (!(class_java_lang_ClassCastException =
146 load_class_bootstrap(utf_java_lang_ClassCastException)) ||
147 !link_class(class_java_lang_ClassCastException))
150 /* java/lang/ClassNotFoundException */
152 if (!(class_java_lang_ClassNotFoundException =
153 load_class_bootstrap(utf_java_lang_ClassNotFoundException)) ||
154 !link_class(class_java_lang_ClassNotFoundException))
157 /* java/lang/IllegalArgumentException */
159 if (!(class_java_lang_IllegalArgumentException =
160 load_class_bootstrap(utf_java_lang_IllegalArgumentException)) ||
161 !link_class(class_java_lang_IllegalArgumentException))
164 /* java/lang/IllegalMonitorStateException */
166 if (!(class_java_lang_IllegalMonitorStateException =
167 load_class_bootstrap(utf_java_lang_IllegalMonitorStateException)) ||
168 !link_class(class_java_lang_IllegalMonitorStateException))
171 /* java/lang/NullPointerException */
173 if (!(class_java_lang_NullPointerException =
174 load_class_bootstrap(utf_java_lang_NullPointerException)) ||
175 !link_class(class_java_lang_NullPointerException))
183 static void throw_exception_exit_intern(bool doexit)
185 java_objectheader *xptr;
189 xptr = *exceptionptr;
192 /* clear exception, because we are calling jit code again */
193 *exceptionptr = NULL;
195 c = xptr->vftbl->class;
197 pss = class_resolveclassmethod(c,
200 class_java_lang_Object,
203 /* print the stacktrace */
206 (void) vm_call_method(pss, xptr);
208 /* This normally means, we are EXTREMLY out of memory or have a */
209 /* serious problem while printStackTrace. But may be another */
210 /* exception, so print it. */
213 java_lang_Throwable *t;
215 t = (java_lang_Throwable *) *exceptionptr;
217 fprintf(stderr, "Exception while printStackTrace(): ");
218 utf_fprint_printable_ascii_classname(stderr, t->header.vftbl->class->name);
220 if (t->detailMessage) {
223 buf = javastring_tochar((java_objectheader *) t->detailMessage);
224 fprintf(stderr, ": %s", buf);
225 MFREE(buf, char, strlen(buf));
228 fprintf(stderr, "\n");
232 utf_fprint_printable_ascii_classname(stderr, c->name);
233 fprintf(stderr, ": printStackTrace()V not found!\n");
246 void throw_exception(void)
248 throw_exception_exit_intern(false);
252 void throw_exception_exit(void)
254 throw_exception_exit_intern(true);
258 void throw_main_exception(void)
260 fprintf(stderr, "Exception in thread \"main\" ");
263 throw_exception_exit_intern(false);
267 void throw_main_exception_exit(void)
269 fprintf(stderr, "Exception in thread \"main\" ");
272 throw_exception_exit_intern(true);
276 void throw_cacao_exception_exit(const char *exception, const char *message, ...)
283 len = strlen(exception);
284 tmp = MNEW(char, len + 1);
285 strncpy(tmp, exception, len);
288 /* convert to classname */
290 for (i = len - 1; i >= 0; i--)
291 if (tmp[i] == '/') tmp[i] = '.';
293 fprintf(stderr, "Exception in thread \"main\" %s", tmp);
295 MFREE(tmp, char, len);
297 if (strlen(message) > 0) {
298 fprintf(stderr, ": ");
300 va_start(ap, message);
301 vfprintf(stderr, message, ap);
305 fprintf(stderr, "\n");
314 /* exceptions_throw_outofmemory_exit *******************************************
316 Just print an: java.lang.InternalError: Out of memory
318 *******************************************************************************/
320 void exceptions_throw_outofmemory_exit(void)
322 throw_cacao_exception_exit(string_java_lang_InternalError,
327 /* new_exception ***************************************************************
329 Creates an exception object with the given name and initalizes it.
332 classname....class name in UTF-8
335 an exception pointer (in any case -- either it is the newly created
336 exception, or an exception thrown while trying to create it).
338 *******************************************************************************/
340 java_objectheader *new_exception(const char *classname)
342 java_objectheader *o;
345 if (!(c = load_class_bootstrap(utf_new_char(classname))))
346 return *exceptionptr;
348 o = native_new_and_init(c);
351 return *exceptionptr;
357 /* new_exception_message *******************************************************
359 Creates an exception object with the given name and initalizes it
360 with the given char message.
363 classname....class name in UTF-8
364 message......message in UTF-8
367 an exception pointer (in any case -- either it is the newly created
368 exception, or an exception thrown while trying to create it).
370 *******************************************************************************/
372 java_objectheader *new_exception_message(const char *classname,
377 s = javastring_new_from_utf_string(message);
379 return *exceptionptr;
381 return new_exception_javastring(classname, s);
385 /* new_exception_throwable *****************************************************
387 Creates an exception object with the given name and initalizes it
388 with the given java/lang/Throwable exception.
391 classname....class name in UTF-8
392 throwable....the given Throwable
395 an exception pointer (in any case -- either it is the newly created
396 exception, or an exception thrown while trying to create it).
398 *******************************************************************************/
400 java_objectheader *new_exception_throwable(const char *classname,
401 java_lang_Throwable *throwable)
403 java_objectheader *o;
406 if (!(c = load_class_bootstrap(utf_new_char(classname))))
407 return *exceptionptr;
409 o = native_new_and_init_throwable(c, throwable);
412 return *exceptionptr;
418 /* new_exception_utfmessage ****************************************************
420 Creates an exception object with the given name and initalizes it
421 with the given utf message.
424 classname....class name in UTF-8
425 message......the message as an utf *
428 an exception pointer (in any case -- either it is the newly created
429 exception, or an exception thrown while trying to create it).
431 *******************************************************************************/
433 java_objectheader *new_exception_utfmessage(const char *classname, utf *message)
437 s = javastring_new(message);
439 return *exceptionptr;
441 return new_exception_javastring(classname, s);
445 /* new_exception_javastring ****************************************************
447 Creates an exception object with the given name and initalizes it
448 with the given java/lang/String message.
451 classname....class name in UTF-8
452 message......the message as a java.lang.String
455 an exception pointer (in any case -- either it is the newly created
456 exception, or an exception thrown while trying to create it).
458 *******************************************************************************/
460 java_objectheader *new_exception_javastring(const char *classname,
461 java_lang_String *message)
463 java_objectheader *o;
466 if (!(c = load_class_bootstrap(utf_new_char(classname))))
467 return *exceptionptr;
469 o = native_new_and_init_string(c, message);
472 return *exceptionptr;
478 /* new_exception_int ***********************************************************
480 Creates an exception object with the given name and initalizes it
481 with the given int value.
484 classname....class name in UTF-8
485 i............the integer
488 an exception pointer (in any case -- either it is the newly created
489 exception, or an exception thrown while trying to create it).
491 *******************************************************************************/
493 java_objectheader *new_exception_int(const char *classname, s4 i)
495 java_objectheader *o;
498 if (!(c = load_class_bootstrap(utf_new_char(classname))))
499 return *exceptionptr;
501 o = native_new_and_init_int(c, i);
504 return *exceptionptr;
510 /* exceptions_new_abstractmethoderror ******************************************
512 Generates a java.lang.AbstractMethodError for the VM.
514 *******************************************************************************/
516 java_objectheader *exceptions_new_abstractmethoderror(void)
518 java_objectheader *e;
520 e = native_new_and_init(class_java_lang_AbstractMethodError);
523 return *exceptionptr;
529 /* exceptions_asm_new_abstractmethoderror **************************************
531 Generates a java.lang.AbstractMethodError for
532 asm_abstractmethoderror.
534 *******************************************************************************/
536 java_objectheader *exceptions_asm_new_abstractmethoderror(u1 *sp, u1 *ra)
539 java_objectheader *e;
541 /* create the stackframeinfo (XPC is equal to RA) */
543 stacktrace_create_extern_stackframeinfo(&sfi, NULL, sp, ra, ra);
545 /* create the exception */
547 e = exceptions_new_abstractmethoderror();
549 /* remove the stackframeinfo */
551 stacktrace_remove_stackframeinfo(&sfi);
557 /* exceptions_throw_abstractmethoderror ****************************************
559 Generates a java.lang.AbstractMethodError for the VM and throws it.
561 *******************************************************************************/
563 void exceptions_throw_abstractmethoderror(void)
565 *exceptionptr = exceptions_new_abstractmethoderror();
569 /* new_classformaterror ********************************************************
571 generates a java.lang.ClassFormatError for the classloader
574 c............the class in which the error was found
575 message......UTF-8 format string
578 an exception pointer (in any case -- either it is the newly created
579 exception, or an exception thrown while trying to create it).
581 *******************************************************************************/
583 java_objectheader *new_classformaterror(classinfo *c, const char *message, ...)
585 java_objectheader *o;
590 /* calculate message length */
595 msglen += utf_bytes(c->name) + strlen(" (");
597 va_start(ap, message);
598 msglen += get_variable_message_length(message, ap);
602 msglen += strlen(")");
604 msglen += strlen("0");
606 /* allocate a buffer */
608 msg = MNEW(char, msglen);
610 /* print message into allocated buffer */
613 utf_copy_classname(msg, c->name);
617 va_start(ap, message);
618 vsprintf(msg + strlen(msg), message, ap);
624 o = new_exception_message(string_java_lang_ClassFormatError, msg);
626 MFREE(msg, char, msglen);
632 /* exceptions_throw_classformaterror *******************************************
634 Generate a java.lang.ClassFormatError for the VM system and throw it.
637 c............the class in which the error was found
638 message......UTF-8 format string
641 an exception pointer (in any case -- either it is the newly created
642 exception, or an exception thrown while trying to create it).
644 *******************************************************************************/
646 void exceptions_throw_classformaterror(classinfo *c, const char *message, ...)
650 va_start(ap, message);
651 *exceptionptr = new_classformaterror(c, message, ap);
656 /* new_classnotfoundexception **************************************************
658 Generates a java.lang.ClassNotFoundException for the classloader.
661 name.........name of the class not found as a utf *
664 an exception pointer (in any case -- either it is the newly created
665 exception, or an exception thrown while trying to create it).
667 *******************************************************************************/
669 java_objectheader *new_classnotfoundexception(utf *name)
671 java_objectheader *o;
674 s = javastring_new(name);
676 return *exceptionptr;
678 o = native_new_and_init_string(class_java_lang_ClassNotFoundException, s);
681 return *exceptionptr;
687 /* new_noclassdeffounderror ****************************************************
689 Generates a java.lang.NoClassDefFoundError
692 name.........name of the class not found as a utf *
695 an exception pointer (in any case -- either it is the newly created
696 exception, or an exception thrown while trying to create it).
698 *******************************************************************************/
700 java_objectheader *new_noclassdeffounderror(utf *name)
702 java_objectheader *o;
705 s = javastring_new(name);
707 return *exceptionptr;
709 o = native_new_and_init_string(class_java_lang_NoClassDefFoundError, s);
712 return *exceptionptr;
718 /* classnotfoundexception_to_noclassdeffounderror ******************************
720 Check the *exceptionptr for a ClassNotFoundException. If it is one,
721 convert it to a NoClassDefFoundError.
723 *******************************************************************************/
725 void classnotfoundexception_to_noclassdeffounderror(void)
727 java_objectheader *xptr;
728 java_objectheader *cause;
732 cause = *exceptionptr;
734 /* convert ClassNotFoundException's to NoClassDefFoundError's */
736 if (builtin_instanceof(cause, class_java_lang_ClassNotFoundException)) {
737 /* clear exception, because we are calling jit code again */
739 *exceptionptr = NULL;
741 /* create new error */
744 new_exception_javastring(string_java_lang_NoClassDefFoundError,
745 ((java_lang_Throwable *) cause)->detailMessage);
747 /* we had an exception while creating the error */
752 /* set new exception */
754 *exceptionptr = xptr;
759 /* new_internalerror ***********************************************************
761 Generates a java.lang.InternalError for the VM.
764 message......UTF-8 message format string
767 an exception pointer (in any case -- either it is the newly created
768 exception, or an exception thrown while trying to create it).
770 *******************************************************************************/
772 java_objectheader *new_internalerror(const char *message, ...)
774 java_objectheader *o;
779 /* calculate exception message length */
781 va_start(ap, message);
782 msglen = get_variable_message_length(message, ap);
785 /* allocate memory */
787 msg = MNEW(char, msglen);
789 /* generate message */
791 va_start(ap, message);
792 vsprintf(msg, message, ap);
795 /* create exception object */
797 o = new_exception_message(string_java_lang_InternalError, msg);
801 MFREE(msg, char, msglen);
807 /* exceptions_new_linkageerror *************************************************
809 Generates a java.lang.LinkageError with an error message.
812 message......UTF-8 message
813 c............class related to the error. If this is != NULL
814 the name of c is appended to the error message.
817 an exception pointer (in any case -- either it is the newly created
818 exception, or an exception thrown while trying to create it).
820 *******************************************************************************/
822 java_objectheader *exceptions_new_linkageerror(const char *message,
825 java_objectheader *o;
829 /* calculate exception message length */
831 msglen = strlen(message) + 1;
833 msglen += utf_bytes(c->name);
836 /* allocate memory */
838 msg = MNEW(char, msglen);
840 /* generate message */
844 utf_cat_classname(msg, c->name);
847 o = native_new_and_init_string(class_java_lang_LinkageError,
848 javastring_new_from_utf_string(msg));
852 MFREE(msg, char, msglen);
855 return *exceptionptr;
861 /* exceptions_new_nosuchmethoderror ********************************************
863 Generates a java.lang.NoSuchMethodError with an error message.
866 c............class in which the method was not found
867 name.........name of the method
868 desc.........descriptor of the method
871 an exception pointer (in any case -- either it is the newly created
872 exception, or an exception thrown while trying to create it).
874 *******************************************************************************/
876 java_objectheader *exceptions_new_nosuchmethoderror(classinfo *c,
877 utf *name, utf *desc)
879 java_objectheader *o;
883 /* calculate exception message length */
885 msglen = utf_bytes(c->name) + strlen(".") + utf_bytes(name) +
886 utf_bytes(desc) + strlen("0");
888 /* allocate memory */
890 msg = MNEW(char, msglen);
892 /* generate message */
894 utf_copy_classname(msg, c->name);
899 o = native_new_and_init_string(class_java_lang_NoSuchMethodError,
900 javastring_new_from_utf_string(msg));
904 MFREE(msg, char, msglen);
907 return *exceptionptr;
913 /* exceptions_throw_nosuchmethoderror ******************************************
915 Generates a java.lang.NoSuchMethodError with an error message.
918 c............class in which the method was not found
919 name.........name of the method
920 desc.........descriptor of the method
922 *******************************************************************************/
924 void exceptions_throw_nosuchmethoderror(classinfo *c, utf *name, utf *desc)
926 *exceptionptr = exceptions_new_nosuchmethoderror(c, name, desc);
930 /* new_unsupportedclassversionerror ********************************************
932 Generate a java.lang.UnsupportedClassVersionError for the classloader
935 c............class in which the method was not found
936 message......UTF-8 format string
939 an exception pointer (in any case -- either it is the newly created
940 exception, or an exception thrown while trying to create it).
942 *******************************************************************************/
944 java_objectheader *new_unsupportedclassversionerror(classinfo *c, const char *message, ...)
946 java_objectheader *o;
951 /* calculate exception message length */
953 msglen = utf_bytes(c->name) + strlen(" (") + strlen(")") + strlen("0");
955 va_start(ap, message);
956 msglen += get_variable_message_length(message, ap);
959 /* allocate memory */
961 msg = MNEW(char, msglen);
963 /* generate message */
965 utf_copy_classname(msg, c->name);
968 va_start(ap, message);
969 vsprintf(msg + strlen(msg), message, ap);
974 /* create exception object */
976 o = new_exception_message(string_java_lang_UnsupportedClassVersionError,
981 MFREE(msg, char, msglen);
987 /* exceptions_new_verifyerror **************************************************
989 Generates a java.lang.VerifyError for the JIT compiler.
992 m............method in which the error was found
993 message......UTF-8 format string
996 an exception pointer (in any case -- either it is the newly created
997 exception, or an exception thrown while trying to create it).
999 *******************************************************************************/
1001 java_objectheader *exceptions_new_verifyerror(methodinfo *m,
1002 const char *message, ...)
1004 java_objectheader *o;
1009 useinlining = false; /* at least until sure inlining works with exceptions*/
1011 /* calculate exception message length */
1016 msglen = strlen("(class: ") + utf_bytes(m->class->name) +
1017 strlen(", method: ") + utf_bytes(m->name) +
1018 strlen(" signature: ") + utf_bytes(m->descriptor) +
1019 strlen(") ") + strlen("0");
1021 va_start(ap, message);
1022 msglen += get_variable_message_length(message, ap);
1025 /* allocate memory */
1027 msg = MNEW(char, msglen);
1029 /* generate message */
1032 strcpy(msg, "(class: ");
1033 utf_cat_classname(msg, m->class->name);
1034 strcat(msg, ", method: ");
1035 utf_cat(msg, m->name);
1036 strcat(msg, " signature: ");
1037 utf_cat(msg, m->descriptor);
1041 va_start(ap, message);
1042 vsprintf(msg + strlen(msg), message, ap);
1045 /* create exception object */
1047 o = new_exception_message(string_java_lang_VerifyError, msg);
1051 MFREE(msg, char, msglen);
1057 /* exceptions_throw_verifyerror ************************************************
1059 Throws a java.lang.VerifyError for the VM system.
1061 *******************************************************************************/
1063 void exceptions_throw_verifyerror(methodinfo *m, const char *message, ...)
1065 *exceptionptr = exceptions_new_verifyerror(m, message);
1069 /* exceptions_throw_verifyerror_for_stack **************************************
1071 throws a java.lang.VerifyError for an invalid stack slot type
1074 m............method in which the error was found
1075 type.........the expected type
1078 an exception pointer (in any case -- either it is the newly created
1079 exception, or an exception thrown while trying to create it).
1081 *******************************************************************************/
1083 void exceptions_throw_verifyerror_for_stack(methodinfo *m,int type)
1085 java_objectheader *o;
1090 /* calculate exception message length */
1095 msglen = strlen("(class: ") + utf_bytes(m->class->name) +
1096 strlen(", method: ") + utf_bytes(m->name) +
1097 strlen(" signature: ") + utf_bytes(m->descriptor) +
1098 strlen(") Expecting to find longest-------typename on stack")
1101 /* allocate memory */
1103 msg = MNEW(char, msglen);
1105 /* generate message */
1108 strcpy(msg, "(class: ");
1109 utf_cat_classname(msg, m->class->name);
1110 strcat(msg, ", method: ");
1111 utf_cat(msg, m->name);
1112 strcat(msg, " signature: ");
1113 utf_cat(msg, m->descriptor);
1120 strcat(msg,"Expecting to find ");
1122 case TYPE_INT: typename = "integer"; break;
1123 case TYPE_LNG: typename = "long"; break;
1124 case TYPE_FLT: typename = "float"; break;
1125 case TYPE_DBL: typename = "double"; break;
1126 case TYPE_ADR: typename = "object/array"; break;
1127 case TYPE_RET: typename = "returnAddress"; break;
1128 default: typename = "<INVALID>"; assert(0); break;
1130 strcat(msg, typename);
1131 strcat(msg, " on stack");
1133 /* create exception object */
1135 o = new_exception_message(string_java_lang_VerifyError, msg);
1139 MFREE(msg, char, msglen);
1145 /* new_arithmeticexception *****************************************************
1147 Generates a java.lang.ArithmeticException for the jit compiler.
1149 *******************************************************************************/
1151 java_objectheader *new_arithmeticexception(void)
1153 java_objectheader *e;
1155 e = new_exception_message(string_java_lang_ArithmeticException,
1156 string_java_lang_ArithmeticException_message);
1159 return *exceptionptr;
1165 /* exceptions_new_arrayindexoutofboundsexception *******************************
1167 Generates a java.lang.ArrayIndexOutOfBoundsException for the VM
1170 *******************************************************************************/
1172 java_objectheader *new_arrayindexoutofboundsexception(s4 index)
1174 java_objectheader *e;
1176 java_objectheader *o;
1177 java_lang_String *s;
1179 /* convert the index into a String, like Sun does */
1181 m = class_resolveclassmethod(class_java_lang_String,
1182 utf_new_char("valueOf"),
1183 utf_new_char("(I)Ljava/lang/String;"),
1184 class_java_lang_Object,
1188 return *exceptionptr;
1190 o = vm_call_method(m, NULL, index);
1192 s = (java_lang_String *) o;
1195 return *exceptionptr;
1197 e = new_exception_javastring(string_java_lang_ArrayIndexOutOfBoundsException,
1201 return *exceptionptr;
1207 /* exceptions_throw_arrayindexoutofboundsexception *****************************
1209 Generates a java.lang.ArrayIndexOutOfBoundsException for the VM
1212 *******************************************************************************/
1214 void exceptions_throw_arrayindexoutofboundsexception(void)
1216 java_objectheader *e;
1218 e = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
1227 /* exceptions_new_arraystoreexception ******************************************
1229 Generates a java.lang.ArrayStoreException for the VM compiler.
1231 *******************************************************************************/
1233 java_objectheader *exceptions_new_arraystoreexception(void)
1235 java_objectheader *e;
1237 e = new_exception(string_java_lang_ArrayStoreException);
1238 /* e = native_new_and_init(class_java_lang_ArrayStoreException); */
1241 return *exceptionptr;
1247 /* exceptions_throw_arraystoreexception ****************************************
1249 Generates a java.lang.ArrayStoreException for the VM system and
1250 throw it in the VM system.
1252 *******************************************************************************/
1254 void exceptions_throw_arraystoreexception(void)
1256 *exceptionptr = exceptions_new_arraystoreexception();
1260 /* exceptions_new_classcastexception *******************************************
1262 Generates a java.lang.ClassCastException for the JIT compiler.
1264 *******************************************************************************/
1266 java_objectheader *exceptions_new_classcastexception(java_objectheader *o)
1268 java_objectheader *e;
1270 java_lang_String *s;
1272 classname = o->vftbl->class->name;
1274 s = javastring_new(classname);
1276 e = native_new_and_init_string(class_java_lang_ClassCastException, s);
1279 return *exceptionptr;
1285 /* exceptions_new_illegalargumentexception *************************************
1287 Generates a java.lang.IllegalArgumentException for the VM system.
1289 *******************************************************************************/
1291 java_objectheader *new_illegalargumentexception(void)
1293 java_objectheader *e;
1295 e = native_new_and_init(class_java_lang_IllegalArgumentException);
1298 return *exceptionptr;
1304 /* exceptions_throw_illegalargumentexception ***********************************
1306 Generates a java.lang.IllegalArgumentException for the VM system
1307 and throw it in the VM system.
1309 *******************************************************************************/
1311 void exceptions_throw_illegalargumentexception(void)
1313 *exceptionptr = new_illegalargumentexception();
1317 /* exceptions_new_illegalmonitorstateexception *********************************
1319 Generates a java.lang.IllegalMonitorStateException for the VM
1322 *******************************************************************************/
1324 java_objectheader *exceptions_new_illegalmonitorstateexception(void)
1326 java_objectheader *e;
1328 e = native_new_and_init(class_java_lang_IllegalMonitorStateException);
1331 return *exceptionptr;
1337 /* exceptions_throw_illegalmonitorstateexception *******************************
1339 Generates a java.lang.IllegalMonitorStateException for the VM
1340 system and throw it in the VM system.
1342 *******************************************************************************/
1344 void exceptions_throw_illegalmonitorstateexception(void)
1346 *exceptionptr = exceptions_new_illegalmonitorstateexception();
1350 /* exceptions_new_negativearraysizeexception ***********************************
1352 Generates a java.lang.NegativeArraySizeException for the VM system.
1354 *******************************************************************************/
1356 java_objectheader *new_negativearraysizeexception(void)
1358 java_objectheader *e;
1360 e = new_exception(string_java_lang_NegativeArraySizeException);
1363 return *exceptionptr;
1369 /* exceptions_throw_negativearraysizeexception *********************************
1371 Generates a java.lang.NegativeArraySizeException for the VM system.
1373 *******************************************************************************/
1375 void exceptions_throw_negativearraysizeexception(void)
1377 *exceptionptr = new_negativearraysizeexception();
1381 /* new_nullpointerexception ****************************************************
1383 generates a java.lang.NullPointerException for the jit compiler
1385 *******************************************************************************/
1387 java_objectheader *new_nullpointerexception(void)
1389 java_objectheader *e;
1391 e = native_new_and_init(class_java_lang_NullPointerException);
1394 return *exceptionptr;
1400 /* exceptions_throw_nullpointerexception ***************************************
1402 Generates a java.lang.NullPointerException for the VM system and
1403 throw it in the VM system.
1405 *******************************************************************************/
1407 void exceptions_throw_nullpointerexception(void)
1409 *exceptionptr = new_nullpointerexception();
1413 /* exceptions_new_stringindexoutofboundsexception ******************************
1415 Generates a java.lang.StringIndexOutOfBoundsException for the VM
1418 *******************************************************************************/
1420 java_objectheader *exceptions_new_stringindexoutofboundsexception(void)
1422 java_objectheader *e;
1424 e = new_exception(string_java_lang_StringIndexOutOfBoundsException);
1427 return *exceptionptr;
1433 /* exceptions_throw_stringindexoutofboundsexception ****************************
1435 Throws a java.lang.StringIndexOutOfBoundsException for the VM
1438 *******************************************************************************/
1440 void exceptions_throw_stringindexoutofboundsexception(void)
1442 *exceptionptr = exceptions_new_stringindexoutofboundsexception();
1446 /* exceptions_get_and_clear_exception ******************************************
1448 Gets the exception pointer of the current thread and clears it.
1449 This function may return NULL.
1451 *******************************************************************************/
1453 java_objectheader *exceptions_get_and_clear_exception(void)
1455 java_objectheader **p;
1456 java_objectheader *e;
1458 /* get the pointer of the exception pointer */
1462 /* get the exception */
1466 /* and clear the exception */
1470 /* return the exception */
1476 /* exceptions_handle_exception *************************************************
1478 Try to find an exception handler for the given exception and return it.
1479 If no handler is found, exit the monitor of the method (if any)
1483 xptr.........the exception object
1484 xpc..........PC of where the exception was thrown
1485 pv...........Procedure Value of the current method
1486 sp...........current stack pointer
1489 the address of the first matching exception handler, or
1490 NULL if no handler was found
1492 *******************************************************************************/
1494 u1 *exceptions_handle_exception(java_objectheader *xptr, u1 *xpc, u1 *pv, u1 *sp)
1500 dseg_exception_entry *ex;
1501 s4 exceptiontablelength;
1503 classref_or_classinfo cr;
1505 #if defined(ENABLE_THREADS)
1506 java_objectheader *o;
1509 /* get info from the method header */
1511 code = *((codeinfo **) (pv + CodeinfoPointer));
1512 framesize = *((s4 *) (pv + FrameSize));
1513 issync = *((s4 *) (pv + IsSync));
1514 ex = (dseg_exception_entry *)
1515 (pv + ExTableStart);
1516 exceptiontablelength = *((s4 *) (pv + ExTableSize));
1518 /* Get the methodinfo pointer from the codeinfo pointer. For
1519 asm_vm_call_method the codeinfo pointer is NULL. */
1521 m = (code == NULL) ? NULL : code->m;
1523 #if !defined(NDEBUG)
1524 /* print exception trace */
1526 if (opt_verbose || opt_verbosecall || opt_verboseexception)
1527 builtin_trace_exception(xptr, m, xpc, 1);
1530 for (i = 0; i < exceptiontablelength; i++) {
1531 /* ATTENTION: keep this here, as we need to decrement the
1532 pointer before the loop executes! */
1536 /* If the start and end PC is NULL, this means we have the
1537 special case of asm_vm_call_method. So, just return the
1538 proper exception handler. */
1540 if ((ex->startpc == NULL) && (ex->endpc == NULL))
1541 return (u1 *) (ptrint) &asm_vm_call_method_exception_handler;
1543 /* is the xpc is the current catch range */
1545 if ((ex->startpc <= xpc) && (xpc < ex->endpc)) {
1548 /* NULL catches everything */
1550 if (cr.any == NULL) {
1551 #if !defined(NDEBUG)
1552 /* Print stacktrace of exception when caught. */
1554 if (opt_verboseexception) {
1555 exceptions_print_exception(xptr);
1556 stacktrace_print_trace(xptr);
1560 return ex->handlerpc;
1563 /* resolve or load/link the exception class */
1565 if (IS_CLASSREF(cr)) {
1566 /* The exception class reference is unresolved. */
1567 /* We have to do _eager_ resolving here. While the class of */
1568 /* the exception object is guaranteed to be loaded, it may */
1569 /* well have been loaded by a different loader than the */
1570 /* defining loader of m's class, which is the one we must */
1571 /* use to resolve the catch class. Thus lazy resolving */
1572 /* might fail, even if the result of the resolution would */
1573 /* be an already loaded class. */
1575 c = resolve_classref_eager(cr.ref);
1578 /* Exception resolving the exception class, argh! */
1582 /* Ok, we resolved it. Enter it in the table, so we don't */
1583 /* have to do this again. */
1584 /* XXX this write should be atomic. Is it? */
1586 ex->catchtype.cls = c;
1590 /* XXX I don't think this case can ever happen. -Edwin */
1591 if (!(c->state & CLASS_LOADED))
1592 /* use the methods' classloader */
1593 if (!load_class_from_classloader(c->name,
1594 m->class->classloader))
1597 /* XXX I think, if it is not linked, we can be sure that */
1598 /* the exception object is no (indirect) instance of it, no? */
1600 if (!(c->state & CLASS_LINKED))
1605 /* is the thrown exception an instance of the catch class? */
1607 if (builtin_instanceof(xptr, c)) {
1608 #if !defined(NDEBUG)
1609 /* Print stacktrace of exception when caught. */
1611 if (opt_verboseexception) {
1612 exceptions_print_exception(xptr);
1613 stacktrace_print_trace(xptr);
1617 return ex->handlerpc;
1622 #if defined(ENABLE_THREADS)
1623 /* is this method synchronized? */
1626 /* get synchronization object */
1628 # if defined(__MIPS__) && (SIZEOF_VOID_P == 4)
1629 /* XXX change this if we ever want to use 4-byte stackslots */
1630 o = *((java_objectheader **) (sp + issync - 8));
1632 o = *((java_objectheader **) (sp + issync - SIZEOF_VOID_P));
1637 lock_monitor_exit(o);
1641 /* none of the exceptions catch this one */
1647 /* exceptions_print_exception **************************************************
1649 Prints an exception, the detail message and the cause, if
1650 available, with CACAO internal functions to stdout.
1652 *******************************************************************************/
1654 #if !defined(NDEBUG)
1655 void exceptions_print_exception(java_objectheader *xptr)
1657 java_lang_Throwable *t;
1658 java_lang_Throwable *cause;
1661 t = (java_lang_Throwable *) xptr;
1670 /* print the root exception */
1672 utf_display_printable_ascii_classname(t->header.vftbl->class->name);
1674 if (t->detailMessage) {
1675 u = javastring_toutf(t->detailMessage, false);
1678 utf_display_printable_ascii(u);
1683 /* print the cause if available */
1685 if (cause && (cause != t)) {
1686 printf("Caused by: ");
1687 utf_display_printable_ascii_classname(cause->header.vftbl->class->name);
1689 if (cause->detailMessage) {
1690 u = javastring_toutf(cause->detailMessage, false);
1693 utf_display_printable_ascii(u);
1699 #endif /* !defined(NDEBUG) */
1703 * These are local overrides for various environment variables in Emacs.
1704 * Please do not remove this and leave it at the end of the file, where
1705 * Emacs will automagically detect them.
1706 * ---------------------------------------------------------------------
1709 * indent-tabs-mode: t
1713 * vim:noexpandtab:sw=4:ts=4: