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 6244 2006-12-27 15:15:31Z 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 /* exceptions_throw_outofmemory_exit *******************************************
327 Just print an: java.lang.InternalError: Out of memory
329 *******************************************************************************/
331 void exceptions_throw_outofmemory_exit(void)
333 throw_cacao_exception_exit(string_java_lang_InternalError,
338 /* new_exception ***************************************************************
340 Creates an exception object with the given name and initalizes it.
343 classname....class name in UTF-8
346 an exception pointer (in any case -- either it is the newly created
347 exception, or an exception thrown while trying to create it).
349 *******************************************************************************/
351 java_objectheader *new_exception(const char *classname)
353 java_objectheader *o;
356 if (!(c = load_class_bootstrap(utf_new_char(classname))))
357 return *exceptionptr;
359 o = native_new_and_init(c);
362 return *exceptionptr;
368 /* new_exception_message *******************************************************
370 Creates an exception object with the given name and initalizes it
371 with the given char message.
374 classname....class name in UTF-8
375 message......message in UTF-8
378 an exception pointer (in any case -- either it is the newly created
379 exception, or an exception thrown while trying to create it).
381 *******************************************************************************/
383 java_objectheader *new_exception_message(const char *classname,
388 s = javastring_new_from_utf_string(message);
390 return *exceptionptr;
392 return new_exception_javastring(classname, s);
396 /* new_exception_throwable *****************************************************
398 Creates an exception object with the given name and initalizes it
399 with the given java/lang/Throwable exception.
402 classname....class name in UTF-8
403 throwable....the given Throwable
406 an exception pointer (in any case -- either it is the newly created
407 exception, or an exception thrown while trying to create it).
409 *******************************************************************************/
411 java_objectheader *new_exception_throwable(const char *classname,
412 java_lang_Throwable *throwable)
414 java_objectheader *o;
417 if (!(c = load_class_bootstrap(utf_new_char(classname))))
418 return *exceptionptr;
420 o = native_new_and_init_throwable(c, throwable);
423 return *exceptionptr;
429 /* new_exception_utfmessage ****************************************************
431 Creates an exception object with the given name and initalizes it
432 with the given utf message.
435 classname....class name in UTF-8
436 message......the message as an utf *
439 an exception pointer (in any case -- either it is the newly created
440 exception, or an exception thrown while trying to create it).
442 *******************************************************************************/
444 java_objectheader *new_exception_utfmessage(const char *classname, utf *message)
448 s = javastring_new(message);
450 return *exceptionptr;
452 return new_exception_javastring(classname, s);
456 /* new_exception_javastring ****************************************************
458 Creates an exception object with the given name and initalizes it
459 with the given java/lang/String message.
462 classname....class name in UTF-8
463 message......the message as a java.lang.String
466 an exception pointer (in any case -- either it is the newly created
467 exception, or an exception thrown while trying to create it).
469 *******************************************************************************/
471 java_objectheader *new_exception_javastring(const char *classname,
472 java_lang_String *message)
474 java_objectheader *o;
477 if (!(c = load_class_bootstrap(utf_new_char(classname))))
478 return *exceptionptr;
480 o = native_new_and_init_string(c, message);
483 return *exceptionptr;
489 /* new_exception_int ***********************************************************
491 Creates an exception object with the given name and initalizes it
492 with the given int value.
495 classname....class name in UTF-8
496 i............the integer
499 an exception pointer (in any case -- either it is the newly created
500 exception, or an exception thrown while trying to create it).
502 *******************************************************************************/
504 java_objectheader *new_exception_int(const char *classname, s4 i)
506 java_objectheader *o;
509 if (!(c = load_class_bootstrap(utf_new_char(classname))))
510 return *exceptionptr;
512 o = native_new_and_init_int(c, i);
515 return *exceptionptr;
521 /* exceptions_new_abstractmethoderror ******************************************
523 Generates a java.lang.AbstractMethodError for the VM.
525 *******************************************************************************/
527 #if defined(ENABLE_JAVASE)
528 java_objectheader *exceptions_new_abstractmethoderror(void)
530 java_objectheader *e;
532 e = native_new_and_init(class_java_lang_AbstractMethodError);
535 return *exceptionptr;
542 /* exceptions_asm_new_abstractmethoderror **************************************
544 Generates a java.lang.AbstractMethodError for
545 asm_abstractmethoderror.
547 *******************************************************************************/
549 #if defined(ENABLE_JAVASE)
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 e = exceptions_new_abstractmethoderror();
563 /* remove the stackframeinfo */
565 stacktrace_remove_stackframeinfo(&sfi);
572 /* exceptions_throw_abstractmethoderror ****************************************
574 Generates a java.lang.AbstractMethodError for the VM and throws it.
576 *******************************************************************************/
578 #if defined(ENABLE_JAVASE)
579 void exceptions_throw_abstractmethoderror(void)
581 *exceptionptr = exceptions_new_abstractmethoderror();
586 /* new_classformaterror ********************************************************
588 generates a java.lang.ClassFormatError for the classloader
591 c............the class in which the error was found
592 message......UTF-8 format string
595 an exception pointer (in any case -- either it is the newly created
596 exception, or an exception thrown while trying to create it).
598 *******************************************************************************/
600 java_objectheader *new_classformaterror(classinfo *c, const char *message, ...)
602 java_objectheader *o;
607 /* calculate message length */
612 msglen += utf_bytes(c->name) + strlen(" (");
614 va_start(ap, message);
615 msglen += get_variable_message_length(message, ap);
619 msglen += strlen(")");
621 msglen += strlen("0");
623 /* allocate a buffer */
625 msg = MNEW(char, msglen);
627 /* print message into allocated buffer */
630 utf_copy_classname(msg, c->name);
634 va_start(ap, message);
635 vsprintf(msg + strlen(msg), message, ap);
641 o = new_exception_message(string_java_lang_ClassFormatError, msg);
643 MFREE(msg, char, msglen);
649 /* exceptions_throw_classformaterror *******************************************
651 Generate a java.lang.ClassFormatError for the VM system and throw it.
654 c............the class in which the error was found
655 message......UTF-8 format string
658 an exception pointer (in any case -- either it is the newly created
659 exception, or an exception thrown while trying to create it).
661 *******************************************************************************/
663 void exceptions_throw_classformaterror(classinfo *c, const char *message, ...)
667 va_start(ap, message);
668 *exceptionptr = new_classformaterror(c, message, ap);
673 /* new_classnotfoundexception **************************************************
675 Generates a java.lang.ClassNotFoundException for the classloader.
678 name.........name of the class not found as a utf *
681 an exception pointer (in any case -- either it is the newly created
682 exception, or an exception thrown while trying to create it).
684 *******************************************************************************/
686 java_objectheader *new_classnotfoundexception(utf *name)
688 java_objectheader *o;
691 s = javastring_new(name);
693 return *exceptionptr;
695 o = native_new_and_init_string(class_java_lang_ClassNotFoundException, s);
698 return *exceptionptr;
704 /* new_noclassdeffounderror ****************************************************
706 Generates a java.lang.NoClassDefFoundError
709 name.........name of the class not found as a utf *
712 an exception pointer (in any case -- either it is the newly created
713 exception, or an exception thrown while trying to create it).
715 *******************************************************************************/
717 java_objectheader *new_noclassdeffounderror(utf *name)
719 java_objectheader *o;
722 s = javastring_new(name);
724 return *exceptionptr;
726 o = native_new_and_init_string(class_java_lang_NoClassDefFoundError, s);
729 return *exceptionptr;
735 /* classnotfoundexception_to_noclassdeffounderror ******************************
737 Check the *exceptionptr for a ClassNotFoundException. If it is one,
738 convert it to a NoClassDefFoundError.
740 *******************************************************************************/
742 void classnotfoundexception_to_noclassdeffounderror(void)
744 java_objectheader *xptr;
745 java_objectheader *cause;
749 cause = *exceptionptr;
751 /* convert ClassNotFoundException's to NoClassDefFoundError's */
753 if (builtin_instanceof(cause, class_java_lang_ClassNotFoundException)) {
754 /* clear exception, because we are calling jit code again */
756 *exceptionptr = NULL;
758 /* create new error */
761 new_exception_javastring(string_java_lang_NoClassDefFoundError,
762 ((java_lang_Throwable *) cause)->detailMessage);
764 /* we had an exception while creating the error */
769 /* set new exception */
771 *exceptionptr = xptr;
776 /* new_internalerror ***********************************************************
778 Generates a java.lang.InternalError for the VM.
781 message......UTF-8 message format string
784 an exception pointer (in any case -- either it is the newly created
785 exception, or an exception thrown while trying to create it).
787 *******************************************************************************/
789 java_objectheader *new_internalerror(const char *message, ...)
791 java_objectheader *o;
796 /* calculate exception message length */
798 va_start(ap, message);
799 msglen = get_variable_message_length(message, ap);
802 /* allocate memory */
804 msg = MNEW(char, msglen);
806 /* generate message */
808 va_start(ap, message);
809 vsprintf(msg, message, ap);
812 /* create exception object */
814 o = new_exception_message(string_java_lang_InternalError, msg);
818 MFREE(msg, char, msglen);
824 /* exceptions_throw_internalerror **********************************************
826 Generates a java.lang.InternalError for the VM.
829 message......UTF-8 message format string
831 *******************************************************************************/
833 void exceptions_throw_internalerror(const char *message, ...)
837 va_start(ap, message);
838 *exceptionptr = new_internalerror(message, ap);
843 /* exceptions_new_linkageerror *************************************************
845 Generates a java.lang.LinkageError with an error message.
848 message......UTF-8 message
849 c............class related to the error. If this is != NULL
850 the name of c is appended to the error message.
853 an exception pointer (in any case -- either it is the newly created
854 exception, or an exception thrown while trying to create it).
856 *******************************************************************************/
858 java_objectheader *exceptions_new_linkageerror(const char *message,
861 java_objectheader *o;
865 /* calculate exception message length */
867 msglen = strlen(message) + 1;
869 msglen += utf_bytes(c->name);
872 /* allocate memory */
874 msg = MNEW(char, msglen);
876 /* generate message */
880 utf_cat_classname(msg, c->name);
883 o = native_new_and_init_string(class_java_lang_LinkageError,
884 javastring_new_from_utf_string(msg));
888 MFREE(msg, char, msglen);
891 return *exceptionptr;
897 /* exceptions_new_nosuchmethoderror ********************************************
899 Generates a java.lang.NoSuchMethodError with an error message.
902 c............class in which the method was not found
903 name.........name of the method
904 desc.........descriptor of the method
907 an exception pointer (in any case -- either it is the newly created
908 exception, or an exception thrown while trying to create it).
910 *******************************************************************************/
912 #if defined(ENABLE_JAVASE)
913 java_objectheader *exceptions_new_nosuchmethoderror(classinfo *c,
914 utf *name, utf *desc)
916 java_objectheader *o;
920 /* calculate exception message length */
922 msglen = utf_bytes(c->name) + strlen(".") + utf_bytes(name) +
923 utf_bytes(desc) + strlen("0");
925 /* allocate memory */
927 msg = MNEW(char, msglen);
929 /* generate message */
931 utf_copy_classname(msg, c->name);
936 o = native_new_and_init_string(class_java_lang_NoSuchMethodError,
937 javastring_new_from_utf_string(msg));
941 MFREE(msg, char, msglen);
944 return *exceptionptr;
951 /* exceptions_throw_nosuchmethoderror ******************************************
953 Generates a java.lang.NoSuchMethodError with an error message.
956 c............class in which the method was not found
957 name.........name of the method
958 desc.........descriptor of the method
960 *******************************************************************************/
962 #if defined(ENABLE_JAVASE)
963 void exceptions_throw_nosuchmethoderror(classinfo *c, utf *name, utf *desc)
965 *exceptionptr = exceptions_new_nosuchmethoderror(c, name, desc);
970 /* new_unsupportedclassversionerror ********************************************
972 Generate a java.lang.UnsupportedClassVersionError for the classloader
975 c............class in which the method was not found
976 message......UTF-8 format string
979 an exception pointer (in any case -- either it is the newly created
980 exception, or an exception thrown while trying to create it).
982 *******************************************************************************/
984 java_objectheader *new_unsupportedclassversionerror(classinfo *c, const char *message, ...)
986 java_objectheader *o;
991 /* calculate exception message length */
993 msglen = utf_bytes(c->name) + strlen(" (") + strlen(")") + strlen("0");
995 va_start(ap, message);
996 msglen += get_variable_message_length(message, ap);
999 /* allocate memory */
1001 msg = MNEW(char, msglen);
1003 /* generate message */
1005 utf_copy_classname(msg, c->name);
1008 va_start(ap, message);
1009 vsprintf(msg + strlen(msg), message, ap);
1014 /* create exception object */
1016 o = new_exception_message(string_java_lang_UnsupportedClassVersionError,
1021 MFREE(msg, char, msglen);
1027 /* exceptions_new_verifyerror **************************************************
1029 Generates a java.lang.VerifyError for the JIT compiler.
1032 m............method in which the error was found
1033 message......UTF-8 format string
1036 an exception pointer (in any case -- either it is the newly created
1037 exception, or an exception thrown while trying to create it).
1039 *******************************************************************************/
1041 java_objectheader *exceptions_new_verifyerror(methodinfo *m,
1042 const char *message, ...)
1044 java_objectheader *o;
1049 useinlining = false; /* at least until sure inlining works with exceptions*/
1051 /* calculate exception message length */
1056 msglen = strlen("(class: ") + utf_bytes(m->class->name) +
1057 strlen(", method: ") + utf_bytes(m->name) +
1058 strlen(" signature: ") + utf_bytes(m->descriptor) +
1059 strlen(") ") + strlen("0");
1061 va_start(ap, message);
1062 msglen += get_variable_message_length(message, ap);
1065 /* allocate memory */
1067 msg = MNEW(char, msglen);
1069 /* generate message */
1072 strcpy(msg, "(class: ");
1073 utf_cat_classname(msg, m->class->name);
1074 strcat(msg, ", method: ");
1075 utf_cat(msg, m->name);
1076 strcat(msg, " signature: ");
1077 utf_cat(msg, m->descriptor);
1081 va_start(ap, message);
1082 vsprintf(msg + strlen(msg), message, ap);
1085 /* create exception object */
1087 o = new_exception_message(string_java_lang_VerifyError, msg);
1091 MFREE(msg, char, msglen);
1097 /* exceptions_throw_verifyerror ************************************************
1099 Throws a java.lang.VerifyError for the VM system.
1101 *******************************************************************************/
1103 void exceptions_throw_verifyerror(methodinfo *m, const char *message, ...)
1105 *exceptionptr = exceptions_new_verifyerror(m, message);
1109 /* exceptions_throw_verifyerror_for_stack **************************************
1111 throws a java.lang.VerifyError for an invalid stack slot type
1114 m............method in which the error was found
1115 type.........the expected type
1118 an exception pointer (in any case -- either it is the newly created
1119 exception, or an exception thrown while trying to create it).
1121 *******************************************************************************/
1123 void exceptions_throw_verifyerror_for_stack(methodinfo *m,int type)
1125 java_objectheader *o;
1130 /* calculate exception message length */
1135 msglen = strlen("(class: ") + utf_bytes(m->class->name) +
1136 strlen(", method: ") + utf_bytes(m->name) +
1137 strlen(" signature: ") + utf_bytes(m->descriptor) +
1138 strlen(") Expecting to find longest-------typename on stack")
1141 /* allocate memory */
1143 msg = MNEW(char, msglen);
1145 /* generate message */
1148 strcpy(msg, "(class: ");
1149 utf_cat_classname(msg, m->class->name);
1150 strcat(msg, ", method: ");
1151 utf_cat(msg, m->name);
1152 strcat(msg, " signature: ");
1153 utf_cat(msg, m->descriptor);
1160 strcat(msg,"Expecting to find ");
1162 case TYPE_INT: typename = "integer"; break;
1163 case TYPE_LNG: typename = "long"; break;
1164 case TYPE_FLT: typename = "float"; break;
1165 case TYPE_DBL: typename = "double"; break;
1166 case TYPE_ADR: typename = "object/array"; break;
1167 case TYPE_RET: typename = "returnAddress"; break;
1168 default: typename = "<INVALID>"; assert(0); break;
1170 strcat(msg, typename);
1171 strcat(msg, " on stack");
1173 /* create exception object */
1175 o = new_exception_message(string_java_lang_VerifyError, msg);
1179 MFREE(msg, char, msglen);
1185 /* exceptions_new_virtualmachineerror ******************************************
1187 Generates a java.lang.VirtualMachineError for the VM system.
1189 *******************************************************************************/
1191 java_objectheader *exceptions_new_virtualmachineerror(void)
1193 java_objectheader *e;
1195 e = native_new_and_init(class_java_lang_VirtualMachineError);
1198 return *exceptionptr;
1204 /* exceptions_throw_virtualmachineerror ****************************************
1206 Throws a java.lang.VirtualMachineError for the VM system.
1208 *******************************************************************************/
1210 void exceptions_throw_virtualmachineerror(void)
1212 *exceptionptr = exceptions_new_virtualmachineerror();
1216 /* new_arithmeticexception *****************************************************
1218 Generates a java.lang.ArithmeticException for the jit compiler.
1220 *******************************************************************************/
1222 java_objectheader *new_arithmeticexception(void)
1224 java_objectheader *e;
1226 e = new_exception_message(string_java_lang_ArithmeticException,
1227 string_java_lang_ArithmeticException_message);
1230 return *exceptionptr;
1236 /* exceptions_new_arrayindexoutofboundsexception *******************************
1238 Generates a java.lang.ArrayIndexOutOfBoundsException for the VM
1241 *******************************************************************************/
1243 java_objectheader *new_arrayindexoutofboundsexception(s4 index)
1245 java_objectheader *e;
1247 java_objectheader *o;
1248 java_lang_String *s;
1250 /* convert the index into a String, like Sun does */
1252 m = class_resolveclassmethod(class_java_lang_String,
1253 utf_new_char("valueOf"),
1254 utf_new_char("(I)Ljava/lang/String;"),
1255 class_java_lang_Object,
1259 return *exceptionptr;
1261 o = vm_call_method(m, NULL, index);
1263 s = (java_lang_String *) o;
1266 return *exceptionptr;
1268 e = new_exception_javastring(string_java_lang_ArrayIndexOutOfBoundsException,
1272 return *exceptionptr;
1278 /* exceptions_throw_arrayindexoutofboundsexception *****************************
1280 Generates a java.lang.ArrayIndexOutOfBoundsException for the VM
1283 *******************************************************************************/
1285 void exceptions_throw_arrayindexoutofboundsexception(void)
1287 java_objectheader *e;
1289 e = new_exception(string_java_lang_ArrayIndexOutOfBoundsException);
1298 /* exceptions_new_arraystoreexception ******************************************
1300 Generates a java.lang.ArrayStoreException for the VM compiler.
1302 *******************************************************************************/
1304 java_objectheader *exceptions_new_arraystoreexception(void)
1306 java_objectheader *e;
1308 e = new_exception(string_java_lang_ArrayStoreException);
1309 /* e = native_new_and_init(class_java_lang_ArrayStoreException); */
1312 return *exceptionptr;
1318 /* exceptions_throw_arraystoreexception ****************************************
1320 Generates a java.lang.ArrayStoreException for the VM system and
1321 throw it in the VM system.
1323 *******************************************************************************/
1325 void exceptions_throw_arraystoreexception(void)
1327 *exceptionptr = exceptions_new_arraystoreexception();
1331 /* exceptions_new_classcastexception *******************************************
1333 Generates a java.lang.ClassCastException for the JIT compiler.
1335 *******************************************************************************/
1337 java_objectheader *exceptions_new_classcastexception(java_objectheader *o)
1339 java_objectheader *e;
1341 java_lang_String *s;
1343 classname = o->vftbl->class->name;
1345 s = javastring_new(classname);
1347 e = native_new_and_init_string(class_java_lang_ClassCastException, s);
1350 return *exceptionptr;
1356 /* exceptions_new_illegalargumentexception *************************************
1358 Generates a java.lang.IllegalArgumentException for the VM system.
1360 *******************************************************************************/
1362 java_objectheader *new_illegalargumentexception(void)
1364 java_objectheader *e;
1366 e = native_new_and_init(class_java_lang_IllegalArgumentException);
1369 return *exceptionptr;
1375 /* exceptions_throw_illegalargumentexception ***********************************
1377 Generates a java.lang.IllegalArgumentException for the VM system
1378 and throw it in the VM system.
1380 *******************************************************************************/
1382 void exceptions_throw_illegalargumentexception(void)
1384 *exceptionptr = new_illegalargumentexception();
1388 /* exceptions_new_illegalmonitorstateexception *********************************
1390 Generates a java.lang.IllegalMonitorStateException for the VM
1393 *******************************************************************************/
1395 java_objectheader *exceptions_new_illegalmonitorstateexception(void)
1397 java_objectheader *e;
1399 e = native_new_and_init(class_java_lang_IllegalMonitorStateException);
1402 return *exceptionptr;
1408 /* exceptions_throw_illegalmonitorstateexception *******************************
1410 Generates a java.lang.IllegalMonitorStateException for the VM
1411 system and throw it in the VM system.
1413 *******************************************************************************/
1415 void exceptions_throw_illegalmonitorstateexception(void)
1417 *exceptionptr = exceptions_new_illegalmonitorstateexception();
1421 /* exceptions_new_negativearraysizeexception ***********************************
1423 Generates a java.lang.NegativeArraySizeException for the VM system.
1425 *******************************************************************************/
1427 java_objectheader *new_negativearraysizeexception(void)
1429 java_objectheader *e;
1431 e = new_exception(string_java_lang_NegativeArraySizeException);
1434 return *exceptionptr;
1440 /* exceptions_throw_negativearraysizeexception *********************************
1442 Generates a java.lang.NegativeArraySizeException for the VM system.
1444 *******************************************************************************/
1446 void exceptions_throw_negativearraysizeexception(void)
1448 *exceptionptr = new_negativearraysizeexception();
1452 /* exceptions_new_nullpointerexception *****************************************
1454 Generates a java.lang.NullPointerException for the VM system.
1456 *******************************************************************************/
1458 java_objectheader *exceptions_new_nullpointerexception(void)
1460 java_objectheader *e;
1462 e = native_new_and_init(class_java_lang_NullPointerException);
1465 return *exceptionptr;
1471 /* exceptions_throw_nullpointerexception ***************************************
1473 Generates a java.lang.NullPointerException for the VM system and
1474 throw it in the VM system.
1476 *******************************************************************************/
1478 void exceptions_throw_nullpointerexception(void)
1480 *exceptionptr = exceptions_new_nullpointerexception();
1484 /* exceptions_new_stringindexoutofboundsexception ******************************
1486 Generates a java.lang.StringIndexOutOfBoundsException for the VM
1489 *******************************************************************************/
1491 java_objectheader *exceptions_new_stringindexoutofboundsexception(void)
1493 java_objectheader *e;
1495 e = new_exception(string_java_lang_StringIndexOutOfBoundsException);
1498 return *exceptionptr;
1504 /* exceptions_throw_stringindexoutofboundsexception ****************************
1506 Throws a java.lang.StringIndexOutOfBoundsException for the VM
1509 *******************************************************************************/
1511 void exceptions_throw_stringindexoutofboundsexception(void)
1513 *exceptionptr = exceptions_new_stringindexoutofboundsexception();
1517 /* exceptions_get_and_clear_exception ******************************************
1519 Gets the exception pointer of the current thread and clears it.
1520 This function may return NULL.
1522 *******************************************************************************/
1524 java_objectheader *exceptions_get_and_clear_exception(void)
1526 java_objectheader **p;
1527 java_objectheader *e;
1529 /* get the pointer of the exception pointer */
1533 /* get the exception */
1537 /* and clear the exception */
1541 /* return the exception */
1547 /* exceptions_handle_exception *************************************************
1549 Try to find an exception handler for the given exception and return it.
1550 If no handler is found, exit the monitor of the method (if any)
1554 xptr.........the exception object
1555 xpc..........PC of where the exception was thrown
1556 pv...........Procedure Value of the current method
1557 sp...........current stack pointer
1560 the address of the first matching exception handler, or
1561 NULL if no handler was found
1563 *******************************************************************************/
1565 #if defined(ENABLE_JIT)
1566 u1 *exceptions_handle_exception(java_objectheader *xptr, u1 *xpc, u1 *pv, u1 *sp)
1571 dseg_exception_entry *ex;
1572 s4 exceptiontablelength;
1574 classref_or_classinfo cr;
1576 #if defined(ENABLE_THREADS)
1577 java_objectheader *o;
1580 /* get info from the method header */
1582 code = *((codeinfo **) (pv + CodeinfoPointer));
1583 issync = *((s4 *) (pv + IsSync));
1584 ex = (dseg_exception_entry *) (pv + ExTableStart);
1585 exceptiontablelength = *((s4 *) (pv + ExTableSize));
1587 /* Get the methodinfo pointer from the codeinfo pointer. For
1588 asm_vm_call_method the codeinfo pointer is NULL. */
1590 m = (code == NULL) ? NULL : code->m;
1592 #if !defined(NDEBUG)
1593 /* print exception trace */
1595 if (opt_verbose || opt_verbosecall || opt_verboseexception)
1596 builtin_trace_exception(xptr, m, xpc, 1);
1599 for (i = 0; i < exceptiontablelength; i++) {
1600 /* ATTENTION: keep this here, as we need to decrement the
1601 pointer before the loop executes! */
1605 /* If the start and end PC is NULL, this means we have the
1606 special case of asm_vm_call_method. So, just return the
1607 proper exception handler. */
1609 if ((ex->startpc == NULL) && (ex->endpc == NULL))
1610 return (u1 *) (ptrint) &asm_vm_call_method_exception_handler;
1612 /* is the xpc is the current catch range */
1614 if ((ex->startpc <= xpc) && (xpc < ex->endpc)) {
1617 /* NULL catches everything */
1619 if (cr.any == NULL) {
1620 #if !defined(NDEBUG)
1621 /* Print stacktrace of exception when caught. */
1623 if (opt_verboseexception) {
1624 exceptions_print_exception(xptr);
1625 stacktrace_print_trace(xptr);
1629 return ex->handlerpc;
1632 /* resolve or load/link the exception class */
1634 if (IS_CLASSREF(cr)) {
1635 /* The exception class reference is unresolved. */
1636 /* We have to do _eager_ resolving here. While the class of */
1637 /* the exception object is guaranteed to be loaded, it may */
1638 /* well have been loaded by a different loader than the */
1639 /* defining loader of m's class, which is the one we must */
1640 /* use to resolve the catch class. Thus lazy resolving */
1641 /* might fail, even if the result of the resolution would */
1642 /* be an already loaded class. */
1644 c = resolve_classref_eager(cr.ref);
1647 /* Exception resolving the exception class, argh! */
1651 /* Ok, we resolved it. Enter it in the table, so we don't */
1652 /* have to do this again. */
1653 /* XXX this write should be atomic. Is it? */
1655 ex->catchtype.cls = c;
1659 /* XXX I don't think this case can ever happen. -Edwin */
1660 if (!(c->state & CLASS_LOADED))
1661 /* use the methods' classloader */
1662 if (!load_class_from_classloader(c->name,
1663 m->class->classloader))
1666 /* XXX I think, if it is not linked, we can be sure that */
1667 /* the exception object is no (indirect) instance of it, no? */
1669 if (!(c->state & CLASS_LINKED))
1674 /* is the thrown exception an instance of the catch class? */
1676 if (builtin_instanceof(xptr, c)) {
1677 #if !defined(NDEBUG)
1678 /* Print stacktrace of exception when caught. */
1680 if (opt_verboseexception) {
1681 exceptions_print_exception(xptr);
1682 stacktrace_print_trace(xptr);
1686 return ex->handlerpc;
1691 #if defined(ENABLE_THREADS)
1692 /* is this method synchronized? */
1695 /* get synchronization object */
1697 # if defined(__MIPS__) && (SIZEOF_VOID_P == 4)
1698 /* XXX change this if we ever want to use 4-byte stackslots */
1699 o = *((java_objectheader **) (sp + issync - 8));
1701 o = *((java_objectheader **) (sp + issync - SIZEOF_VOID_P));
1706 lock_monitor_exit(o);
1710 /* none of the exceptions catch this one */
1714 #endif /* defined(ENABLE_JIT) */
1717 /* exceptions_print_exception **************************************************
1719 Prints an exception, the detail message and the cause, if
1720 available, with CACAO internal functions to stdout.
1722 *******************************************************************************/
1724 void exceptions_print_exception(java_objectheader *xptr)
1726 java_lang_Throwable *t;
1727 #if defined(ENABLE_JAVASE)
1728 java_lang_Throwable *cause;
1732 t = (java_lang_Throwable *) xptr;
1739 #if defined(ENABLE_JAVASE)
1743 /* print the root exception */
1745 utf_display_printable_ascii_classname(t->header.vftbl->class->name);
1747 if (t->detailMessage != NULL) {
1748 u = javastring_toutf(t->detailMessage, false);
1751 utf_display_printable_ascii(u);
1756 #if defined(ENABLE_JAVASE)
1757 /* print the cause if available */
1759 if ((cause != NULL) && (cause != t)) {
1760 printf("Caused by: ");
1761 utf_display_printable_ascii_classname(cause->header.vftbl->class->name);
1763 if (cause->detailMessage) {
1764 u = javastring_toutf(cause->detailMessage, false);
1767 utf_display_printable_ascii(u);
1777 * These are local overrides for various environment variables in Emacs.
1778 * Please do not remove this and leave it at the end of the file, where
1779 * Emacs will automagically detect them.
1780 * ---------------------------------------------------------------------
1783 * indent-tabs-mode: t
1787 * vim:noexpandtab:sw=4:ts=4: