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 5053 2006-06-28 19:11:20Z 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_throw_abstractmethoderror ****************************************
524 Generates a java.lang.AbstractMethodError for the VM and throws it.
526 *******************************************************************************/
528 void exceptions_throw_abstractmethoderror(void)
530 *exceptionptr = exceptions_new_abstractmethoderror();
534 /* new_classformaterror ********************************************************
536 generates a java.lang.ClassFormatError for the classloader
539 c............the class in which the error was found
540 message......UTF-8 format string
543 an exception pointer (in any case -- either it is the newly created
544 exception, or an exception thrown while trying to create it).
546 *******************************************************************************/
548 java_objectheader *new_classformaterror(classinfo *c, const char *message, ...)
550 java_objectheader *o;
555 /* calculate message length */
560 msglen += utf_bytes(c->name) + strlen(" (");
562 va_start(ap, message);
563 msglen += get_variable_message_length(message, ap);
567 msglen += strlen(")");
569 msglen += strlen("0");
571 /* allocate a buffer */
573 msg = MNEW(char, msglen);
575 /* print message into allocated buffer */
578 utf_copy_classname(msg, c->name);
582 va_start(ap, message);
583 vsprintf(msg + strlen(msg), message, ap);
589 o = new_exception_message(string_java_lang_ClassFormatError, msg);
591 MFREE(msg, char, msglen);
597 /* exceptions_throw_classformaterror *******************************************
599 Generate a java.lang.ClassFormatError for the VM system and throw it.
602 c............the class in which the error was found
603 message......UTF-8 format string
606 an exception pointer (in any case -- either it is the newly created
607 exception, or an exception thrown while trying to create it).
609 *******************************************************************************/
611 void exceptions_throw_classformaterror(classinfo *c, const char *message, ...)
615 va_start(ap, message);
616 *exceptionptr = new_classformaterror(c, message, ap);
621 /* new_classnotfoundexception **************************************************
623 Generates a java.lang.ClassNotFoundException for the classloader.
626 name.........name of the class not found as a utf *
629 an exception pointer (in any case -- either it is the newly created
630 exception, or an exception thrown while trying to create it).
632 *******************************************************************************/
634 java_objectheader *new_classnotfoundexception(utf *name)
636 java_objectheader *o;
639 s = javastring_new(name);
641 return *exceptionptr;
643 o = native_new_and_init_string(class_java_lang_ClassNotFoundException, s);
646 return *exceptionptr;
652 /* new_noclassdeffounderror ****************************************************
654 Generates a java.lang.NoClassDefFoundError
657 name.........name of the class not found as a utf *
660 an exception pointer (in any case -- either it is the newly created
661 exception, or an exception thrown while trying to create it).
663 *******************************************************************************/
665 java_objectheader *new_noclassdeffounderror(utf *name)
667 java_objectheader *o;
670 s = javastring_new(name);
672 return *exceptionptr;
674 o = native_new_and_init_string(class_java_lang_NoClassDefFoundError, s);
677 return *exceptionptr;
683 /* classnotfoundexception_to_noclassdeffounderror ******************************
685 Check the *exceptionptr for a ClassNotFoundException. If it is one,
686 convert it to a NoClassDefFoundError.
688 *******************************************************************************/
690 void classnotfoundexception_to_noclassdeffounderror(void)
692 java_objectheader *xptr;
693 java_objectheader *cause;
697 cause = *exceptionptr;
699 /* convert ClassNotFoundException's to NoClassDefFoundError's */
701 if (builtin_instanceof(cause, class_java_lang_ClassNotFoundException)) {
702 /* clear exception, because we are calling jit code again */
704 *exceptionptr = NULL;
706 /* create new error */
709 new_exception_javastring(string_java_lang_NoClassDefFoundError,
710 ((java_lang_Throwable *) cause)->detailMessage);
712 /* we had an exception while creating the error */
717 /* set new exception */
719 *exceptionptr = xptr;
724 /* new_internalerror ***********************************************************
726 Generates a java.lang.InternalError for the VM.
729 message......UTF-8 message format string
732 an exception pointer (in any case -- either it is the newly created
733 exception, or an exception thrown while trying to create it).
735 *******************************************************************************/
737 java_objectheader *new_internalerror(const char *message, ...)
739 java_objectheader *o;
744 /* calculate exception message length */
746 va_start(ap, message);
747 msglen = get_variable_message_length(message, ap);
750 /* allocate memory */
752 msg = MNEW(char, msglen);
754 /* generate message */
756 va_start(ap, message);
757 vsprintf(msg, message, ap);
760 /* create exception object */
762 o = new_exception_message(string_java_lang_InternalError, msg);
766 MFREE(msg, char, msglen);
772 /* exceptions_new_linkageerror *************************************************
774 Generates a java.lang.LinkageError with an error message.
777 message......UTF-8 message
778 c............class related to the error. If this is != NULL
779 the name of c is appended to the error message.
782 an exception pointer (in any case -- either it is the newly created
783 exception, or an exception thrown while trying to create it).
785 *******************************************************************************/
787 java_objectheader *exceptions_new_linkageerror(const char *message,
790 java_objectheader *o;
794 /* calculate exception message length */
796 msglen = strlen(message) + 1;
798 msglen += utf_bytes(c->name);
801 /* allocate memory */
803 msg = MNEW(char, msglen);
805 /* generate message */
809 utf_cat_classname(msg, c->name);
812 o = native_new_and_init_string(class_java_lang_LinkageError,
813 javastring_new_from_utf_string(msg));
817 MFREE(msg, char, msglen);
820 return *exceptionptr;
826 /* exceptions_new_nosuchmethoderror ********************************************
828 Generates a java.lang.NoSuchMethodError with an error message.
831 c............class in which the method was not found
832 name.........name of the method
833 desc.........descriptor of the method
836 an exception pointer (in any case -- either it is the newly created
837 exception, or an exception thrown while trying to create it).
839 *******************************************************************************/
841 java_objectheader *exceptions_new_nosuchmethoderror(classinfo *c,
842 utf *name, utf *desc)
844 java_objectheader *o;
848 /* calculate exception message length */
850 msglen = utf_bytes(c->name) + strlen(".") + utf_bytes(name) +
851 utf_bytes(desc) + strlen("0");
853 /* allocate memory */
855 msg = MNEW(char, msglen);
857 /* generate message */
859 utf_copy_classname(msg, c->name);
864 o = native_new_and_init_string(class_java_lang_NoSuchMethodError,
865 javastring_new_from_utf_string(msg));
869 MFREE(msg, char, msglen);
872 return *exceptionptr;
878 /* exceptions_throw_nosuchmethoderror ******************************************
880 Generates a java.lang.NoSuchMethodError with an error message.
883 c............class in which the method was not found
884 name.........name of the method
885 desc.........descriptor of the method
887 *******************************************************************************/
889 void exceptions_throw_nosuchmethoderror(classinfo *c, utf *name, utf *desc)
891 *exceptionptr = exceptions_new_nosuchmethoderror(c, name, desc);
895 /* new_unsupportedclassversionerror ********************************************
897 Generate a java.lang.UnsupportedClassVersionError for the classloader
900 c............class in which the method was not found
901 message......UTF-8 format string
904 an exception pointer (in any case -- either it is the newly created
905 exception, or an exception thrown while trying to create it).
907 *******************************************************************************/
909 java_objectheader *new_unsupportedclassversionerror(classinfo *c, const char *message, ...)
911 java_objectheader *o;
916 /* calculate exception message length */
918 msglen = utf_bytes(c->name) + strlen(" (") + strlen(")") + strlen("0");
920 va_start(ap, message);
921 msglen += get_variable_message_length(message, ap);
924 /* allocate memory */
926 msg = MNEW(char, msglen);
928 /* generate message */
930 utf_copy_classname(msg, c->name);
933 va_start(ap, message);
934 vsprintf(msg + strlen(msg), message, ap);
939 /* create exception object */
941 o = new_exception_message(string_java_lang_UnsupportedClassVersionError,
946 MFREE(msg, char, msglen);
952 /* new_verifyerror *************************************************************
954 Generates a java.lang.VerifyError for the JIT compiler.
957 m............method in which the error was found
958 message......UTF-8 format string
961 an exception pointer (in any case -- either it is the newly created
962 exception, or an exception thrown while trying to create it).
964 *******************************************************************************/
966 java_objectheader *new_verifyerror(methodinfo *m, const char *message, ...)
968 java_objectheader *o;
973 useinlining = false; /* at least until sure inlining works with exceptions*/
975 /* calculate exception message length */
980 msglen = strlen("(class: ") + utf_bytes(m->class->name) +
981 strlen(", method: ") + utf_bytes(m->name) +
982 strlen(" signature: ") + utf_bytes(m->descriptor) +
983 strlen(") ") + strlen("0");
985 va_start(ap, message);
986 msglen += get_variable_message_length(message, ap);
989 /* allocate memory */
991 msg = MNEW(char, msglen);
993 /* generate message */
996 strcpy(msg, "(class: ");
997 utf_cat_classname(msg, m->class->name);
998 strcat(msg, ", method: ");
999 utf_cat(msg, m->name);
1000 strcat(msg, " signature: ");
1001 utf_cat(msg, m->descriptor);
1005 va_start(ap, message);
1006 vsprintf(msg + strlen(msg), message, ap);
1009 /* create exception object */
1011 o = new_exception_message(string_java_lang_VerifyError, msg);
1015 MFREE(msg, char, msglen);
1021 /* exceptions_throw_verifyerror_for_stack **************************************
1023 throws a java.lang.VerifyError for an invalid stack slot type
1026 m............method in which the error was found
1027 type.........the expected type
1030 an exception pointer (in any case -- either it is the newly created
1031 exception, or an exception thrown while trying to create it).
1033 *******************************************************************************/
1035 void exceptions_throw_verifyerror_for_stack(methodinfo *m,int type)
1037 java_objectheader *o;
1042 /* calculate exception message length */
1047 msglen = strlen("(class: ") + utf_bytes(m->class->name) +
1048 strlen(", method: ") + utf_bytes(m->name) +
1049 strlen(" signature: ") + utf_bytes(m->descriptor) +
1050 strlen(") Expecting to find longest-------typename on stack")
1053 /* allocate memory */
1055 msg = MNEW(char, msglen);
1057 /* generate message */
1060 strcpy(msg, "(class: ");
1061 utf_cat_classname(msg, m->class->name);
1062 strcat(msg, ", method: ");
1063 utf_cat(msg, m->name);
1064 strcat(msg, " signature: ");
1065 utf_cat(msg, m->descriptor);
1072 strcat(msg,"Expecting to find ");
1074 case TYPE_INT: typename = "integer"; break;
1075 case TYPE_LNG: typename = "long"; break;
1076 case TYPE_FLT: typename = "float"; break;
1077 case TYPE_DBL: typename = "double"; break;
1078 case TYPE_ADR: typename = "object/array"; break;
1079 default: typename = "<INVALID>"; assert(0); break;
1081 strcat(msg, typename);
1082 strcat(msg, " on stack");
1084 /* create exception object */
1086 o = new_exception_message(string_java_lang_VerifyError, msg);
1090 MFREE(msg, char, msglen);
1096 /* new_arithmeticexception *****************************************************
1098 Generates a java.lang.ArithmeticException for the jit compiler.
1100 *******************************************************************************/
1102 java_objectheader *new_arithmeticexception(void)
1104 java_objectheader *e;
1106 e = new_exception_message(string_java_lang_ArithmeticException,
1107 string_java_lang_ArithmeticException_message);
1110 return *exceptionptr;
1116 /* exceptions_new_arrayindexoutofboundsexception *******************************
1118 Generates a java.lang.ArrayIndexOutOfBoundsException for the VM
1121 *******************************************************************************/
1123 java_objectheader *new_arrayindexoutofboundsexception(s4 index)
1125 java_objectheader *e;
1127 java_objectheader *o;
1128 java_lang_String *s;
1130 /* convert the index into a String, like Sun does */
1132 m = class_resolveclassmethod(class_java_lang_String,
1133 utf_new_char("valueOf"),
1134 utf_new_char("(I)Ljava/lang/String;"),
1135 class_java_lang_Object,
1139 return *exceptionptr;
1141 o = vm_call_method(m, NULL, index);
1143 s = (java_lang_String *) o;
1146 return *exceptionptr;
1148 e = new_exception_javastring(string_java_lang_ArrayIndexOutOfBoundsException,
1152 return *exceptionptr;
1158 /* exceptions_throw_arrayindexoutofboundsexception *****************************
1160 Generates a java.lang.ArrayIndexOutOfBoundsException for the VM
1163 *******************************************************************************/
1165 void exceptions_throw_arrayindexoutofboundsexception(void)
1167 java_objectheader *e;
1169 e = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
1178 /* new_arraystoreexception *****************************************************
1180 generates a java.lang.ArrayStoreException for the jit compiler
1182 *******************************************************************************/
1184 java_objectheader *new_arraystoreexception(void)
1186 java_objectheader *e;
1188 e = new_exception(string_java_lang_ArrayStoreException);
1189 /* e = native_new_and_init(class_java_lang_ArrayStoreException); */
1192 return *exceptionptr;
1198 /* new_classcastexception ******************************************************
1200 generates a java.lang.ClassCastException for the jit compiler
1202 *******************************************************************************/
1204 java_objectheader *new_classcastexception(void)
1206 java_objectheader *e;
1208 e = new_exception(string_java_lang_ClassCastException);
1211 return *exceptionptr;
1217 /* exceptions_new_illegalargumentexception *************************************
1219 Generates a java.lang.IllegalArgumentException for the VM system.
1221 *******************************************************************************/
1223 java_objectheader *new_illegalargumentexception(void)
1225 java_objectheader *e;
1227 e = native_new_and_init(class_java_lang_IllegalArgumentException);
1230 return *exceptionptr;
1236 /* exceptions_throw_illegalargumentexception ***********************************
1238 Generates a java.lang.IllegalArgumentException for the VM system
1239 and throw it in the VM system.
1241 *******************************************************************************/
1243 void exceptions_throw_illegalargumentexception(void)
1245 *exceptionptr = new_illegalargumentexception();
1249 /* new_illegalmonitorstateexception ********************************************
1251 Generates a java.lang.IllegalMonitorStateException for the VM
1254 *******************************************************************************/
1256 java_objectheader *new_illegalmonitorstateexception(void)
1258 java_objectheader *e;
1260 e = native_new_and_init(class_java_lang_IllegalMonitorStateException);
1263 return *exceptionptr;
1269 /* exceptions_new_negativearraysizeexception ***********************************
1271 Generates a java.lang.NegativeArraySizeException for the VM system.
1273 *******************************************************************************/
1275 java_objectheader *new_negativearraysizeexception(void)
1277 java_objectheader *e;
1279 e = new_exception(string_java_lang_NegativeArraySizeException);
1282 return *exceptionptr;
1288 /* exceptions_throw_negativearraysizeexception *********************************
1290 Generates a java.lang.NegativeArraySizeException for the VM system.
1292 *******************************************************************************/
1294 void exceptions_throw_negativearraysizeexception(void)
1296 *exceptionptr = new_negativearraysizeexception();
1300 /* new_nullpointerexception ****************************************************
1302 generates a java.lang.NullPointerException for the jit compiler
1304 *******************************************************************************/
1306 java_objectheader *new_nullpointerexception(void)
1308 java_objectheader *e;
1310 e = native_new_and_init(class_java_lang_NullPointerException);
1313 return *exceptionptr;
1319 /* exceptions_throw_nullpointerexception ***************************************
1321 Generates a java.lang.NullPointerException for the VM system and
1322 throw it in the VM system.
1324 *******************************************************************************/
1326 void exceptions_throw_nullpointerexception(void)
1328 *exceptionptr = new_nullpointerexception();
1332 /* exceptions_new_stringindexoutofboundsexception ******************************
1334 Generates a java.lang.StringIndexOutOfBoundsException for the VM
1337 *******************************************************************************/
1339 java_objectheader *exceptions_new_stringindexoutofboundsexception(void)
1341 java_objectheader *e;
1343 e = new_exception(string_java_lang_StringIndexOutOfBoundsException);
1346 return *exceptionptr;
1352 /* exceptions_throw_stringindexoutofboundsexception ****************************
1354 Throws a java.lang.StringIndexOutOfBoundsException for the VM
1357 *******************************************************************************/
1359 void exceptions_throw_stringindexoutofboundsexception(void)
1361 *exceptionptr = exceptions_new_stringindexoutofboundsexception();
1365 /* exceptions_handle_exception *************************************************
1367 Try to find an exception handler for the given exception and return it.
1368 If no handler is found, exit the monitor of the method (if any)
1372 xptr.........the exception object
1373 xpc..........PC of where the exception was thrown
1374 pv...........Procedure Value of the current method
1375 sp...........current stack pointer
1378 the address of the first matching exception handler, or
1379 NULL if no handler was found
1381 *******************************************************************************/
1383 u1 *exceptions_handle_exception(java_objectheader *xptr, u1 *xpc, u1 *pv, u1 *sp)
1390 s4 exceptiontablelength;
1392 classref_or_classinfo cr;
1394 #if defined(ENABLE_THREADS)
1395 java_objectheader *o;
1398 /* get info from the method header */
1400 code = *((codeinfo **) (pv + CodeinfoPointer));
1401 framesize = *((s4 *) (pv + FrameSize));
1402 issync = *((s4 *) (pv + IsSync));
1403 ex = (exceptionentry *) (pv + ExTableStart);
1404 exceptiontablelength = *((s4 *) (pv + ExTableSize));
1406 /* Get the methodinfo pointer form the codeinfo pointer. For
1407 asm_vm_call_method the codeinfo pointer is NULL. */
1409 m = (code == NULL) ? NULL : code->m;
1411 #if !defined(NDEBUG)
1412 /* print exception trace */
1414 if (opt_verbose || opt_verbosecall || opt_verboseexception)
1415 builtin_trace_exception(xptr, m, xpc, 1);
1418 for (i = 0; i < exceptiontablelength; i++) {
1419 /* ATTENTION: keep this here, as we need to decrement the
1420 pointer before the loop executes! */
1424 /* If the start and end PC is NULL, this means we have the
1425 special case of asm_vm_call_method. So, just return the
1426 proper exception handler. */
1428 if ((ex->startpc == NULL) && (ex->endpc == NULL))
1429 return (u1 *) (ptrint) &asm_vm_call_method_exception_handler;
1431 /* is the xpc is the current catch range */
1433 if ((ex->startpc <= xpc) && (xpc < ex->endpc)) {
1436 /* NULL catches everything */
1438 if (cr.any == NULL) {
1439 #if !defined(NDEBUG)
1440 /* Print stacktrace of exception when caught. */
1442 if (opt_verboseexception) {
1443 exceptions_print_exception(xptr);
1444 stacktrace_print_trace(xptr);
1448 return ex->handlerpc;
1451 /* resolve or load/link the exception class */
1453 if (IS_CLASSREF(cr)) {
1454 c = resolve_classref_eager(cr.ref);
1459 if (!(c->state & CLASS_LOADED))
1460 /* use the methods' classloader */
1461 if (!load_class_from_classloader(c->name,
1462 m->class->classloader))
1465 if (!(c->state & CLASS_LINKED))
1470 /* is the thrown exception an instance of the catch class? */
1472 if (builtin_instanceof(xptr, c)) {
1473 #if !defined(NDEBUG)
1474 /* Print stacktrace of exception when caught. */
1476 if (opt_verboseexception) {
1477 exceptions_print_exception(xptr);
1478 stacktrace_print_trace(xptr);
1482 return ex->handlerpc;
1487 #if defined(ENABLE_THREADS)
1488 /* is this method synchronized? */
1491 /* get synchronization object */
1493 # if defined(__MIPS__) && (SIZEOF_VOID_P == 4)
1494 /* XXX change this if we ever want to use 4-byte stackslots */
1495 o = *((java_objectheader **) (sp + issync - 8));
1497 o = *((java_objectheader **) (sp + issync - SIZEOF_VOID_P));
1502 builtin_monitorexit(o);
1506 /* none of the exceptions catch this one */
1512 /* exceptions_print_exception **************************************************
1514 Prints an exception, the detail message and the cause, if
1515 available, with CACAO internal functions to stdout.
1517 *******************************************************************************/
1519 #if !defined(NDEBUG)
1520 void exceptions_print_exception(java_objectheader *xptr)
1522 java_lang_Throwable *t;
1523 java_lang_Throwable *cause;
1526 t = (java_lang_Throwable *) xptr;
1535 /* print the root exception */
1537 utf_display_printable_ascii_classname(t->header.vftbl->class->name);
1539 if (t->detailMessage) {
1540 u = javastring_toutf(t->detailMessage, false);
1543 utf_display_printable_ascii(u);
1548 /* print the cause if available */
1550 if (cause && (cause != t)) {
1551 printf("Caused by: ");
1552 utf_display_printable_ascii_classname(cause->header.vftbl->class->name);
1554 if (cause->detailMessage) {
1555 u = javastring_toutf(cause->detailMessage, false);
1558 utf_display_printable_ascii(u);
1564 #endif /* !defined(NDEBUG) */
1568 * These are local overrides for various environment variables in Emacs.
1569 * Please do not remove this and leave it at the end of the file, where
1570 * Emacs will automagically detect them.
1571 * ---------------------------------------------------------------------
1574 * indent-tabs-mode: t
1578 * vim:noexpandtab:sw=4:ts=4: