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
30 $Id: exceptions.c 6598 2007-01-11 14:28:47Z twisti $
44 #include "mm/memory.h"
45 #include "native/jni.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))
87 if (!(class_java_lang_Error = load_class_bootstrap(utf_java_lang_Error)) ||
88 !link_class(class_java_lang_Error))
91 #if defined(ENABLE_JAVASE)
92 /* java/lang/AbstractMethodError */
94 if (!(class_java_lang_AbstractMethodError =
95 load_class_bootstrap(utf_java_lang_AbstractMethodError)) ||
96 !link_class(class_java_lang_AbstractMethodError))
99 /* java/lang/LinkageError */
101 if (!(class_java_lang_LinkageError =
102 load_class_bootstrap(utf_java_lang_LinkageError)) ||
103 !link_class(class_java_lang_LinkageError))
107 /* java/lang/NoClassDefFoundError */
109 if (!(class_java_lang_NoClassDefFoundError =
110 load_class_bootstrap(utf_java_lang_NoClassDefFoundError)) ||
111 !link_class(class_java_lang_NoClassDefFoundError))
114 #if defined(ENABLE_JAVASE)
115 /* java/lang/NoSuchMethodError */
117 if (!(class_java_lang_NoSuchMethodError =
118 load_class_bootstrap(utf_java_lang_NoSuchMethodError)) ||
119 !link_class(class_java_lang_NoSuchMethodError))
123 /* java/lang/OutOfMemoryError */
125 if (!(class_java_lang_OutOfMemoryError =
126 load_class_bootstrap(utf_java_lang_OutOfMemoryError)) ||
127 !link_class(class_java_lang_OutOfMemoryError))
130 /* java/lang/VirtualMachineError */
132 if (!(class_java_lang_VirtualMachineError =
133 load_class_bootstrap(utf_java_lang_VirtualMachineError)) ||
134 !link_class(class_java_lang_VirtualMachineError))
138 /* java/lang/Exception */
140 if (!(class_java_lang_Exception =
141 load_class_bootstrap(utf_java_lang_Exception)) ||
142 !link_class(class_java_lang_Exception))
145 /* java/lang/ClassCastException */
147 if (!(class_java_lang_ClassCastException =
148 load_class_bootstrap(utf_java_lang_ClassCastException)) ||
149 !link_class(class_java_lang_ClassCastException))
152 /* java/lang/ClassNotFoundException */
154 if (!(class_java_lang_ClassNotFoundException =
155 load_class_bootstrap(utf_java_lang_ClassNotFoundException)) ||
156 !link_class(class_java_lang_ClassNotFoundException))
159 /* java/lang/IllegalArgumentException */
161 if (!(class_java_lang_IllegalArgumentException =
162 load_class_bootstrap(utf_java_lang_IllegalArgumentException)) ||
163 !link_class(class_java_lang_IllegalArgumentException))
166 /* java/lang/IllegalMonitorStateException */
168 if (!(class_java_lang_IllegalMonitorStateException =
169 load_class_bootstrap(utf_java_lang_IllegalMonitorStateException)) ||
170 !link_class(class_java_lang_IllegalMonitorStateException))
173 /* java/lang/NullPointerException */
175 if (!(class_java_lang_NullPointerException =
176 load_class_bootstrap(utf_java_lang_NullPointerException)) ||
177 !link_class(class_java_lang_NullPointerException))
181 #if defined(WITH_CLASSPATH_GNU)
182 /* java/lang/VMThrowable */
184 if (!(class_java_lang_VMThrowable =
185 load_class_bootstrap(utf_java_lang_VMThrowable)) ||
186 !link_class(class_java_lang_VMThrowable))
194 static void throw_exception_exit_intern(bool doexit)
196 java_objectheader *xptr;
200 xptr = *exceptionptr;
203 /* clear exception, because we are calling jit code again */
204 *exceptionptr = NULL;
206 c = xptr->vftbl->class;
208 pss = class_resolveclassmethod(c,
211 class_java_lang_Object,
214 /* print the stacktrace */
217 (void) vm_call_method(pss, xptr);
219 /* This normally means, we are EXTREMLY out of memory or have a */
220 /* serious problem while printStackTrace. But may be another */
221 /* exception, so print it. */
224 java_lang_Throwable *t;
226 t = (java_lang_Throwable *) *exceptionptr;
228 fprintf(stderr, "Exception while printStackTrace(): ");
229 utf_fprint_printable_ascii_classname(stderr, t->header.vftbl->class->name);
231 if (t->detailMessage) {
234 buf = javastring_tochar((java_objectheader *) t->detailMessage);
235 fprintf(stderr, ": %s", buf);
236 MFREE(buf, char, strlen(buf));
239 fprintf(stderr, "\n");
243 utf_fprint_printable_ascii_classname(stderr, c->name);
244 fprintf(stderr, ": printStackTrace()V not found!\n");
257 void throw_exception(void)
259 throw_exception_exit_intern(false);
263 void throw_exception_exit(void)
265 throw_exception_exit_intern(true);
269 void throw_main_exception(void)
271 fprintf(stderr, "Exception in thread \"main\" ");
274 throw_exception_exit_intern(false);
278 void throw_main_exception_exit(void)
280 fprintf(stderr, "Exception in thread \"main\" ");
283 throw_exception_exit_intern(true);
287 void throw_cacao_exception_exit(const char *exception, const char *message, ...)
294 len = strlen(exception);
295 tmp = MNEW(char, len + 1);
296 strncpy(tmp, exception, len);
299 /* convert to classname */
301 for (i = len - 1; i >= 0; i--)
302 if (tmp[i] == '/') tmp[i] = '.';
304 fprintf(stderr, "Exception in thread \"main\" %s", tmp);
306 MFREE(tmp, char, len);
308 if (strlen(message) > 0) {
309 fprintf(stderr, ": ");
311 va_start(ap, message);
312 vfprintf(stderr, message, ap);
316 fprintf(stderr, "\n");
325 /* new_exception ***************************************************************
327 Creates an exception object with the given name and initalizes it.
330 classname....class name in UTF-8
333 an exception pointer (in any case -- either it is the newly created
334 exception, or an exception thrown while trying to create it).
336 *******************************************************************************/
338 java_objectheader *new_exception(const char *classname)
340 java_objectheader *o;
343 if (!(c = load_class_bootstrap(utf_new_char(classname))))
344 return *exceptionptr;
346 o = native_new_and_init(c);
349 return *exceptionptr;
355 /* new_exception_message *******************************************************
357 Creates an exception object with the given name and initalizes it
358 with the given char message.
361 classname....class name in UTF-8
362 message......message in UTF-8
365 an exception pointer (in any case -- either it is the newly created
366 exception, or an exception thrown while trying to create it).
368 *******************************************************************************/
370 java_objectheader *new_exception_message(const char *classname,
375 s = javastring_new_from_utf_string(message);
377 return *exceptionptr;
379 return new_exception_javastring(classname, s);
383 /* new_exception_throwable *****************************************************
385 Creates an exception object with the given name and initalizes it
386 with the given java/lang/Throwable exception.
389 classname....class name in UTF-8
390 throwable....the given Throwable
393 an exception pointer (in any case -- either it is the newly created
394 exception, or an exception thrown while trying to create it).
396 *******************************************************************************/
398 java_objectheader *new_exception_throwable(const char *classname,
399 java_lang_Throwable *throwable)
401 java_objectheader *o;
404 if (!(c = load_class_bootstrap(utf_new_char(classname))))
405 return *exceptionptr;
407 o = native_new_and_init_throwable(c, throwable);
410 return *exceptionptr;
416 /* new_exception_utfmessage ****************************************************
418 Creates an exception object with the given name and initalizes it
419 with the given utf message.
422 classname....class name in UTF-8
423 message......the message as an utf *
426 an exception pointer (in any case -- either it is the newly created
427 exception, or an exception thrown while trying to create it).
429 *******************************************************************************/
431 java_objectheader *new_exception_utfmessage(const char *classname, utf *message)
435 s = javastring_new(message);
437 return *exceptionptr;
439 return new_exception_javastring(classname, s);
443 /* new_exception_javastring ****************************************************
445 Creates an exception object with the given name and initalizes it
446 with the given java/lang/String message.
449 classname....class name in UTF-8
450 message......the message as a java.lang.String
453 an exception pointer (in any case -- either it is the newly created
454 exception, or an exception thrown while trying to create it).
456 *******************************************************************************/
458 java_objectheader *new_exception_javastring(const char *classname,
459 java_lang_String *message)
461 java_objectheader *o;
464 if (!(c = load_class_bootstrap(utf_new_char(classname))))
465 return *exceptionptr;
467 o = native_new_and_init_string(c, message);
470 return *exceptionptr;
476 /* new_exception_int ***********************************************************
478 Creates an exception object with the given name and initalizes it
479 with the given int value.
482 classname....class name in UTF-8
483 i............the integer
486 an exception pointer (in any case -- either it is the newly created
487 exception, or an exception thrown while trying to create it).
489 *******************************************************************************/
491 java_objectheader *new_exception_int(const char *classname, s4 i)
493 java_objectheader *o;
496 if (!(c = load_class_bootstrap(utf_new_char(classname))))
497 return *exceptionptr;
499 o = native_new_and_init_int(c, i);
502 return *exceptionptr;
508 /* exceptions_new_abstractmethoderror ******************************************
510 Generates a java.lang.AbstractMethodError for the VM.
512 *******************************************************************************/
514 #if defined(ENABLE_JAVASE)
515 java_objectheader *exceptions_new_abstractmethoderror(void)
517 java_objectheader *e;
519 e = native_new_and_init(class_java_lang_AbstractMethodError);
522 return *exceptionptr;
529 /* exceptions_throw_abstractmethoderror ****************************************
531 Generates a java.lang.AbstractMethodError for the VM and throws it.
533 *******************************************************************************/
535 #if defined(ENABLE_JAVASE)
536 void exceptions_throw_abstractmethoderror(void)
538 *exceptionptr = exceptions_new_abstractmethoderror();
543 /* exceptions_asm_new_abstractmethoderror **************************************
545 Generates a java.lang.AbstractMethodError for
546 asm_abstractmethoderror.
548 *******************************************************************************/
550 java_objectheader *exceptions_asm_new_abstractmethoderror(u1 *sp, u1 *ra)
553 java_objectheader *e;
555 /* create the stackframeinfo (XPC is equal to RA) */
557 stacktrace_create_extern_stackframeinfo(&sfi, NULL, sp, ra, ra);
559 /* create the exception */
561 #if defined(ENABLE_JAVASE)
562 e = exceptions_new_abstractmethoderror();
564 /* in the meantime we do this */
566 e = exceptions_new_virtualmachineerror();
569 /* remove the stackframeinfo */
571 stacktrace_remove_stackframeinfo(&sfi);
577 /* new_classformaterror ********************************************************
579 generates a java.lang.ClassFormatError for the classloader
582 c............the class in which the error was found
583 message......UTF-8 format string
586 an exception pointer (in any case -- either it is the newly created
587 exception, or an exception thrown while trying to create it).
589 *******************************************************************************/
591 java_objectheader *new_classformaterror(classinfo *c, const char *message, ...)
593 java_objectheader *o;
598 /* calculate message length */
603 msglen += utf_bytes(c->name) + strlen(" (");
605 va_start(ap, message);
606 msglen += get_variable_message_length(message, ap);
610 msglen += strlen(")");
612 msglen += strlen("0");
614 /* allocate a buffer */
616 msg = MNEW(char, msglen);
618 /* print message into allocated buffer */
621 utf_copy_classname(msg, c->name);
625 va_start(ap, message);
626 vsprintf(msg + strlen(msg), message, ap);
632 o = new_exception_message(string_java_lang_ClassFormatError, msg);
634 MFREE(msg, char, msglen);
640 /* exceptions_throw_classformaterror *******************************************
642 Generate a java.lang.ClassFormatError for the VM system and throw it.
645 c............the class in which the error was found
646 message......UTF-8 format string
649 an exception pointer (in any case -- either it is the newly created
650 exception, or an exception thrown while trying to create it).
652 *******************************************************************************/
654 void exceptions_throw_classformaterror(classinfo *c, const char *message, ...)
658 va_start(ap, message);
659 *exceptionptr = new_classformaterror(c, message, ap);
664 /* new_classnotfoundexception **************************************************
666 Generates a java.lang.ClassNotFoundException for the classloader.
669 name.........name of the class not found as a utf *
672 an exception pointer (in any case -- either it is the newly created
673 exception, or an exception thrown while trying to create it).
675 *******************************************************************************/
677 java_objectheader *new_classnotfoundexception(utf *name)
679 java_objectheader *o;
682 s = javastring_new(name);
684 return *exceptionptr;
686 o = native_new_and_init_string(class_java_lang_ClassNotFoundException, s);
689 return *exceptionptr;
695 /* new_noclassdeffounderror ****************************************************
697 Generates a java.lang.NoClassDefFoundError
700 name.........name of the class not found as a utf *
703 an exception pointer (in any case -- either it is the newly created
704 exception, or an exception thrown while trying to create it).
706 *******************************************************************************/
708 java_objectheader *new_noclassdeffounderror(utf *name)
710 java_objectheader *o;
713 s = javastring_new(name);
715 return *exceptionptr;
717 o = native_new_and_init_string(class_java_lang_NoClassDefFoundError, s);
720 return *exceptionptr;
726 /* classnotfoundexception_to_noclassdeffounderror ******************************
728 Check the *exceptionptr for a ClassNotFoundException. If it is one,
729 convert it to a NoClassDefFoundError.
731 *******************************************************************************/
733 void classnotfoundexception_to_noclassdeffounderror(void)
735 java_objectheader *xptr;
736 java_objectheader *cause;
740 cause = *exceptionptr;
742 /* convert ClassNotFoundException's to NoClassDefFoundError's */
744 if (builtin_instanceof(cause, class_java_lang_ClassNotFoundException)) {
745 /* clear exception, because we are calling jit code again */
747 *exceptionptr = NULL;
749 /* create new error */
752 new_exception_javastring(string_java_lang_NoClassDefFoundError,
753 ((java_lang_Throwable *) cause)->detailMessage);
755 /* we had an exception while creating the error */
760 /* set new exception */
762 *exceptionptr = xptr;
767 /* exceptions_throw_internalerror **********************************************
769 Generates and throws a java.lang.InternalError for the VM.
772 message......UTF-8 message format string
774 *******************************************************************************/
776 void exceptions_throw_internalerror(const char *message, ...)
778 java_objectheader *o;
783 /* calculate exception message length */
785 va_start(ap, message);
786 msglen = get_variable_message_length(message, ap);
789 /* allocate memory */
791 msg = MNEW(char, msglen);
793 /* generate message */
795 va_start(ap, message);
796 vsprintf(msg, message, ap);
799 /* create exception object */
801 o = new_exception_message(string_java_lang_InternalError, msg);
805 MFREE(msg, char, msglen);
814 /* exceptions_new_linkageerror *************************************************
816 Generates a java.lang.LinkageError with an error message.
819 message......UTF-8 message
820 c............class related to the error. If this is != NULL
821 the name of c is appended to the error message.
824 an exception pointer (in any case -- either it is the newly created
825 exception, or an exception thrown while trying to create it).
827 *******************************************************************************/
829 java_objectheader *exceptions_new_linkageerror(const char *message,
832 java_objectheader *o;
836 /* calculate exception message length */
838 msglen = strlen(message) + 1;
840 msglen += utf_bytes(c->name);
843 /* allocate memory */
845 msg = MNEW(char, msglen);
847 /* generate message */
851 utf_cat_classname(msg, c->name);
854 o = native_new_and_init_string(class_java_lang_LinkageError,
855 javastring_new_from_utf_string(msg));
859 MFREE(msg, char, msglen);
862 return *exceptionptr;
868 /* exceptions_new_nosuchmethoderror ********************************************
870 Generates a java.lang.NoSuchMethodError with an error message.
873 c............class in which the method was not found
874 name.........name of the method
875 desc.........descriptor of the method
878 an exception pointer (in any case -- either it is the newly created
879 exception, or an exception thrown while trying to create it).
881 *******************************************************************************/
883 #if defined(ENABLE_JAVASE)
884 java_objectheader *exceptions_new_nosuchmethoderror(classinfo *c,
885 utf *name, utf *desc)
887 java_objectheader *o;
891 /* calculate exception message length */
893 msglen = utf_bytes(c->name) + strlen(".") + utf_bytes(name) +
894 utf_bytes(desc) + strlen("0");
896 /* allocate memory */
898 msg = MNEW(char, msglen);
900 /* generate message */
902 utf_copy_classname(msg, c->name);
907 o = native_new_and_init_string(class_java_lang_NoSuchMethodError,
908 javastring_new_from_utf_string(msg));
912 MFREE(msg, char, msglen);
915 return *exceptionptr;
922 /* exceptions_throw_nosuchmethoderror ******************************************
924 Generates a java.lang.NoSuchMethodError with an error message.
927 c............class in which the method was not found
928 name.........name of the method
929 desc.........descriptor of the method
931 *******************************************************************************/
933 #if defined(ENABLE_JAVASE)
934 void exceptions_throw_nosuchmethoderror(classinfo *c, utf *name, utf *desc)
936 *exceptionptr = exceptions_new_nosuchmethoderror(c, name, desc);
941 /* exceptions_throw_outofmemoryerror *******************************************
943 Generates and throws an java.lang.OutOfMemoryError for the VM.
945 *******************************************************************************/
947 void exceptions_throw_outofmemoryerror(void)
949 java_objectheader *e;
951 e = native_new_and_init(class_java_lang_OutOfMemoryError);
960 /* new_unsupportedclassversionerror ********************************************
962 Generate a java.lang.UnsupportedClassVersionError for the classloader
965 c............class in which the method was not found
966 message......UTF-8 format string
969 an exception pointer (in any case -- either it is the newly created
970 exception, or an exception thrown while trying to create it).
972 *******************************************************************************/
974 java_objectheader *new_unsupportedclassversionerror(classinfo *c, const char *message, ...)
976 java_objectheader *o;
981 /* calculate exception message length */
983 msglen = utf_bytes(c->name) + strlen(" (") + 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 */
995 utf_copy_classname(msg, c->name);
998 va_start(ap, message);
999 vsprintf(msg + strlen(msg), message, ap);
1004 /* create exception object */
1006 o = new_exception_message(string_java_lang_UnsupportedClassVersionError,
1011 MFREE(msg, char, msglen);
1017 /* exceptions_new_verifyerror **************************************************
1019 Generates a java.lang.VerifyError for the JIT compiler.
1022 m............method in which the error was found
1023 message......UTF-8 format string
1026 an exception pointer (in any case -- either it is the newly created
1027 exception, or an exception thrown while trying to create it).
1029 *******************************************************************************/
1031 java_objectheader *exceptions_new_verifyerror(methodinfo *m,
1032 const char *message, ...)
1034 java_objectheader *o;
1039 useinlining = false; /* at least until sure inlining works with exceptions*/
1041 /* calculate exception message length */
1046 msglen = strlen("(class: ") + utf_bytes(m->class->name) +
1047 strlen(", method: ") + utf_bytes(m->name) +
1048 strlen(" signature: ") + utf_bytes(m->descriptor) +
1049 strlen(") ") + strlen("0");
1051 va_start(ap, message);
1052 msglen += get_variable_message_length(message, ap);
1055 /* allocate memory */
1057 msg = MNEW(char, msglen);
1059 /* generate message */
1062 strcpy(msg, "(class: ");
1063 utf_cat_classname(msg, m->class->name);
1064 strcat(msg, ", method: ");
1065 utf_cat(msg, m->name);
1066 strcat(msg, " signature: ");
1067 utf_cat(msg, m->descriptor);
1071 va_start(ap, message);
1072 vsprintf(msg + strlen(msg), message, ap);
1075 /* create exception object */
1077 o = new_exception_message(string_java_lang_VerifyError, msg);
1081 MFREE(msg, char, msglen);
1087 /* exceptions_throw_verifyerror ************************************************
1089 Throws a java.lang.VerifyError for the VM system.
1091 *******************************************************************************/
1093 void exceptions_throw_verifyerror(methodinfo *m, const char *message, ...)
1095 *exceptionptr = exceptions_new_verifyerror(m, message);
1099 /* exceptions_throw_verifyerror_for_stack **************************************
1101 throws a java.lang.VerifyError for an invalid stack slot type
1104 m............method in which the error was found
1105 type.........the expected type
1108 an exception pointer (in any case -- either it is the newly created
1109 exception, or an exception thrown while trying to create it).
1111 *******************************************************************************/
1113 void exceptions_throw_verifyerror_for_stack(methodinfo *m,int type)
1115 java_objectheader *o;
1120 /* calculate exception message length */
1125 msglen = strlen("(class: ") + utf_bytes(m->class->name) +
1126 strlen(", method: ") + utf_bytes(m->name) +
1127 strlen(" signature: ") + utf_bytes(m->descriptor) +
1128 strlen(") Expecting to find longest-------typename on stack")
1131 /* allocate memory */
1133 msg = MNEW(char, msglen);
1135 /* generate message */
1138 strcpy(msg, "(class: ");
1139 utf_cat_classname(msg, m->class->name);
1140 strcat(msg, ", method: ");
1141 utf_cat(msg, m->name);
1142 strcat(msg, " signature: ");
1143 utf_cat(msg, m->descriptor);
1150 strcat(msg,"Expecting to find ");
1152 case TYPE_INT: typename = "integer"; break;
1153 case TYPE_LNG: typename = "long"; break;
1154 case TYPE_FLT: typename = "float"; break;
1155 case TYPE_DBL: typename = "double"; break;
1156 case TYPE_ADR: typename = "object/array"; break;
1157 case TYPE_RET: typename = "returnAddress"; break;
1158 default: typename = "<INVALID>"; assert(0); break;
1160 strcat(msg, typename);
1161 strcat(msg, " on stack");
1163 /* create exception object */
1165 o = new_exception_message(string_java_lang_VerifyError, msg);
1169 MFREE(msg, char, msglen);
1175 /* exceptions_new_virtualmachineerror ******************************************
1177 Generates a java.lang.VirtualMachineError for the VM system.
1179 *******************************************************************************/
1181 java_objectheader *exceptions_new_virtualmachineerror(void)
1183 java_objectheader *e;
1185 e = native_new_and_init(class_java_lang_VirtualMachineError);
1188 return *exceptionptr;
1194 /* exceptions_throw_virtualmachineerror ****************************************
1196 Throws a java.lang.VirtualMachineError for the VM system.
1198 *******************************************************************************/
1200 void exceptions_throw_virtualmachineerror(void)
1202 *exceptionptr = exceptions_new_virtualmachineerror();
1206 /* new_arithmeticexception *****************************************************
1208 Generates a java.lang.ArithmeticException for the jit compiler.
1210 *******************************************************************************/
1212 java_objectheader *new_arithmeticexception(void)
1214 java_objectheader *e;
1216 e = new_exception_message(string_java_lang_ArithmeticException,
1217 string_java_lang_ArithmeticException_message);
1220 return *exceptionptr;
1226 /* exceptions_new_arrayindexoutofboundsexception *******************************
1228 Generates a java.lang.ArrayIndexOutOfBoundsException for the VM
1231 *******************************************************************************/
1233 java_objectheader *new_arrayindexoutofboundsexception(s4 index)
1235 java_objectheader *e;
1237 java_objectheader *o;
1238 java_lang_String *s;
1240 /* convert the index into a String, like Sun does */
1242 m = class_resolveclassmethod(class_java_lang_String,
1243 utf_new_char("valueOf"),
1244 utf_new_char("(I)Ljava/lang/String;"),
1245 class_java_lang_Object,
1249 return *exceptionptr;
1251 o = vm_call_method(m, NULL, index);
1253 s = (java_lang_String *) o;
1256 return *exceptionptr;
1258 e = new_exception_javastring(string_java_lang_ArrayIndexOutOfBoundsException,
1262 return *exceptionptr;
1268 /* exceptions_throw_arrayindexoutofboundsexception *****************************
1270 Generates a java.lang.ArrayIndexOutOfBoundsException for the VM
1273 *******************************************************************************/
1275 void exceptions_throw_arrayindexoutofboundsexception(void)
1277 java_objectheader *e;
1279 e = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
1288 /* exceptions_new_arraystoreexception ******************************************
1290 Generates a java.lang.ArrayStoreException for the VM compiler.
1292 *******************************************************************************/
1294 java_objectheader *exceptions_new_arraystoreexception(void)
1296 java_objectheader *e;
1298 e = new_exception(string_java_lang_ArrayStoreException);
1299 /* e = native_new_and_init(class_java_lang_ArrayStoreException); */
1302 return *exceptionptr;
1308 /* exceptions_throw_arraystoreexception ****************************************
1310 Generates a java.lang.ArrayStoreException for the VM system and
1311 throw it in the VM system.
1313 *******************************************************************************/
1315 void exceptions_throw_arraystoreexception(void)
1317 *exceptionptr = exceptions_new_arraystoreexception();
1321 /* exceptions_new_classcastexception *******************************************
1323 Generates a java.lang.ClassCastException for the JIT compiler.
1325 *******************************************************************************/
1327 java_objectheader *exceptions_new_classcastexception(java_objectheader *o)
1329 java_objectheader *e;
1331 java_lang_String *s;
1333 classname = o->vftbl->class->name;
1335 s = javastring_new(classname);
1337 e = native_new_and_init_string(class_java_lang_ClassCastException, s);
1340 return *exceptionptr;
1346 /* exceptions_new_illegalargumentexception *************************************
1348 Generates a java.lang.IllegalArgumentException for the VM system.
1350 *******************************************************************************/
1352 java_objectheader *new_illegalargumentexception(void)
1354 java_objectheader *e;
1356 e = native_new_and_init(class_java_lang_IllegalArgumentException);
1359 return *exceptionptr;
1365 /* exceptions_throw_illegalargumentexception ***********************************
1367 Generates a java.lang.IllegalArgumentException for the VM system
1368 and throw it in the VM system.
1370 *******************************************************************************/
1372 void exceptions_throw_illegalargumentexception(void)
1374 *exceptionptr = new_illegalargumentexception();
1378 /* exceptions_new_illegalmonitorstateexception *********************************
1380 Generates a java.lang.IllegalMonitorStateException for the VM
1383 *******************************************************************************/
1385 java_objectheader *exceptions_new_illegalmonitorstateexception(void)
1387 java_objectheader *e;
1389 e = native_new_and_init(class_java_lang_IllegalMonitorStateException);
1392 return *exceptionptr;
1398 /* exceptions_throw_illegalmonitorstateexception *******************************
1400 Generates a java.lang.IllegalMonitorStateException for the VM
1401 system and throw it in the VM system.
1403 *******************************************************************************/
1405 void exceptions_throw_illegalmonitorstateexception(void)
1407 *exceptionptr = exceptions_new_illegalmonitorstateexception();
1411 /* exceptions_new_negativearraysizeexception ***********************************
1413 Generates a java.lang.NegativeArraySizeException for the VM system.
1415 *******************************************************************************/
1417 java_objectheader *new_negativearraysizeexception(void)
1419 java_objectheader *e;
1421 e = new_exception(string_java_lang_NegativeArraySizeException);
1424 return *exceptionptr;
1430 /* exceptions_throw_negativearraysizeexception *********************************
1432 Generates a java.lang.NegativeArraySizeException for the VM system.
1434 *******************************************************************************/
1436 void exceptions_throw_negativearraysizeexception(void)
1438 *exceptionptr = new_negativearraysizeexception();
1442 /* exceptions_new_nullpointerexception *****************************************
1444 Generates a java.lang.NullPointerException for the VM system.
1446 *******************************************************************************/
1448 java_objectheader *exceptions_new_nullpointerexception(void)
1450 java_objectheader *e;
1452 e = native_new_and_init(class_java_lang_NullPointerException);
1455 return *exceptionptr;
1461 /* exceptions_throw_nullpointerexception ***************************************
1463 Generates a java.lang.NullPointerException for the VM system and
1464 throw it in the VM system.
1466 *******************************************************************************/
1468 void exceptions_throw_nullpointerexception(void)
1470 *exceptionptr = exceptions_new_nullpointerexception();
1474 /* exceptions_new_stringindexoutofboundsexception ******************************
1476 Generates a java.lang.StringIndexOutOfBoundsException for the VM
1479 *******************************************************************************/
1481 java_objectheader *exceptions_new_stringindexoutofboundsexception(void)
1483 java_objectheader *e;
1485 e = new_exception(string_java_lang_StringIndexOutOfBoundsException);
1488 return *exceptionptr;
1494 /* exceptions_throw_stringindexoutofboundsexception ****************************
1496 Throws a java.lang.StringIndexOutOfBoundsException for the VM
1499 *******************************************************************************/
1501 void exceptions_throw_stringindexoutofboundsexception(void)
1503 *exceptionptr = exceptions_new_stringindexoutofboundsexception();
1507 /* exceptions_get_and_clear_exception ******************************************
1509 Gets the exception pointer of the current thread and clears it.
1510 This function may return NULL.
1512 *******************************************************************************/
1514 java_objectheader *exceptions_get_and_clear_exception(void)
1516 java_objectheader **p;
1517 java_objectheader *e;
1519 /* get the pointer of the exception pointer */
1523 /* get the exception */
1527 /* and clear the exception */
1531 /* return the exception */
1537 /* exceptions_handle_exception *************************************************
1539 Try to find an exception handler for the given exception and return it.
1540 If no handler is found, exit the monitor of the method (if any)
1544 xptr.........the exception object
1545 xpc..........PC of where the exception was thrown
1546 pv...........Procedure Value of the current method
1547 sp...........current stack pointer
1550 the address of the first matching exception handler, or
1551 NULL if no handler was found
1553 *******************************************************************************/
1555 #if defined(ENABLE_JIT)
1556 u1 *exceptions_handle_exception(java_objectheader *xptr, u1 *xpc, u1 *pv, u1 *sp)
1561 dseg_exception_entry *ex;
1562 s4 exceptiontablelength;
1564 classref_or_classinfo cr;
1566 #if defined(ENABLE_THREADS)
1567 java_objectheader *o;
1570 /* get info from the method header */
1572 code = *((codeinfo **) (pv + CodeinfoPointer));
1573 issync = *((s4 *) (pv + IsSync));
1574 ex = (dseg_exception_entry *) (pv + ExTableStart);
1575 exceptiontablelength = *((s4 *) (pv + ExTableSize));
1577 /* Get the methodinfo pointer from the codeinfo pointer. For
1578 asm_vm_call_method the codeinfo pointer is NULL. */
1580 m = (code == NULL) ? NULL : code->m;
1582 #if !defined(NDEBUG)
1583 /* print exception trace */
1585 if (opt_verbose || opt_verbosecall || opt_verboseexception)
1586 builtin_trace_exception(xptr, m, xpc, 1);
1589 for (i = 0; i < exceptiontablelength; i++) {
1590 /* ATTENTION: keep this here, as we need to decrement the
1591 pointer before the loop executes! */
1595 /* If the start and end PC is NULL, this means we have the
1596 special case of asm_vm_call_method. So, just return the
1597 proper exception handler. */
1599 if ((ex->startpc == NULL) && (ex->endpc == NULL))
1600 return (u1 *) (ptrint) &asm_vm_call_method_exception_handler;
1602 /* is the xpc is the current catch range */
1604 if ((ex->startpc <= xpc) && (xpc < ex->endpc)) {
1607 /* NULL catches everything */
1609 if (cr.any == NULL) {
1610 #if !defined(NDEBUG)
1611 /* Print stacktrace of exception when caught. */
1613 if (opt_verboseexception) {
1614 exceptions_print_exception(xptr);
1615 stacktrace_print_trace(xptr);
1619 return ex->handlerpc;
1622 /* resolve or load/link the exception class */
1624 if (IS_CLASSREF(cr)) {
1625 /* The exception class reference is unresolved. */
1626 /* We have to do _eager_ resolving here. While the class of */
1627 /* the exception object is guaranteed to be loaded, it may */
1628 /* well have been loaded by a different loader than the */
1629 /* defining loader of m's class, which is the one we must */
1630 /* use to resolve the catch class. Thus lazy resolving */
1631 /* might fail, even if the result of the resolution would */
1632 /* be an already loaded class. */
1634 c = resolve_classref_eager(cr.ref);
1637 /* Exception resolving the exception class, argh! */
1641 /* Ok, we resolved it. Enter it in the table, so we don't */
1642 /* have to do this again. */
1643 /* XXX this write should be atomic. Is it? */
1645 ex->catchtype.cls = c;
1649 /* XXX I don't think this case can ever happen. -Edwin */
1650 if (!(c->state & CLASS_LOADED))
1651 /* use the methods' classloader */
1652 if (!load_class_from_classloader(c->name,
1653 m->class->classloader))
1656 /* XXX I think, if it is not linked, we can be sure that */
1657 /* the exception object is no (indirect) instance of it, no? */
1659 if (!(c->state & CLASS_LINKED))
1664 /* is the thrown exception an instance of the catch class? */
1666 if (builtin_instanceof(xptr, c)) {
1667 #if !defined(NDEBUG)
1668 /* Print stacktrace of exception when caught. */
1670 if (opt_verboseexception) {
1671 exceptions_print_exception(xptr);
1672 stacktrace_print_trace(xptr);
1676 return ex->handlerpc;
1681 #if defined(ENABLE_THREADS)
1682 /* is this method synchronized? */
1685 /* get synchronization object */
1687 # if defined(__MIPS__) && (SIZEOF_VOID_P == 4)
1688 /* XXX change this if we ever want to use 4-byte stackslots */
1689 o = *((java_objectheader **) (sp + issync - 8));
1691 o = *((java_objectheader **) (sp + issync - SIZEOF_VOID_P));
1696 lock_monitor_exit(o);
1700 /* none of the exceptions catch this one */
1704 #endif /* defined(ENABLE_JIT) */
1707 /* exceptions_print_exception **************************************************
1709 Prints an exception, the detail message and the cause, if
1710 available, with CACAO internal functions to stdout.
1712 *******************************************************************************/
1714 void exceptions_print_exception(java_objectheader *xptr)
1716 java_lang_Throwable *t;
1717 #if defined(ENABLE_JAVASE)
1718 java_lang_Throwable *cause;
1722 t = (java_lang_Throwable *) xptr;
1729 #if defined(ENABLE_JAVASE)
1733 /* print the root exception */
1735 utf_display_printable_ascii_classname(t->header.vftbl->class->name);
1737 if (t->detailMessage != NULL) {
1738 u = javastring_toutf(t->detailMessage, false);
1741 utf_display_printable_ascii(u);
1746 #if defined(ENABLE_JAVASE)
1747 /* print the cause if available */
1749 if ((cause != NULL) && (cause != t)) {
1750 printf("Caused by: ");
1751 utf_display_printable_ascii_classname(cause->header.vftbl->class->name);
1753 if (cause->detailMessage) {
1754 u = javastring_toutf(cause->detailMessage, false);
1757 utf_display_printable_ascii(u);
1767 * These are local overrides for various environment variables in Emacs.
1768 * Please do not remove this and leave it at the end of the file, where
1769 * Emacs will automagically detect them.
1770 * ---------------------------------------------------------------------
1773 * indent-tabs-mode: t
1777 * vim:noexpandtab:sw=4:ts=4: