1 /* src/vm/exceptions.c - exception related functions
3 Copyright (C) 1996-2005, 2006, 2007 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 $Id: exceptions.c 7587 2007-03-28 13:29:09Z twisti $
39 #include "mm/memory.h"
41 #include "native/jni.h"
42 #include "native/native.h"
43 #include "native/include/java_lang_String.h"
44 #include "native/include/java_lang_Throwable.h"
46 #if defined(ENABLE_THREADS)
47 # include "threads/native/threads.h"
49 # include "threads/none/threads.h"
52 #include "toolbox/logging.h"
53 #include "toolbox/util.h"
55 #include "vm/builtin.h"
56 #include "vm/exceptions.h"
57 #include "vm/global.h"
58 #include "vm/stringlocal.h"
61 #include "vm/jit/asmpart.h"
62 #include "vm/jit/jit.h"
63 #include "vm/jit/methodheader.h"
64 #include "vm/jit/stacktrace.h"
66 #include "vmcore/class.h"
67 #include "vmcore/loader.h"
68 #include "vmcore/options.h"
71 /* for raising exceptions from native methods *********************************/
73 #if !defined(ENABLE_THREADS)
74 java_objectheader *_no_threads_exceptionptr = NULL;
78 /* init_system_exceptions ******************************************************
80 Load and link exceptions used in the system.
82 *******************************************************************************/
84 bool exceptions_init(void)
86 /* java/lang/Throwable */
88 if (!(class_java_lang_Throwable =
89 load_class_bootstrap(utf_java_lang_Throwable)) ||
90 !link_class(class_java_lang_Throwable))
95 if (!(class_java_lang_Error = load_class_bootstrap(utf_java_lang_Error)) ||
96 !link_class(class_java_lang_Error))
99 #if defined(ENABLE_JAVASE)
100 /* java/lang/LinkageError */
102 if (!(class_java_lang_LinkageError =
103 load_class_bootstrap(utf_java_lang_LinkageError)) ||
104 !link_class(class_java_lang_LinkageError))
108 /* java/lang/NoClassDefFoundError */
110 if (!(class_java_lang_NoClassDefFoundError =
111 load_class_bootstrap(utf_java_lang_NoClassDefFoundError)) ||
112 !link_class(class_java_lang_NoClassDefFoundError))
115 /* java/lang/OutOfMemoryError */
117 if (!(class_java_lang_OutOfMemoryError =
118 load_class_bootstrap(utf_java_lang_OutOfMemoryError)) ||
119 !link_class(class_java_lang_OutOfMemoryError))
122 /* java/lang/VirtualMachineError */
124 if (!(class_java_lang_VirtualMachineError =
125 load_class_bootstrap(utf_java_lang_VirtualMachineError)) ||
126 !link_class(class_java_lang_VirtualMachineError))
130 /* java/lang/Exception */
132 if (!(class_java_lang_Exception =
133 load_class_bootstrap(utf_java_lang_Exception)) ||
134 !link_class(class_java_lang_Exception))
137 /* java/lang/ClassCastException */
139 if (!(class_java_lang_ClassCastException =
140 load_class_bootstrap(utf_java_lang_ClassCastException)) ||
141 !link_class(class_java_lang_ClassCastException))
144 /* java/lang/ClassNotFoundException */
146 if (!(class_java_lang_ClassNotFoundException =
147 load_class_bootstrap(utf_java_lang_ClassNotFoundException)) ||
148 !link_class(class_java_lang_ClassNotFoundException))
151 /* java/lang/NullPointerException */
153 if (!(class_java_lang_NullPointerException =
154 load_class_bootstrap(utf_java_lang_NullPointerException)) ||
155 !link_class(class_java_lang_NullPointerException))
159 #if defined(WITH_CLASSPATH_GNU)
160 /* java/lang/VMThrowable */
162 if (!(class_java_lang_VMThrowable =
163 load_class_bootstrap(utf_java_lang_VMThrowable)) ||
164 !link_class(class_java_lang_VMThrowable))
172 /* exceptions_new_class ********************************************************
174 Creates an exception object from the given class and initalizes it.
177 class....class pointer
179 *******************************************************************************/
181 static java_objectheader *exceptions_new_class(classinfo *c)
183 java_objectheader *o;
185 o = native_new_and_init(c);
188 return *exceptionptr;
194 /* exceptions_new_utf **********************************************************
196 Creates an exception object with the given name and initalizes it.
199 classname....class name in UTF-8
201 *******************************************************************************/
203 static java_objectheader *exceptions_new_utf(utf *classname)
206 java_objectheader *o;
208 c = load_class_bootstrap(classname);
211 return *exceptionptr;
213 o = exceptions_new_class(c);
219 /* exceptions_throw_class ******************************************************
221 Creates an exception object from the given class, initalizes and
225 class....class pointer
227 *******************************************************************************/
229 static void exceptions_throw_class(classinfo *c)
231 java_objectheader *o;
233 o = exceptions_new_class(c);
242 /* exceptions_throw_utf ********************************************************
244 Creates an exception object with the given name, initalizes and
248 classname....class name in UTF-8
250 *******************************************************************************/
252 static void exceptions_throw_utf(utf *classname)
256 c = load_class_bootstrap(classname);
261 exceptions_throw_class(c);
265 /* exceptions_throw_utf_throwable **********************************************
267 Creates an exception object with the given name and initalizes it
268 with the given java/lang/Throwable exception.
271 classname....class name in UTF-8
272 cause........the given Throwable
274 *******************************************************************************/
276 static void exceptions_throw_utf_throwable(utf *classname,
277 java_objectheader *cause)
279 java_objectheader *o;
282 c = load_class_bootstrap(classname);
287 o = native_new_and_init_throwable(c, cause);
296 /* exceptions_new_utf_javastring ***********************************************
298 Creates an exception object with the given name and initalizes it
299 with the given java/lang/String message.
302 classname....class name in UTF-8
303 message......the message as a java.lang.String
306 an exception pointer (in any case -- either it is the newly created
307 exception, or an exception thrown while trying to create it).
309 *******************************************************************************/
311 static java_objectheader *exceptions_new_utf_javastring(utf *classname,
312 java_objectheader *message)
314 java_objectheader *o;
317 c = load_class_bootstrap(classname);
320 return *exceptionptr;
322 o = native_new_and_init_string(c, message);
325 return *exceptionptr;
331 /* exceptions_new_class_utf ****************************************************
333 Creates an exception object of the given class and initalizes it.
336 c..........class pointer
337 message....the message as UTF-8 string
339 *******************************************************************************/
341 static java_objectheader *exceptions_new_class_utf(classinfo *c, utf *message)
343 java_objectheader *o;
344 java_objectheader *s;
346 s = javastring_new(message);
349 return *exceptionptr;
351 o = native_new_and_init_string(c, s);
354 return *exceptionptr;
360 /* exceptions_new_utf_utf ******************************************************
362 Creates an exception object with the given name and initalizes it
363 with the given utf message.
366 classname....class name in UTF-8
367 message......the message as an utf *
370 an exception pointer (in any case -- either it is the newly created
371 exception, or an exception thrown while trying to create it).
373 *******************************************************************************/
375 static java_objectheader *exceptions_new_utf_utf(utf *classname, utf *message)
378 java_objectheader *o;
380 c = load_class_bootstrap(classname);
383 return *exceptionptr;
385 o = exceptions_new_class_utf(c, message);
391 /* new_exception_message *******************************************************
393 Creates an exception object with the given name and initalizes it
394 with the given char message.
397 classname....class name in UTF-8
398 message......message in UTF-8
401 an exception pointer (in any case -- either it is the newly created
402 exception, or an exception thrown while trying to create it).
404 *******************************************************************************/
406 static java_objectheader *new_exception_message(const char *classname,
409 java_objectheader *o;
410 java_objectheader *s;
412 s = javastring_new_from_utf_string(message);
415 return *exceptionptr;
417 o = exceptions_new_utf_javastring(classname, s);
423 /* exceptions_throw_class_utf **************************************************
425 Creates an exception object of the given class, initalizes and
426 throws it with the given utf message.
429 c..........class pointer
430 message....the message as an UTF-8
432 *******************************************************************************/
434 static void exceptions_throw_class_utf(classinfo *c, utf *message)
436 *exceptionptr = exceptions_new_class_utf(c, message);
440 /* exceptions_throw_utf_utf ****************************************************
442 Creates an exception object with the given name, initalizes and
443 throws it with the given utf message.
446 classname....class name in UTF-8
447 message......the message as an utf *
449 *******************************************************************************/
451 static void exceptions_throw_utf_utf(utf *classname, utf *message)
453 *exceptionptr = exceptions_new_utf_utf(classname, message);
457 /* new_exception_int ***********************************************************
459 Creates an exception object with the given name and initalizes it
460 with the given int value.
463 classname....class name in UTF-8
464 i............the integer
467 an exception pointer (in any case -- either it is the newly created
468 exception, or an exception thrown while trying to create it).
470 *******************************************************************************/
472 java_objectheader *new_exception_int(const char *classname, s4 i)
474 java_objectheader *o;
477 if (!(c = load_class_bootstrap(utf_new_char(classname))))
478 return *exceptionptr;
480 o = native_new_and_init_int(c, i);
483 return *exceptionptr;
489 /* exceptions_new_abstractmethoderror ****************************************
491 Generates a java.lang.AbstractMethodError for the VM.
493 *******************************************************************************/
495 java_objectheader *exceptions_new_abstractmethoderror(void)
497 java_objectheader *o;
499 o = exceptions_new_utf(utf_java_lang_AbstractMethodError);
505 /* exceptions_new_error ********************************************************
507 Generates a java.lang.Error for the VM.
509 *******************************************************************************/
511 #if defined(ENABLE_JAVAME_CLDC1_1)
512 static java_objectheader *exceptions_new_error(utf *message)
514 java_objectheader *o;
516 o = exceptions_new_class_utf(class_java_lang_Error, message);
523 /* exceptions_asm_new_abstractmethoderror **************************************
525 Generates a java.lang.AbstractMethodError for
526 asm_abstractmethoderror.
528 *******************************************************************************/
530 java_objectheader *exceptions_asm_new_abstractmethoderror(u1 *sp, u1 *ra)
533 java_objectheader *e;
535 /* create the stackframeinfo (XPC is equal to RA) */
537 stacktrace_create_extern_stackframeinfo(&sfi, NULL, sp, ra, ra);
539 /* create the exception */
541 #if defined(ENABLE_JAVASE)
542 e = exceptions_new_abstractmethoderror();
544 e = exceptions_new_error(utf_java_lang_AbstractMethodError);
547 /* remove the stackframeinfo */
549 stacktrace_remove_stackframeinfo(&sfi);
555 /* exceptions_new_arraystoreexception ******************************************
557 Generates a java.lang.ArrayStoreException for the VM.
559 *******************************************************************************/
561 java_objectheader *exceptions_new_arraystoreexception(void)
563 java_objectheader *o;
565 o = exceptions_new_utf(utf_java_lang_ArrayStoreException);
571 /* exceptions_throw_abstractmethoderror ****************************************
573 Generates and throws a java.lang.AbstractMethodError for the VM.
575 *******************************************************************************/
577 void exceptions_throw_abstractmethoderror(void)
579 exceptions_throw_utf(utf_java_lang_AbstractMethodError);
583 /* exceptions_throw_classcircularityerror **************************************
585 Generates and throws a java.lang.ClassCircularityError for the
589 c............the class in which the error was found
591 *******************************************************************************/
593 void exceptions_throw_classcircularityerror(classinfo *c)
595 java_objectheader *o;
599 /* calculate message length */
601 msglen = utf_bytes(c->name) + strlen("0");
603 /* allocate a buffer */
605 msg = MNEW(char, msglen);
607 /* print message into allocated buffer */
609 utf_copy_classname(msg, c->name);
611 o = new_exception_message(utf_java_lang_ClassCircularityError, msg);
613 MFREE(msg, char, msglen);
622 /* exceptions_throw_classformaterror *******************************************
624 Generates and throws a java.lang.ClassFormatError for the VM.
627 c............the class in which the error was found
628 message......UTF-8 format string
630 *******************************************************************************/
632 void exceptions_throw_classformaterror(classinfo *c, const char *message, ...)
634 java_objectheader *o;
639 /* calculate message length */
644 msglen += utf_bytes(c->name) + strlen(" (");
646 va_start(ap, message);
647 msglen += get_variable_message_length(message, ap);
651 msglen += strlen(")");
653 msglen += strlen("0");
655 /* allocate a buffer */
657 msg = MNEW(char, msglen);
659 /* print message into allocated buffer */
662 utf_copy_classname(msg, c->name);
666 va_start(ap, message);
667 vsprintf(msg + strlen(msg), message, ap);
673 o = new_exception_message(utf_java_lang_ClassFormatError, msg);
675 MFREE(msg, char, msglen);
681 /* exceptions_throw_classnotfoundexception *************************************
683 Generates and throws a java.lang.ClassNotFoundException for the
687 name.........name of the class not found as a utf *
689 *******************************************************************************/
691 void exceptions_throw_classnotfoundexception(utf *name)
693 /* we use class here, as this one is rather frequent */
695 exceptions_throw_class_utf(class_java_lang_ClassNotFoundException, name);
699 /* exceptions_throw_noclassdeffounderror ***************************************
701 Generates and throws a java.lang.NoClassDefFoundError.
704 name.........name of the class not found as a utf *
706 *******************************************************************************/
708 void exceptions_throw_noclassdeffounderror(utf *name)
711 vm_abort("java.lang.NoClassDefFoundError: %s", name->text);
713 exceptions_throw_class_utf(class_java_lang_NoClassDefFoundError, name);
717 /* classnotfoundexception_to_noclassdeffounderror ******************************
719 Check the *exceptionptr for a ClassNotFoundException. If it is one,
720 convert it to a NoClassDefFoundError.
722 *******************************************************************************/
724 void classnotfoundexception_to_noclassdeffounderror(void)
726 java_objectheader *xptr;
727 java_objectheader *cause;
728 java_lang_Throwable *t;
733 cause = *exceptionptr;
735 /* convert ClassNotFoundException's to NoClassDefFoundError's */
737 if (builtin_instanceof(cause, class_java_lang_ClassNotFoundException)) {
738 /* clear exception, because we are calling jit code again */
740 *exceptionptr = NULL;
742 /* create new error */
744 t = (java_lang_Throwable *) cause;
745 s = t->detailMessage;
747 xptr = exceptions_new_utf_javastring(utf_java_lang_NoClassDefFoundError, s);
749 /* we had an exception while creating the error */
754 /* set new exception */
756 *exceptionptr = xptr;
761 /* exceptions_throw_exceptionininitializererror ********************************
763 Generates and throws a java.lang.ExceptionInInitializerError for
767 cause......cause exception object
769 *******************************************************************************/
771 void exceptions_throw_exceptionininitializererror(java_objectheader *cause)
773 exceptions_throw_utf_throwable(utf_java_lang_ExceptionInInitializerError,
778 /* exceptions_throw_incompatibleclasschangeerror *******************************
780 Generates and throws a java.lang.IncompatibleClassChangeError for
784 message......UTF-8 message format string
786 *******************************************************************************/
788 void exceptions_throw_incompatibleclasschangeerror(classinfo *c, const char *message)
790 java_objectheader *o;
794 /* calculate exception message length */
796 msglen = utf_bytes(c->name) + strlen(message) + strlen("0");
798 /* allocate memory */
800 msg = MNEW(char, msglen);
802 utf_copy_classname(msg, c->name);
803 strcat(msg, message);
805 o = native_new_and_init_string(utf_java_lang_IncompatibleClassChangeError,
806 javastring_new_from_utf_string(msg));
810 MFREE(msg, char, msglen);
819 /* exceptions_throw_instantiationerror *****************************************
821 Generates and throws a java.lang.InstantiationError for the VM.
823 *******************************************************************************/
825 void exceptions_throw_instantiationerror(classinfo *c)
827 exceptions_throw_utf_utf(utf_java_lang_InstantiationError, c->name);
831 /* exceptions_throw_internalerror **********************************************
833 Generates and throws a java.lang.InternalError for the VM.
836 message......UTF-8 message format string
838 *******************************************************************************/
840 void exceptions_throw_internalerror(const char *message, ...)
842 java_objectheader *o;
847 /* calculate exception message length */
849 va_start(ap, message);
850 msglen = get_variable_message_length(message, ap);
853 /* allocate memory */
855 msg = MNEW(char, msglen);
857 /* generate message */
859 va_start(ap, message);
860 vsprintf(msg, message, ap);
863 /* create exception object */
865 o = new_exception_message(utf_java_lang_InternalError, msg);
869 MFREE(msg, char, msglen);
878 /* exceptions_throw_linkageerror ***********************************************
880 Generates and throws java.lang.LinkageError with an error message.
883 message......UTF-8 message
884 c............class related to the error. If this is != NULL
885 the name of c is appended to the error message.
887 *******************************************************************************/
889 void exceptions_throw_linkageerror(const char *message, classinfo *c)
891 java_objectheader *o;
895 /* calculate exception message length */
897 msglen = strlen(message) + 1;
900 msglen += utf_bytes(c->name);
902 /* allocate memory */
904 msg = MNEW(char, msglen);
906 /* generate message */
911 utf_cat_classname(msg, c->name);
913 o = native_new_and_init_string(class_java_lang_LinkageError,
914 javastring_new_from_utf_string(msg));
918 MFREE(msg, char, msglen);
927 /* exceptions_throw_nosuchfielderror *******************************************
929 Generates and throws a java.lang.NoSuchFieldError with an error
933 c............class in which the field was not found
934 name.........name of the field
936 *******************************************************************************/
938 void exceptions_throw_nosuchfielderror(classinfo *c, utf *name)
944 /* calculate exception message length */
946 msglen = utf_bytes(c->name) + strlen(".") + utf_bytes(name) + strlen("0");
948 /* allocate memory */
950 msg = MNEW(char, msglen);
952 /* generate message */
954 utf_copy_classname(msg, c->name);
958 u = utf_new_char(msg);
962 MFREE(msg, char, msglen);
964 exceptions_throw_utf_utf(utf_java_lang_NoSuchFieldError, u);
968 /* exceptions_throw_nosuchmethoderror ******************************************
970 Generates and throws a java.lang.NoSuchMethodError with an error
974 c............class in which the method was not found
975 name.........name of the method
976 desc.........descriptor of the method
978 *******************************************************************************/
980 void exceptions_throw_nosuchmethoderror(classinfo *c, utf *name, utf *desc)
986 /* calculate exception message length */
988 msglen = utf_bytes(c->name) + strlen(".") + utf_bytes(name) +
989 utf_bytes(desc) + strlen("0");
991 /* allocate memory */
993 msg = MNEW(char, msglen);
995 /* generate message */
997 utf_copy_classname(msg, c->name);
1002 u = utf_new_char(msg);
1006 MFREE(msg, char, msglen);
1008 exceptions_throw_utf_utf(utf_java_lang_NoSuchMethodError, u);
1012 /* exceptions_throw_outofmemoryerror *******************************************
1014 Generates and throws an java.lang.OutOfMemoryError for the VM.
1016 *******************************************************************************/
1018 void exceptions_throw_outofmemoryerror(void)
1020 exceptions_throw_class(class_java_lang_OutOfMemoryError);
1024 /* exceptions_throw_unsatisfiedlinkerror ***************************************
1026 Generates and throws a java.lang.UnsatisfiedLinkError for the
1030 name......UTF-8 name string
1032 *******************************************************************************/
1034 void exceptions_throw_unsatisfiedlinkerror(utf *name)
1036 #if defined(ENABLE_JAVASE)
1037 exceptions_throw_utf_utf(utf_java_lang_UnsatisfiedLinkError, name);
1039 exceptions_throw_class_utf(class_java_lang_Error, name);
1044 /* exceptions_throw_unsupportedclassversionerror *******************************
1046 Generates and throws a java.lang.UnsupportedClassVersionError for
1050 c............class in which the method was not found
1051 message......UTF-8 format string
1053 *******************************************************************************/
1055 void exceptions_throw_unsupportedclassversionerror(classinfo *c, u4 ma, u4 mi)
1057 java_objectheader *o;
1061 /* calculate exception message length */
1064 utf_bytes(c->name) +
1065 strlen(" (Unsupported major.minor version 00.0)") +
1068 /* allocate memory */
1070 msg = MNEW(char, msglen);
1072 /* generate message */
1074 utf_copy_classname(msg, c->name);
1075 sprintf(msg + strlen(msg), " (Unsupported major.minor version %d.%d)",
1078 /* create exception object */
1080 o = new_exception_message(utf_java_lang_UnsupportedClassVersionError, msg);
1084 MFREE(msg, char, msglen);
1093 /* exceptions_throw_verifyerror ************************************************
1095 Generates and throws a java.lang.VerifyError for the JIT compiler.
1098 m............method in which the error was found
1099 message......UTF-8 format string
1101 *******************************************************************************/
1103 void exceptions_throw_verifyerror(methodinfo *m, const char *message, ...)
1105 java_objectheader *o;
1110 /* calculate exception message length */
1116 strlen("(class: ") + utf_bytes(m->class->name) +
1117 strlen(", method: ") + utf_bytes(m->name) +
1118 strlen(" signature: ") + utf_bytes(m->descriptor) +
1119 strlen(") ") + strlen("0");
1121 va_start(ap, message);
1122 msglen += get_variable_message_length(message, ap);
1125 /* allocate memory */
1127 msg = MNEW(char, msglen);
1129 /* generate message */
1132 strcpy(msg, "(class: ");
1133 utf_cat_classname(msg, m->class->name);
1134 strcat(msg, ", method: ");
1135 utf_cat(msg, m->name);
1136 strcat(msg, " signature: ");
1137 utf_cat(msg, m->descriptor);
1141 va_start(ap, message);
1142 vsprintf(msg + strlen(msg), message, ap);
1145 /* create exception object */
1147 o = new_exception_message(utf_java_lang_VerifyError, msg);
1151 MFREE(msg, char, msglen);
1157 /* exceptions_throw_verifyerror_for_stack **************************************
1159 throws a java.lang.VerifyError for an invalid stack slot type
1162 m............method in which the error was found
1163 type.........the expected type
1166 an exception pointer (in any case -- either it is the newly created
1167 exception, or an exception thrown while trying to create it).
1169 *******************************************************************************/
1171 void exceptions_throw_verifyerror_for_stack(methodinfo *m,int type)
1173 java_objectheader *o;
1178 /* calculate exception message length */
1183 msglen = strlen("(class: ") + utf_bytes(m->class->name) +
1184 strlen(", method: ") + utf_bytes(m->name) +
1185 strlen(" signature: ") + utf_bytes(m->descriptor) +
1186 strlen(") Expecting to find longest-------typename on stack")
1189 /* allocate memory */
1191 msg = MNEW(char, msglen);
1193 /* generate message */
1196 strcpy(msg, "(class: ");
1197 utf_cat_classname(msg, m->class->name);
1198 strcat(msg, ", method: ");
1199 utf_cat(msg, m->name);
1200 strcat(msg, " signature: ");
1201 utf_cat(msg, m->descriptor);
1208 strcat(msg,"Expecting to find ");
1210 case TYPE_INT: typename = "integer"; break;
1211 case TYPE_LNG: typename = "long"; break;
1212 case TYPE_FLT: typename = "float"; break;
1213 case TYPE_DBL: typename = "double"; break;
1214 case TYPE_ADR: typename = "object/array"; break;
1215 case TYPE_RET: typename = "returnAddress"; break;
1216 default: typename = "<INVALID>"; assert(0); break;
1218 strcat(msg, typename);
1219 strcat(msg, " on stack");
1221 /* create exception object */
1223 o = new_exception_message(utf_java_lang_VerifyError, msg);
1227 MFREE(msg, char, msglen);
1233 /* exceptions_new_arithmeticexception ******************************************
1235 Generates a java.lang.ArithmeticException for the JIT compiler.
1237 *******************************************************************************/
1239 java_objectheader *exceptions_new_arithmeticexception(void)
1241 java_objectheader *o;
1243 o = new_exception_message(utf_java_lang_ArithmeticException, "/ by zero");
1246 return *exceptionptr;
1252 /* exceptions_new_arrayindexoutofboundsexception *******************************
1254 Generates a java.lang.ArrayIndexOutOfBoundsException for the VM
1257 *******************************************************************************/
1259 java_objectheader *exceptions_new_arrayindexoutofboundsexception(s4 index)
1261 java_objectheader *o;
1263 java_objectheader *s;
1265 /* convert the index into a String, like Sun does */
1267 m = class_resolveclassmethod(class_java_lang_String,
1268 utf_new_char("valueOf"),
1269 utf_new_char("(I)Ljava/lang/String;"),
1270 class_java_lang_Object,
1274 return *exceptionptr;
1276 s = vm_call_method(m, NULL, index);
1279 return *exceptionptr;
1281 o = exceptions_new_utf_javastring(utf_java_lang_ArrayIndexOutOfBoundsException,
1285 return *exceptionptr;
1291 /* exceptions_throw_arrayindexoutofboundsexception *****************************
1293 Generates and throws a java.lang.ArrayIndexOutOfBoundsException for
1296 *******************************************************************************/
1298 void exceptions_throw_arrayindexoutofboundsexception(void)
1300 exceptions_throw_utf(utf_java_lang_ArrayIndexOutOfBoundsException);
1304 /* exceptions_throw_arraystoreexception ****************************************
1306 Generates and throws a java.lang.ArrayStoreException for the VM.
1308 *******************************************************************************/
1310 void exceptions_throw_arraystoreexception(void)
1312 exceptions_throw_utf(utf_java_lang_ArrayStoreException);
1313 /* e = native_new_and_init(class_java_lang_ArrayStoreException); */
1317 /* exceptions_new_classcastexception *******************************************
1319 Generates a java.lang.ClassCastException for the JIT compiler.
1321 *******************************************************************************/
1323 java_objectheader *exceptions_new_classcastexception(java_objectheader *o)
1325 java_objectheader *e;
1327 java_lang_String *s;
1329 classname = o->vftbl->class->name;
1331 s = javastring_new(classname);
1333 e = native_new_and_init_string(class_java_lang_ClassCastException, s);
1336 return *exceptionptr;
1342 /* exceptions_throw_clonenotsupportedexception *********************************
1344 Generates and throws a java.lang.CloneNotSupportedException for the
1347 *******************************************************************************/
1349 void exceptions_throw_clonenotsupportedexception(void)
1351 exceptions_throw_utf(utf_java_lang_CloneNotSupportedException);
1355 /* exceptions_throw_illegalaccessexception *************************************
1357 Generates and throws a java.lang.IllegalAccessException for the VM.
1359 *******************************************************************************/
1361 void exceptions_throw_illegalaccessexception(classinfo *c)
1363 /* XXX handle argument */
1365 exceptions_throw_utf(utf_java_lang_IllegalAccessException);
1369 /* exceptions_throw_illegalargumentexception ***********************************
1371 Generates and throws a java.lang.IllegalArgumentException for the
1374 *******************************************************************************/
1376 void exceptions_throw_illegalargumentexception(void)
1378 exceptions_throw_utf(utf_java_lang_IllegalArgumentException);
1382 /* exceptions_throw_illegalmonitorstateexception *******************************
1384 Generates and throws a java.lang.IllegalMonitorStateException for
1387 *******************************************************************************/
1389 void exceptions_throw_illegalmonitorstateexception(void)
1391 exceptions_throw_utf(utf_java_lang_IllegalMonitorStateException);
1395 /* exceptions_throw_instantiationexception *************************************
1397 Generates and throws a java.lang.InstantiationException for the VM.
1399 *******************************************************************************/
1401 void exceptions_throw_instantiationexception(classinfo *c)
1403 exceptions_throw_utf_utf(utf_java_lang_InstantiationException, c->name);
1407 /* exceptions_throw_interruptedexception ***************************************
1409 Generates and throws a java.lang.InterruptedException for the VM.
1411 *******************************************************************************/
1413 void exceptions_throw_interruptedexception(void)
1415 exceptions_throw_utf(utf_java_lang_InterruptedException);
1419 /* exceptions_throw_invocationtargetexception **********************************
1421 Generates and throws a java.lang.reflect.InvocationTargetException
1425 cause......cause exception object
1427 *******************************************************************************/
1429 void exceptions_throw_invocationtargetexception(java_objectheader *cause)
1431 exceptions_throw_utf_throwable(utf_java_lang_reflect_InvocationTargetException,
1436 /* exceptions_throw_negativearraysizeexception *********************************
1438 Generates and throws a java.lang.NegativeArraySizeException for the
1441 *******************************************************************************/
1443 void exceptions_throw_negativearraysizeexception(void)
1445 exceptions_throw_utf(utf_java_lang_NegativeArraySizeException);
1449 /* exceptions_new_nullpointerexception *****************************************
1451 Generates a java.lang.NullPointerException for the VM system.
1453 *******************************************************************************/
1455 java_objectheader *exceptions_new_nullpointerexception(void)
1457 java_objectheader *o;
1459 o = exceptions_new_class(class_java_lang_NullPointerException);
1465 /* exceptions_throw_nullpointerexception ***************************************
1467 Generates a java.lang.NullPointerException for the VM system and
1468 throw it in the VM system.
1470 *******************************************************************************/
1472 void exceptions_throw_nullpointerexception(void)
1474 exceptions_throw_class(class_java_lang_NullPointerException);
1478 /* exceptions_throw_stringindexoutofboundsexception ****************************
1480 Generates and throws a java.lang.StringIndexOutOfBoundsException
1483 *******************************************************************************/
1485 void exceptions_throw_stringindexoutofboundsexception(void)
1487 exceptions_throw_utf(utf_java_lang_StringIndexOutOfBoundsException);
1491 /* exceptions_get_exception ****************************************************
1493 Returns the current exception pointer of the current thread.
1495 *******************************************************************************/
1497 java_objectheader *exceptions_get_exception(void)
1499 /* return the exception */
1501 return *exceptionptr;
1505 /* exceptions_set_exception ****************************************************
1507 Sets the exception pointer of the current thread.
1509 *******************************************************************************/
1511 void exceptions_set_exception(java_objectheader *o)
1513 /* set the exception */
1519 /* exceptions_clear_exception **************************************************
1521 Clears the current exception pointer of the current thread.
1523 *******************************************************************************/
1525 void exceptions_clear_exception(void)
1527 /* and clear the exception */
1529 *exceptionptr = NULL;
1533 /* exceptions_get_and_clear_exception ******************************************
1535 Gets the exception pointer of the current thread and clears it.
1536 This function may return NULL.
1538 *******************************************************************************/
1540 java_objectheader *exceptions_get_and_clear_exception(void)
1542 java_objectheader **p;
1543 java_objectheader *e;
1545 /* get the pointer of the exception pointer */
1549 /* get the exception */
1553 /* and clear the exception */
1557 /* return the exception */
1563 /* exceptions_handle_exception *************************************************
1565 Try to find an exception handler for the given exception and return it.
1566 If no handler is found, exit the monitor of the method (if any)
1570 xptr.........the exception object
1571 xpc..........PC of where the exception was thrown
1572 pv...........Procedure Value of the current method
1573 sp...........current stack pointer
1576 the address of the first matching exception handler, or
1577 NULL if no handler was found
1579 *******************************************************************************/
1581 #if defined(ENABLE_JIT)
1582 u1 *exceptions_handle_exception(java_objectheader *xptr, u1 *xpc, u1 *pv, u1 *sp)
1587 dseg_exception_entry *ex;
1588 s4 exceptiontablelength;
1590 classref_or_classinfo cr;
1592 #if defined(ENABLE_THREADS)
1593 java_objectheader *o;
1597 /* Addresses are 31 bit integers */
1598 # define ADDR_MASK(x) (u1 *)((u4)(x) & 0x7FFFFFFF)
1600 # define ADDR_MASK(x) (x)
1603 xpc = ADDR_MASK(xpc);
1605 /* get info from the method header */
1607 code = *((codeinfo **) (pv + CodeinfoPointer));
1608 issync = *((s4 *) (pv + IsSync));
1609 ex = (dseg_exception_entry *) (pv + ExTableStart);
1610 exceptiontablelength = *((s4 *) (pv + ExTableSize));
1612 /* Get the methodinfo pointer from the codeinfo pointer. For
1613 asm_vm_call_method the codeinfo pointer is NULL. */
1615 m = (code == NULL) ? NULL : code->m;
1617 #if !defined(NDEBUG)
1618 /* print exception trace */
1620 if (opt_verbose || opt_verbosecall || opt_verboseexception)
1621 builtin_trace_exception(xptr, m, xpc, 1);
1624 for (i = 0; i < exceptiontablelength; i++) {
1625 /* ATTENTION: keep this here, as we need to decrement the
1626 pointer before the loop executes! */
1630 /* If the start and end PC is NULL, this means we have the
1631 special case of asm_vm_call_method. So, just return the
1632 proper exception handler. */
1634 if ((ex->startpc == NULL) && (ex->endpc == NULL))
1635 return (u1 *) (ptrint) &asm_vm_call_method_exception_handler;
1637 /* is the xpc is the current catch range */
1639 if ((ADDR_MASK(ex->startpc) <= xpc) && (xpc < ADDR_MASK(ex->endpc))) {
1642 /* NULL catches everything */
1644 if (cr.any == NULL) {
1645 #if !defined(NDEBUG)
1646 /* Print stacktrace of exception when caught. */
1648 if (opt_verboseexception) {
1649 exceptions_print_exception(xptr);
1650 stacktrace_print_trace(xptr);
1654 return ex->handlerpc;
1657 /* resolve or load/link the exception class */
1659 if (IS_CLASSREF(cr)) {
1660 /* The exception class reference is unresolved. */
1661 /* We have to do _eager_ resolving here. While the class of */
1662 /* the exception object is guaranteed to be loaded, it may */
1663 /* well have been loaded by a different loader than the */
1664 /* defining loader of m's class, which is the one we must */
1665 /* use to resolve the catch class. Thus lazy resolving */
1666 /* might fail, even if the result of the resolution would */
1667 /* be an already loaded class. */
1669 c = resolve_classref_eager(cr.ref);
1672 /* Exception resolving the exception class, argh! */
1676 /* Ok, we resolved it. Enter it in the table, so we don't */
1677 /* have to do this again. */
1678 /* XXX this write should be atomic. Is it? */
1680 ex->catchtype.cls = c;
1684 /* XXX I don't think this case can ever happen. -Edwin */
1685 if (!(c->state & CLASS_LOADED))
1686 /* use the methods' classloader */
1687 if (!load_class_from_classloader(c->name,
1688 m->class->classloader))
1691 /* XXX I think, if it is not linked, we can be sure that */
1692 /* the exception object is no (indirect) instance of it, no? */
1694 if (!(c->state & CLASS_LINKED))
1699 /* is the thrown exception an instance of the catch class? */
1701 if (builtin_instanceof(xptr, c)) {
1702 #if !defined(NDEBUG)
1703 /* Print stacktrace of exception when caught. */
1705 if (opt_verboseexception) {
1706 exceptions_print_exception(xptr);
1707 stacktrace_print_trace(xptr);
1711 return ex->handlerpc;
1716 #if defined(ENABLE_THREADS)
1717 /* is this method synchronized? */
1720 /* get synchronization object */
1722 # if defined(__MIPS__) && (SIZEOF_VOID_P == 4)
1723 /* XXX change this if we ever want to use 4-byte stackslots */
1724 o = *((java_objectheader **) (sp + issync - 8));
1726 o = *((java_objectheader **) (sp + issync - SIZEOF_VOID_P));
1731 lock_monitor_exit(o);
1735 /* none of the exceptions catch this one */
1739 #endif /* defined(ENABLE_JIT) */
1742 /* exceptions_print_exception **************************************************
1744 Prints an exception, the detail message and the cause, if
1745 available, with CACAO internal functions to stdout.
1747 *******************************************************************************/
1749 void exceptions_print_exception(java_objectheader *xptr)
1751 java_lang_Throwable *t;
1752 #if defined(ENABLE_JAVASE)
1753 java_lang_Throwable *cause;
1757 t = (java_lang_Throwable *) xptr;
1764 #if defined(ENABLE_JAVASE)
1768 /* print the root exception */
1770 utf_display_printable_ascii_classname(t->header.vftbl->class->name);
1772 if (t->detailMessage != NULL) {
1773 u = javastring_toutf(t->detailMessage, false);
1776 utf_display_printable_ascii(u);
1781 #if defined(ENABLE_JAVASE)
1782 /* print the cause if available */
1784 if ((cause != NULL) && (cause != t)) {
1785 printf("Caused by: ");
1786 utf_display_printable_ascii_classname(cause->header.vftbl->class->name);
1788 if (cause->detailMessage) {
1789 u = javastring_toutf(cause->detailMessage, false);
1792 utf_display_printable_ascii(u);
1801 /* exceptions_print_current_exception ******************************************
1803 Prints the current pending exception, the detail message and the
1804 cause, if available, with CACAO internal functions to stdout.
1806 *******************************************************************************/
1808 void exceptions_print_current_exception(void)
1810 java_objectheader *xptr;
1812 xptr = *exceptionptr;
1814 exceptions_print_exception(xptr);
1818 /* exceptions_print_stacktrace *************************************************
1820 Prints a pending exception with Throwable.printStackTrace(). If
1821 there happens an exception during printStackTrace(), we print the
1822 thrown exception and the original one.
1824 NOTE: This function calls Java code.
1826 *******************************************************************************/
1828 void exceptions_print_stacktrace(void)
1830 java_objectheader *oxptr;
1831 java_objectheader *xptr;
1835 /* get original exception */
1837 oxptr = *exceptionptr;
1840 vm_abort("exceptions_print_stacktrace: no exception thrown");
1842 /* clear exception, because we are calling jit code again */
1844 *exceptionptr = NULL;
1846 c = oxptr->vftbl->class;
1848 /* find the printStackTrace() method */
1850 m = class_resolveclassmethod(c,
1851 utf_printStackTrace,
1853 class_java_lang_Object,
1857 vm_abort("exceptions_print_stacktrace: printStackTrace()V not found");
1859 /* print compatibility message */
1861 fprintf(stderr, "Exception in thread \"main\" ");
1863 /* print the stacktrace */
1865 (void) vm_call_method(m, oxptr);
1867 /* This normally means, we are EXTREMLY out of memory or
1868 have a serious problem while printStackTrace. But may
1869 be another exception, so print it. */
1871 xptr = *exceptionptr;
1874 fprintf(stderr, "Exception while printStackTrace(): ");
1876 /* now print original exception */
1878 exceptions_print_exception(xptr);
1879 stacktrace_print_trace(xptr);
1881 /* now print original exception */
1883 fprintf(stderr, "Original exception was: ");
1884 exceptions_print_exception(oxptr);
1885 stacktrace_print_trace(oxptr);
1893 * These are local overrides for various environment variables in Emacs.
1894 * Please do not remove this and leave it at the end of the file, where
1895 * Emacs will automagically detect them.
1896 * ---------------------------------------------------------------------
1899 * indent-tabs-mode: t
1903 * vim:noexpandtab:sw=4:ts=4: