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 5059 2006-06-28 21:51:56Z 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/ClassNotFoundException */
145 if (!(class_java_lang_ClassNotFoundException =
146 load_class_bootstrap(utf_java_lang_ClassNotFoundException)) ||
147 !link_class(class_java_lang_ClassNotFoundException))
150 /* java/lang/IllegalArgumentException */
152 if (!(class_java_lang_IllegalArgumentException =
153 load_class_bootstrap(utf_java_lang_IllegalArgumentException)) ||
154 !link_class(class_java_lang_IllegalArgumentException))
157 /* java/lang/IllegalMonitorStateException */
159 if (!(class_java_lang_IllegalMonitorStateException =
160 load_class_bootstrap(utf_java_lang_IllegalMonitorStateException)) ||
161 !link_class(class_java_lang_IllegalMonitorStateException))
164 /* java/lang/NullPointerException */
166 if (!(class_java_lang_NullPointerException =
167 load_class_bootstrap(utf_java_lang_NullPointerException)) ||
168 !link_class(class_java_lang_NullPointerException))
176 static void throw_exception_exit_intern(bool doexit)
178 java_objectheader *xptr;
182 xptr = *exceptionptr;
185 /* clear exception, because we are calling jit code again */
186 *exceptionptr = NULL;
188 c = xptr->vftbl->class;
190 pss = class_resolveclassmethod(c,
193 class_java_lang_Object,
196 /* print the stacktrace */
199 (void) vm_call_method(pss, xptr);
201 /* This normally means, we are EXTREMLY out of memory or have a */
202 /* serious problem while printStackTrace. But may be another */
203 /* exception, so print it. */
206 java_lang_Throwable *t;
208 t = (java_lang_Throwable *) *exceptionptr;
210 fprintf(stderr, "Exception while printStackTrace(): ");
211 utf_fprint_printable_ascii_classname(stderr, t->header.vftbl->class->name);
213 if (t->detailMessage) {
216 buf = javastring_tochar((java_objectheader *) t->detailMessage);
217 fprintf(stderr, ": %s", buf);
218 MFREE(buf, char, strlen(buf));
221 fprintf(stderr, "\n");
225 utf_fprint_printable_ascii_classname(stderr, c->name);
226 fprintf(stderr, ": printStackTrace()V not found!\n");
239 void throw_exception(void)
241 throw_exception_exit_intern(false);
245 void throw_exception_exit(void)
247 throw_exception_exit_intern(true);
251 void throw_main_exception(void)
253 fprintf(stderr, "Exception in thread \"main\" ");
256 throw_exception_exit_intern(false);
260 void throw_main_exception_exit(void)
262 fprintf(stderr, "Exception in thread \"main\" ");
265 throw_exception_exit_intern(true);
269 void throw_cacao_exception_exit(const char *exception, const char *message, ...)
276 len = strlen(exception);
277 tmp = MNEW(char, len + 1);
278 strncpy(tmp, exception, len);
281 /* convert to classname */
283 for (i = len - 1; i >= 0; i--)
284 if (tmp[i] == '/') tmp[i] = '.';
286 fprintf(stderr, "Exception in thread \"main\" %s", tmp);
288 MFREE(tmp, char, len);
290 if (strlen(message) > 0) {
291 fprintf(stderr, ": ");
293 va_start(ap, message);
294 vfprintf(stderr, message, ap);
298 fprintf(stderr, "\n");
307 /* exceptions_throw_outofmemory_exit *******************************************
309 Just print an: java.lang.InternalError: Out of memory
311 *******************************************************************************/
313 void exceptions_throw_outofmemory_exit(void)
315 throw_cacao_exception_exit(string_java_lang_InternalError,
320 /* new_exception ***************************************************************
322 Creates an exception object with the given name and initalizes it.
325 classname....class name in UTF-8
328 an exception pointer (in any case -- either it is the newly created
329 exception, or an exception thrown while trying to create it).
331 *******************************************************************************/
333 java_objectheader *new_exception(const char *classname)
335 java_objectheader *o;
338 if (!(c = load_class_bootstrap(utf_new_char(classname))))
339 return *exceptionptr;
341 o = native_new_and_init(c);
344 return *exceptionptr;
350 /* new_exception_message *******************************************************
352 Creates an exception object with the given name and initalizes it
353 with the given char message.
356 classname....class name in UTF-8
357 message......message in UTF-8
360 an exception pointer (in any case -- either it is the newly created
361 exception, or an exception thrown while trying to create it).
363 *******************************************************************************/
365 java_objectheader *new_exception_message(const char *classname,
370 s = javastring_new_from_utf_string(message);
372 return *exceptionptr;
374 return new_exception_javastring(classname, s);
378 /* new_exception_throwable *****************************************************
380 Creates an exception object with the given name and initalizes it
381 with the given java/lang/Throwable exception.
384 classname....class name in UTF-8
385 throwable....the given Throwable
388 an exception pointer (in any case -- either it is the newly created
389 exception, or an exception thrown while trying to create it).
391 *******************************************************************************/
393 java_objectheader *new_exception_throwable(const char *classname,
394 java_lang_Throwable *throwable)
396 java_objectheader *o;
399 if (!(c = load_class_bootstrap(utf_new_char(classname))))
400 return *exceptionptr;
402 o = native_new_and_init_throwable(c, throwable);
405 return *exceptionptr;
411 /* new_exception_utfmessage ****************************************************
413 Creates an exception object with the given name and initalizes it
414 with the given utf message.
417 classname....class name in UTF-8
418 message......the message as an utf *
421 an exception pointer (in any case -- either it is the newly created
422 exception, or an exception thrown while trying to create it).
424 *******************************************************************************/
426 java_objectheader *new_exception_utfmessage(const char *classname, utf *message)
430 s = javastring_new(message);
432 return *exceptionptr;
434 return new_exception_javastring(classname, s);
438 /* new_exception_javastring ****************************************************
440 Creates an exception object with the given name and initalizes it
441 with the given java/lang/String message.
444 classname....class name in UTF-8
445 message......the message as a java.lang.String
448 an exception pointer (in any case -- either it is the newly created
449 exception, or an exception thrown while trying to create it).
451 *******************************************************************************/
453 java_objectheader *new_exception_javastring(const char *classname,
454 java_lang_String *message)
456 java_objectheader *o;
459 if (!(c = load_class_bootstrap(utf_new_char(classname))))
460 return *exceptionptr;
462 o = native_new_and_init_string(c, message);
465 return *exceptionptr;
471 /* new_exception_int ***********************************************************
473 Creates an exception object with the given name and initalizes it
474 with the given int value.
477 classname....class name in UTF-8
478 i............the integer
481 an exception pointer (in any case -- either it is the newly created
482 exception, or an exception thrown while trying to create it).
484 *******************************************************************************/
486 java_objectheader *new_exception_int(const char *classname, s4 i)
488 java_objectheader *o;
491 if (!(c = load_class_bootstrap(utf_new_char(classname))))
492 return *exceptionptr;
494 o = native_new_and_init_int(c, i);
497 return *exceptionptr;
503 /* exceptions_new_abstractmethoderror ******************************************
505 Generates a java.lang.AbstractMethodError for the VM.
507 *******************************************************************************/
509 java_objectheader *exceptions_new_abstractmethoderror(void)
511 java_objectheader *e;
513 e = native_new_and_init(class_java_lang_AbstractMethodError);
516 return *exceptionptr;
522 /* exceptions_asm_new_abstractmethoderror **************************************
524 Generates a java.lang.AbstractMethodError for
525 asm_abstractmethoderror.
527 *******************************************************************************/
529 java_objectheader *exceptions_asm_new_abstractmethoderror(u1 *sp, u1 *ra)
532 java_objectheader *e;
534 /* create the stackframeinfo (XPC is equal to RA) */
536 stacktrace_create_extern_stackframeinfo(&sfi, NULL, sp, ra, ra);
538 /* create the exception */
540 e = exceptions_new_abstractmethoderror();
542 /* remove the stackframeinfo */
544 stacktrace_remove_stackframeinfo(&sfi);
550 /* exceptions_throw_abstractmethoderror ****************************************
552 Generates a java.lang.AbstractMethodError for the VM and throws it.
554 *******************************************************************************/
556 void exceptions_throw_abstractmethoderror(void)
558 *exceptionptr = exceptions_new_abstractmethoderror();
562 /* new_classformaterror ********************************************************
564 generates a java.lang.ClassFormatError for the classloader
567 c............the class in which the error was found
568 message......UTF-8 format string
571 an exception pointer (in any case -- either it is the newly created
572 exception, or an exception thrown while trying to create it).
574 *******************************************************************************/
576 java_objectheader *new_classformaterror(classinfo *c, const char *message, ...)
578 java_objectheader *o;
583 /* calculate message length */
588 msglen += utf_bytes(c->name) + strlen(" (");
590 va_start(ap, message);
591 msglen += get_variable_message_length(message, ap);
595 msglen += strlen(")");
597 msglen += strlen("0");
599 /* allocate a buffer */
601 msg = MNEW(char, msglen);
603 /* print message into allocated buffer */
606 utf_copy_classname(msg, c->name);
610 va_start(ap, message);
611 vsprintf(msg + strlen(msg), message, ap);
617 o = new_exception_message(string_java_lang_ClassFormatError, msg);
619 MFREE(msg, char, msglen);
625 /* exceptions_throw_classformaterror *******************************************
627 Generate a java.lang.ClassFormatError for the VM system and throw it.
630 c............the class in which the error was found
631 message......UTF-8 format string
634 an exception pointer (in any case -- either it is the newly created
635 exception, or an exception thrown while trying to create it).
637 *******************************************************************************/
639 void exceptions_throw_classformaterror(classinfo *c, const char *message, ...)
643 va_start(ap, message);
644 *exceptionptr = new_classformaterror(c, message, ap);
649 /* new_classnotfoundexception **************************************************
651 Generates a java.lang.ClassNotFoundException for the classloader.
654 name.........name of the class not found as a utf *
657 an exception pointer (in any case -- either it is the newly created
658 exception, or an exception thrown while trying to create it).
660 *******************************************************************************/
662 java_objectheader *new_classnotfoundexception(utf *name)
664 java_objectheader *o;
667 s = javastring_new(name);
669 return *exceptionptr;
671 o = native_new_and_init_string(class_java_lang_ClassNotFoundException, s);
674 return *exceptionptr;
680 /* new_noclassdeffounderror ****************************************************
682 Generates a java.lang.NoClassDefFoundError
685 name.........name of the class not found as a utf *
688 an exception pointer (in any case -- either it is the newly created
689 exception, or an exception thrown while trying to create it).
691 *******************************************************************************/
693 java_objectheader *new_noclassdeffounderror(utf *name)
695 java_objectheader *o;
698 s = javastring_new(name);
700 return *exceptionptr;
702 o = native_new_and_init_string(class_java_lang_NoClassDefFoundError, s);
705 return *exceptionptr;
711 /* classnotfoundexception_to_noclassdeffounderror ******************************
713 Check the *exceptionptr for a ClassNotFoundException. If it is one,
714 convert it to a NoClassDefFoundError.
716 *******************************************************************************/
718 void classnotfoundexception_to_noclassdeffounderror(void)
720 java_objectheader *xptr;
721 java_objectheader *cause;
725 cause = *exceptionptr;
727 /* convert ClassNotFoundException's to NoClassDefFoundError's */
729 if (builtin_instanceof(cause, class_java_lang_ClassNotFoundException)) {
730 /* clear exception, because we are calling jit code again */
732 *exceptionptr = NULL;
734 /* create new error */
737 new_exception_javastring(string_java_lang_NoClassDefFoundError,
738 ((java_lang_Throwable *) cause)->detailMessage);
740 /* we had an exception while creating the error */
745 /* set new exception */
747 *exceptionptr = xptr;
752 /* new_internalerror ***********************************************************
754 Generates a java.lang.InternalError for the VM.
757 message......UTF-8 message format string
760 an exception pointer (in any case -- either it is the newly created
761 exception, or an exception thrown while trying to create it).
763 *******************************************************************************/
765 java_objectheader *new_internalerror(const char *message, ...)
767 java_objectheader *o;
772 /* calculate exception message length */
774 va_start(ap, message);
775 msglen = get_variable_message_length(message, ap);
778 /* allocate memory */
780 msg = MNEW(char, msglen);
782 /* generate message */
784 va_start(ap, message);
785 vsprintf(msg, message, ap);
788 /* create exception object */
790 o = new_exception_message(string_java_lang_InternalError, msg);
794 MFREE(msg, char, msglen);
800 /* exceptions_new_linkageerror *************************************************
802 Generates a java.lang.LinkageError with an error message.
805 message......UTF-8 message
806 c............class related to the error. If this is != NULL
807 the name of c is appended to the error message.
810 an exception pointer (in any case -- either it is the newly created
811 exception, or an exception thrown while trying to create it).
813 *******************************************************************************/
815 java_objectheader *exceptions_new_linkageerror(const char *message,
818 java_objectheader *o;
822 /* calculate exception message length */
824 msglen = strlen(message) + 1;
826 msglen += utf_bytes(c->name);
829 /* allocate memory */
831 msg = MNEW(char, msglen);
833 /* generate message */
837 utf_cat_classname(msg, c->name);
840 o = native_new_and_init_string(class_java_lang_LinkageError,
841 javastring_new_from_utf_string(msg));
845 MFREE(msg, char, msglen);
848 return *exceptionptr;
854 /* exceptions_new_nosuchmethoderror ********************************************
856 Generates a java.lang.NoSuchMethodError with an error message.
859 c............class in which the method was not found
860 name.........name of the method
861 desc.........descriptor of the method
864 an exception pointer (in any case -- either it is the newly created
865 exception, or an exception thrown while trying to create it).
867 *******************************************************************************/
869 java_objectheader *exceptions_new_nosuchmethoderror(classinfo *c,
870 utf *name, utf *desc)
872 java_objectheader *o;
876 /* calculate exception message length */
878 msglen = utf_bytes(c->name) + strlen(".") + utf_bytes(name) +
879 utf_bytes(desc) + strlen("0");
881 /* allocate memory */
883 msg = MNEW(char, msglen);
885 /* generate message */
887 utf_copy_classname(msg, c->name);
892 o = native_new_and_init_string(class_java_lang_NoSuchMethodError,
893 javastring_new_from_utf_string(msg));
897 MFREE(msg, char, msglen);
900 return *exceptionptr;
906 /* exceptions_throw_nosuchmethoderror ******************************************
908 Generates a java.lang.NoSuchMethodError with an error message.
911 c............class in which the method was not found
912 name.........name of the method
913 desc.........descriptor of the method
915 *******************************************************************************/
917 void exceptions_throw_nosuchmethoderror(classinfo *c, utf *name, utf *desc)
919 *exceptionptr = exceptions_new_nosuchmethoderror(c, name, desc);
923 /* new_unsupportedclassversionerror ********************************************
925 Generate a java.lang.UnsupportedClassVersionError for the classloader
928 c............class in which the method was not found
929 message......UTF-8 format string
932 an exception pointer (in any case -- either it is the newly created
933 exception, or an exception thrown while trying to create it).
935 *******************************************************************************/
937 java_objectheader *new_unsupportedclassversionerror(classinfo *c, const char *message, ...)
939 java_objectheader *o;
944 /* calculate exception message length */
946 msglen = utf_bytes(c->name) + strlen(" (") + strlen(")") + strlen("0");
948 va_start(ap, message);
949 msglen += get_variable_message_length(message, ap);
952 /* allocate memory */
954 msg = MNEW(char, msglen);
956 /* generate message */
958 utf_copy_classname(msg, c->name);
961 va_start(ap, message);
962 vsprintf(msg + strlen(msg), message, ap);
967 /* create exception object */
969 o = new_exception_message(string_java_lang_UnsupportedClassVersionError,
974 MFREE(msg, char, msglen);
980 /* new_verifyerror *************************************************************
982 Generates a java.lang.VerifyError for the JIT compiler.
985 m............method in which the error was found
986 message......UTF-8 format string
989 an exception pointer (in any case -- either it is the newly created
990 exception, or an exception thrown while trying to create it).
992 *******************************************************************************/
994 java_objectheader *new_verifyerror(methodinfo *m, const char *message, ...)
996 java_objectheader *o;
1001 useinlining = false; /* at least until sure inlining works with exceptions*/
1003 /* calculate exception message length */
1008 msglen = strlen("(class: ") + utf_bytes(m->class->name) +
1009 strlen(", method: ") + utf_bytes(m->name) +
1010 strlen(" signature: ") + utf_bytes(m->descriptor) +
1011 strlen(") ") + strlen("0");
1013 va_start(ap, message);
1014 msglen += get_variable_message_length(message, ap);
1017 /* allocate memory */
1019 msg = MNEW(char, msglen);
1021 /* generate message */
1024 strcpy(msg, "(class: ");
1025 utf_cat_classname(msg, m->class->name);
1026 strcat(msg, ", method: ");
1027 utf_cat(msg, m->name);
1028 strcat(msg, " signature: ");
1029 utf_cat(msg, m->descriptor);
1033 va_start(ap, message);
1034 vsprintf(msg + strlen(msg), message, ap);
1037 /* create exception object */
1039 o = new_exception_message(string_java_lang_VerifyError, msg);
1043 MFREE(msg, char, msglen);
1049 /* exceptions_throw_verifyerror_for_stack **************************************
1051 throws a java.lang.VerifyError for an invalid stack slot type
1054 m............method in which the error was found
1055 type.........the expected type
1058 an exception pointer (in any case -- either it is the newly created
1059 exception, or an exception thrown while trying to create it).
1061 *******************************************************************************/
1063 void exceptions_throw_verifyerror_for_stack(methodinfo *m,int type)
1065 java_objectheader *o;
1070 /* calculate exception message length */
1075 msglen = strlen("(class: ") + utf_bytes(m->class->name) +
1076 strlen(", method: ") + utf_bytes(m->name) +
1077 strlen(" signature: ") + utf_bytes(m->descriptor) +
1078 strlen(") Expecting to find longest-------typename on stack")
1081 /* allocate memory */
1083 msg = MNEW(char, msglen);
1085 /* generate message */
1088 strcpy(msg, "(class: ");
1089 utf_cat_classname(msg, m->class->name);
1090 strcat(msg, ", method: ");
1091 utf_cat(msg, m->name);
1092 strcat(msg, " signature: ");
1093 utf_cat(msg, m->descriptor);
1100 strcat(msg,"Expecting to find ");
1102 case TYPE_INT: typename = "integer"; break;
1103 case TYPE_LNG: typename = "long"; break;
1104 case TYPE_FLT: typename = "float"; break;
1105 case TYPE_DBL: typename = "double"; break;
1106 case TYPE_ADR: typename = "object/array"; break;
1107 default: typename = "<INVALID>"; assert(0); break;
1109 strcat(msg, typename);
1110 strcat(msg, " on stack");
1112 /* create exception object */
1114 o = new_exception_message(string_java_lang_VerifyError, msg);
1118 MFREE(msg, char, msglen);
1124 /* new_arithmeticexception *****************************************************
1126 Generates a java.lang.ArithmeticException for the jit compiler.
1128 *******************************************************************************/
1130 java_objectheader *new_arithmeticexception(void)
1132 java_objectheader *e;
1134 e = new_exception_message(string_java_lang_ArithmeticException,
1135 string_java_lang_ArithmeticException_message);
1138 return *exceptionptr;
1144 /* exceptions_new_arrayindexoutofboundsexception *******************************
1146 Generates a java.lang.ArrayIndexOutOfBoundsException for the VM
1149 *******************************************************************************/
1151 java_objectheader *new_arrayindexoutofboundsexception(s4 index)
1153 java_objectheader *e;
1155 java_objectheader *o;
1156 java_lang_String *s;
1158 /* convert the index into a String, like Sun does */
1160 m = class_resolveclassmethod(class_java_lang_String,
1161 utf_new_char("valueOf"),
1162 utf_new_char("(I)Ljava/lang/String;"),
1163 class_java_lang_Object,
1167 return *exceptionptr;
1169 o = vm_call_method(m, NULL, index);
1171 s = (java_lang_String *) o;
1174 return *exceptionptr;
1176 e = new_exception_javastring(string_java_lang_ArrayIndexOutOfBoundsException,
1180 return *exceptionptr;
1186 /* exceptions_throw_arrayindexoutofboundsexception *****************************
1188 Generates a java.lang.ArrayIndexOutOfBoundsException for the VM
1191 *******************************************************************************/
1193 void exceptions_throw_arrayindexoutofboundsexception(void)
1195 java_objectheader *e;
1197 e = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
1206 /* new_arraystoreexception *****************************************************
1208 generates a java.lang.ArrayStoreException for the jit compiler
1210 *******************************************************************************/
1212 java_objectheader *new_arraystoreexception(void)
1214 java_objectheader *e;
1216 e = new_exception(string_java_lang_ArrayStoreException);
1217 /* e = native_new_and_init(class_java_lang_ArrayStoreException); */
1220 return *exceptionptr;
1226 /* new_classcastexception ******************************************************
1228 generates a java.lang.ClassCastException for the jit compiler
1230 *******************************************************************************/
1232 java_objectheader *new_classcastexception(void)
1234 java_objectheader *e;
1236 e = new_exception(string_java_lang_ClassCastException);
1239 return *exceptionptr;
1245 /* exceptions_new_illegalargumentexception *************************************
1247 Generates a java.lang.IllegalArgumentException for the VM system.
1249 *******************************************************************************/
1251 java_objectheader *new_illegalargumentexception(void)
1253 java_objectheader *e;
1255 e = native_new_and_init(class_java_lang_IllegalArgumentException);
1258 return *exceptionptr;
1264 /* exceptions_throw_illegalargumentexception ***********************************
1266 Generates a java.lang.IllegalArgumentException for the VM system
1267 and throw it in the VM system.
1269 *******************************************************************************/
1271 void exceptions_throw_illegalargumentexception(void)
1273 *exceptionptr = new_illegalargumentexception();
1277 /* new_illegalmonitorstateexception ********************************************
1279 Generates a java.lang.IllegalMonitorStateException for the VM
1282 *******************************************************************************/
1284 java_objectheader *new_illegalmonitorstateexception(void)
1286 java_objectheader *e;
1288 e = native_new_and_init(class_java_lang_IllegalMonitorStateException);
1291 return *exceptionptr;
1297 /* exceptions_new_negativearraysizeexception ***********************************
1299 Generates a java.lang.NegativeArraySizeException for the VM system.
1301 *******************************************************************************/
1303 java_objectheader *new_negativearraysizeexception(void)
1305 java_objectheader *e;
1307 e = new_exception(string_java_lang_NegativeArraySizeException);
1310 return *exceptionptr;
1316 /* exceptions_throw_negativearraysizeexception *********************************
1318 Generates a java.lang.NegativeArraySizeException for the VM system.
1320 *******************************************************************************/
1322 void exceptions_throw_negativearraysizeexception(void)
1324 *exceptionptr = new_negativearraysizeexception();
1328 /* new_nullpointerexception ****************************************************
1330 generates a java.lang.NullPointerException for the jit compiler
1332 *******************************************************************************/
1334 java_objectheader *new_nullpointerexception(void)
1336 java_objectheader *e;
1338 e = native_new_and_init(class_java_lang_NullPointerException);
1341 return *exceptionptr;
1347 /* exceptions_throw_nullpointerexception ***************************************
1349 Generates a java.lang.NullPointerException for the VM system and
1350 throw it in the VM system.
1352 *******************************************************************************/
1354 void exceptions_throw_nullpointerexception(void)
1356 *exceptionptr = new_nullpointerexception();
1360 /* exceptions_new_stringindexoutofboundsexception ******************************
1362 Generates a java.lang.StringIndexOutOfBoundsException for the VM
1365 *******************************************************************************/
1367 java_objectheader *exceptions_new_stringindexoutofboundsexception(void)
1369 java_objectheader *e;
1371 e = new_exception(string_java_lang_StringIndexOutOfBoundsException);
1374 return *exceptionptr;
1380 /* exceptions_throw_stringindexoutofboundsexception ****************************
1382 Throws a java.lang.StringIndexOutOfBoundsException for the VM
1385 *******************************************************************************/
1387 void exceptions_throw_stringindexoutofboundsexception(void)
1389 *exceptionptr = exceptions_new_stringindexoutofboundsexception();
1393 /* exceptions_handle_exception *************************************************
1395 Try to find an exception handler for the given exception and return it.
1396 If no handler is found, exit the monitor of the method (if any)
1400 xptr.........the exception object
1401 xpc..........PC of where the exception was thrown
1402 pv...........Procedure Value of the current method
1403 sp...........current stack pointer
1406 the address of the first matching exception handler, or
1407 NULL if no handler was found
1409 *******************************************************************************/
1411 u1 *exceptions_handle_exception(java_objectheader *xptr, u1 *xpc, u1 *pv, u1 *sp)
1418 s4 exceptiontablelength;
1420 classref_or_classinfo cr;
1422 #if defined(ENABLE_THREADS)
1423 java_objectheader *o;
1426 /* get info from the method header */
1428 code = *((codeinfo **) (pv + CodeinfoPointer));
1429 framesize = *((s4 *) (pv + FrameSize));
1430 issync = *((s4 *) (pv + IsSync));
1431 ex = (exceptionentry *) (pv + ExTableStart);
1432 exceptiontablelength = *((s4 *) (pv + ExTableSize));
1434 /* Get the methodinfo pointer from the codeinfo pointer. For
1435 asm_vm_call_method the codeinfo pointer is NULL. */
1437 m = (code == NULL) ? NULL : code->m;
1439 #if !defined(NDEBUG)
1440 /* print exception trace */
1442 if (opt_verbose || opt_verbosecall || opt_verboseexception)
1443 builtin_trace_exception(xptr, m, xpc, 1);
1446 for (i = 0; i < exceptiontablelength; i++) {
1447 /* ATTENTION: keep this here, as we need to decrement the
1448 pointer before the loop executes! */
1452 /* If the start and end PC is NULL, this means we have the
1453 special case of asm_vm_call_method. So, just return the
1454 proper exception handler. */
1456 if ((ex->startpc == NULL) && (ex->endpc == NULL))
1457 return (u1 *) (ptrint) &asm_vm_call_method_exception_handler;
1459 /* is the xpc is the current catch range */
1461 if ((ex->startpc <= xpc) && (xpc < ex->endpc)) {
1464 /* NULL catches everything */
1466 if (cr.any == NULL) {
1467 #if !defined(NDEBUG)
1468 /* Print stacktrace of exception when caught. */
1470 if (opt_verboseexception) {
1471 exceptions_print_exception(xptr);
1472 stacktrace_print_trace(xptr);
1476 return ex->handlerpc;
1479 /* resolve or load/link the exception class */
1481 if (IS_CLASSREF(cr)) {
1482 c = resolve_classref_eager(cr.ref);
1487 if (!(c->state & CLASS_LOADED))
1488 /* use the methods' classloader */
1489 if (!load_class_from_classloader(c->name,
1490 m->class->classloader))
1493 if (!(c->state & CLASS_LINKED))
1498 /* is the thrown exception an instance of the catch class? */
1500 if (builtin_instanceof(xptr, c)) {
1501 #if !defined(NDEBUG)
1502 /* Print stacktrace of exception when caught. */
1504 if (opt_verboseexception) {
1505 exceptions_print_exception(xptr);
1506 stacktrace_print_trace(xptr);
1510 return ex->handlerpc;
1515 #if defined(ENABLE_THREADS)
1516 /* is this method synchronized? */
1519 /* get synchronization object */
1521 # if defined(__MIPS__) && (SIZEOF_VOID_P == 4)
1522 /* XXX change this if we ever want to use 4-byte stackslots */
1523 o = *((java_objectheader **) (sp + issync - 8));
1525 o = *((java_objectheader **) (sp + issync - SIZEOF_VOID_P));
1530 builtin_monitorexit(o);
1534 /* none of the exceptions catch this one */
1540 /* exceptions_print_exception **************************************************
1542 Prints an exception, the detail message and the cause, if
1543 available, with CACAO internal functions to stdout.
1545 *******************************************************************************/
1547 #if !defined(NDEBUG)
1548 void exceptions_print_exception(java_objectheader *xptr)
1550 java_lang_Throwable *t;
1551 java_lang_Throwable *cause;
1554 t = (java_lang_Throwable *) xptr;
1563 /* print the root exception */
1565 utf_display_printable_ascii_classname(t->header.vftbl->class->name);
1567 if (t->detailMessage) {
1568 u = javastring_toutf(t->detailMessage, false);
1571 utf_display_printable_ascii(u);
1576 /* print the cause if available */
1578 if (cause && (cause != t)) {
1579 printf("Caused by: ");
1580 utf_display_printable_ascii_classname(cause->header.vftbl->class->name);
1582 if (cause->detailMessage) {
1583 u = javastring_toutf(cause->detailMessage, false);
1586 utf_display_printable_ascii(u);
1592 #endif /* !defined(NDEBUG) */
1596 * These are local overrides for various environment variables in Emacs.
1597 * Please do not remove this and leave it at the end of the file, where
1598 * Emacs will automagically detect them.
1599 * ---------------------------------------------------------------------
1602 * indent-tabs-mode: t
1606 * vim:noexpandtab:sw=4:ts=4: