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 5166 2006-07-21 10:09:33Z twisti $
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 default: typename = "<INVALID>"; assert(0); break;
1129 strcat(msg, typename);
1130 strcat(msg, " on stack");
1132 /* create exception object */
1134 o = new_exception_message(string_java_lang_VerifyError, msg);
1138 MFREE(msg, char, msglen);
1144 /* new_arithmeticexception *****************************************************
1146 Generates a java.lang.ArithmeticException for the jit compiler.
1148 *******************************************************************************/
1150 java_objectheader *new_arithmeticexception(void)
1152 java_objectheader *e;
1154 e = new_exception_message(string_java_lang_ArithmeticException,
1155 string_java_lang_ArithmeticException_message);
1158 return *exceptionptr;
1164 /* exceptions_new_arrayindexoutofboundsexception *******************************
1166 Generates a java.lang.ArrayIndexOutOfBoundsException for the VM
1169 *******************************************************************************/
1171 java_objectheader *new_arrayindexoutofboundsexception(s4 index)
1173 java_objectheader *e;
1175 java_objectheader *o;
1176 java_lang_String *s;
1178 /* convert the index into a String, like Sun does */
1180 m = class_resolveclassmethod(class_java_lang_String,
1181 utf_new_char("valueOf"),
1182 utf_new_char("(I)Ljava/lang/String;"),
1183 class_java_lang_Object,
1187 return *exceptionptr;
1189 o = vm_call_method(m, NULL, index);
1191 s = (java_lang_String *) o;
1194 return *exceptionptr;
1196 e = new_exception_javastring(string_java_lang_ArrayIndexOutOfBoundsException,
1200 return *exceptionptr;
1206 /* exceptions_throw_arrayindexoutofboundsexception *****************************
1208 Generates a java.lang.ArrayIndexOutOfBoundsException for the VM
1211 *******************************************************************************/
1213 void exceptions_throw_arrayindexoutofboundsexception(void)
1215 java_objectheader *e;
1217 e = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
1226 /* new_arraystoreexception *****************************************************
1228 generates a java.lang.ArrayStoreException for the jit compiler
1230 *******************************************************************************/
1232 java_objectheader *new_arraystoreexception(void)
1234 java_objectheader *e;
1236 e = new_exception(string_java_lang_ArrayStoreException);
1237 /* e = native_new_and_init(class_java_lang_ArrayStoreException); */
1240 return *exceptionptr;
1246 /* exceptions_new_classcastexception *******************************************
1248 Generates a java.lang.ClassCastException for the JIT compiler.
1250 *******************************************************************************/
1252 java_objectheader *exceptions_new_classcastexception(java_objectheader *o)
1254 java_objectheader *e;
1256 java_lang_String *s;
1258 classname = o->vftbl->class->name;
1260 s = javastring_new(classname);
1262 e = native_new_and_init_string(class_java_lang_ClassCastException, s);
1265 return *exceptionptr;
1271 /* exceptions_new_illegalargumentexception *************************************
1273 Generates a java.lang.IllegalArgumentException for the VM system.
1275 *******************************************************************************/
1277 java_objectheader *new_illegalargumentexception(void)
1279 java_objectheader *e;
1281 e = native_new_and_init(class_java_lang_IllegalArgumentException);
1284 return *exceptionptr;
1290 /* exceptions_throw_illegalargumentexception ***********************************
1292 Generates a java.lang.IllegalArgumentException for the VM system
1293 and throw it in the VM system.
1295 *******************************************************************************/
1297 void exceptions_throw_illegalargumentexception(void)
1299 *exceptionptr = new_illegalargumentexception();
1303 /* new_illegalmonitorstateexception ********************************************
1305 Generates a java.lang.IllegalMonitorStateException for the VM
1308 *******************************************************************************/
1310 java_objectheader *new_illegalmonitorstateexception(void)
1312 java_objectheader *e;
1314 e = native_new_and_init(class_java_lang_IllegalMonitorStateException);
1317 return *exceptionptr;
1323 /* exceptions_new_negativearraysizeexception ***********************************
1325 Generates a java.lang.NegativeArraySizeException for the VM system.
1327 *******************************************************************************/
1329 java_objectheader *new_negativearraysizeexception(void)
1331 java_objectheader *e;
1333 e = new_exception(string_java_lang_NegativeArraySizeException);
1336 return *exceptionptr;
1342 /* exceptions_throw_negativearraysizeexception *********************************
1344 Generates a java.lang.NegativeArraySizeException for the VM system.
1346 *******************************************************************************/
1348 void exceptions_throw_negativearraysizeexception(void)
1350 *exceptionptr = new_negativearraysizeexception();
1354 /* new_nullpointerexception ****************************************************
1356 generates a java.lang.NullPointerException for the jit compiler
1358 *******************************************************************************/
1360 java_objectheader *new_nullpointerexception(void)
1362 java_objectheader *e;
1364 e = native_new_and_init(class_java_lang_NullPointerException);
1367 return *exceptionptr;
1373 /* exceptions_throw_nullpointerexception ***************************************
1375 Generates a java.lang.NullPointerException for the VM system and
1376 throw it in the VM system.
1378 *******************************************************************************/
1380 void exceptions_throw_nullpointerexception(void)
1382 *exceptionptr = new_nullpointerexception();
1386 /* exceptions_new_stringindexoutofboundsexception ******************************
1388 Generates a java.lang.StringIndexOutOfBoundsException for the VM
1391 *******************************************************************************/
1393 java_objectheader *exceptions_new_stringindexoutofboundsexception(void)
1395 java_objectheader *e;
1397 e = new_exception(string_java_lang_StringIndexOutOfBoundsException);
1400 return *exceptionptr;
1406 /* exceptions_throw_stringindexoutofboundsexception ****************************
1408 Throws a java.lang.StringIndexOutOfBoundsException for the VM
1411 *******************************************************************************/
1413 void exceptions_throw_stringindexoutofboundsexception(void)
1415 *exceptionptr = exceptions_new_stringindexoutofboundsexception();
1419 /* exceptions_get_and_clear_exception ******************************************
1421 Gets the exception pointer of the current thread and clears it.
1422 This function may return NULL.
1424 *******************************************************************************/
1426 java_objectheader *exceptions_get_and_clear_exception(void)
1428 java_objectheader **p;
1429 java_objectheader *e;
1431 /* get the pointer of the exception pointer */
1435 /* get the exception */
1439 /* and clear the exception */
1443 /* return the exception */
1449 /* exceptions_handle_exception *************************************************
1451 Try to find an exception handler for the given exception and return it.
1452 If no handler is found, exit the monitor of the method (if any)
1456 xptr.........the exception object
1457 xpc..........PC of where the exception was thrown
1458 pv...........Procedure Value of the current method
1459 sp...........current stack pointer
1462 the address of the first matching exception handler, or
1463 NULL if no handler was found
1465 *******************************************************************************/
1467 u1 *exceptions_handle_exception(java_objectheader *xptr, u1 *xpc, u1 *pv, u1 *sp)
1474 s4 exceptiontablelength;
1476 classref_or_classinfo cr;
1478 #if defined(ENABLE_THREADS)
1479 java_objectheader *o;
1482 /* get info from the method header */
1484 code = *((codeinfo **) (pv + CodeinfoPointer));
1485 framesize = *((s4 *) (pv + FrameSize));
1486 issync = *((s4 *) (pv + IsSync));
1487 ex = (exceptionentry *) (pv + ExTableStart);
1488 exceptiontablelength = *((s4 *) (pv + ExTableSize));
1490 /* Get the methodinfo pointer from the codeinfo pointer. For
1491 asm_vm_call_method the codeinfo pointer is NULL. */
1493 m = (code == NULL) ? NULL : code->m;
1495 #if !defined(NDEBUG)
1496 /* print exception trace */
1498 if (opt_verbose || opt_verbosecall || opt_verboseexception)
1499 builtin_trace_exception(xptr, m, xpc, 1);
1502 for (i = 0; i < exceptiontablelength; i++) {
1503 /* ATTENTION: keep this here, as we need to decrement the
1504 pointer before the loop executes! */
1508 /* If the start and end PC is NULL, this means we have the
1509 special case of asm_vm_call_method. So, just return the
1510 proper exception handler. */
1512 if ((ex->startpc == NULL) && (ex->endpc == NULL))
1513 return (u1 *) (ptrint) &asm_vm_call_method_exception_handler;
1515 /* is the xpc is the current catch range */
1517 if ((ex->startpc <= xpc) && (xpc < ex->endpc)) {
1520 /* NULL catches everything */
1522 if (cr.any == NULL) {
1523 #if !defined(NDEBUG)
1524 /* Print stacktrace of exception when caught. */
1526 if (opt_verboseexception) {
1527 exceptions_print_exception(xptr);
1528 stacktrace_print_trace(xptr);
1532 return ex->handlerpc;
1535 /* resolve or load/link the exception class */
1537 if (IS_CLASSREF(cr)) {
1538 c = resolve_classref_eager(cr.ref);
1543 if (!(c->state & CLASS_LOADED))
1544 /* use the methods' classloader */
1545 if (!load_class_from_classloader(c->name,
1546 m->class->classloader))
1549 if (!(c->state & CLASS_LINKED))
1554 /* is the thrown exception an instance of the catch class? */
1556 if (builtin_instanceof(xptr, c)) {
1557 #if !defined(NDEBUG)
1558 /* Print stacktrace of exception when caught. */
1560 if (opt_verboseexception) {
1561 exceptions_print_exception(xptr);
1562 stacktrace_print_trace(xptr);
1566 return ex->handlerpc;
1571 #if defined(ENABLE_THREADS)
1572 /* is this method synchronized? */
1575 /* get synchronization object */
1577 # if defined(__MIPS__) && (SIZEOF_VOID_P == 4)
1578 /* XXX change this if we ever want to use 4-byte stackslots */
1579 o = *((java_objectheader **) (sp + issync - 8));
1581 o = *((java_objectheader **) (sp + issync - SIZEOF_VOID_P));
1586 lock_monitor_exit(o);
1590 /* none of the exceptions catch this one */
1596 /* exceptions_print_exception **************************************************
1598 Prints an exception, the detail message and the cause, if
1599 available, with CACAO internal functions to stdout.
1601 *******************************************************************************/
1603 #if !defined(NDEBUG)
1604 void exceptions_print_exception(java_objectheader *xptr)
1606 java_lang_Throwable *t;
1607 java_lang_Throwable *cause;
1610 t = (java_lang_Throwable *) xptr;
1619 /* print the root exception */
1621 utf_display_printable_ascii_classname(t->header.vftbl->class->name);
1623 if (t->detailMessage) {
1624 u = javastring_toutf(t->detailMessage, false);
1627 utf_display_printable_ascii(u);
1632 /* print the cause if available */
1634 if (cause && (cause != t)) {
1635 printf("Caused by: ");
1636 utf_display_printable_ascii_classname(cause->header.vftbl->class->name);
1638 if (cause->detailMessage) {
1639 u = javastring_toutf(cause->detailMessage, false);
1642 utf_display_printable_ascii(u);
1648 #endif /* !defined(NDEBUG) */
1652 * These are local overrides for various environment variables in Emacs.
1653 * Please do not remove this and leave it at the end of the file, where
1654 * Emacs will automagically detect them.
1655 * ---------------------------------------------------------------------
1658 * indent-tabs-mode: t
1662 * vim:noexpandtab:sw=4:ts=4: