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 7246 2007-01-29 18:49:05Z 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"
65 #include "vmcore/class.h"
66 #include "vmcore/loader.h"
67 #include "vmcore/options.h"
70 /* for raising exceptions from native methods *********************************/
72 #if !defined(ENABLE_THREADS)
73 java_objectheader *_no_threads_exceptionptr = NULL;
77 /* init_system_exceptions ******************************************************
79 Load and link exceptions used in the system.
81 *******************************************************************************/
83 bool exceptions_init(void)
85 /* java/lang/Throwable */
87 if (!(class_java_lang_Throwable =
88 load_class_bootstrap(utf_java_lang_Throwable)) ||
89 !link_class(class_java_lang_Throwable))
94 if (!(class_java_lang_Error = load_class_bootstrap(utf_java_lang_Error)) ||
95 !link_class(class_java_lang_Error))
98 #if defined(ENABLE_JAVASE)
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 /* java/lang/OutOfMemoryError */
116 if (!(class_java_lang_OutOfMemoryError =
117 load_class_bootstrap(utf_java_lang_OutOfMemoryError)) ||
118 !link_class(class_java_lang_OutOfMemoryError))
121 /* java/lang/VirtualMachineError */
123 if (!(class_java_lang_VirtualMachineError =
124 load_class_bootstrap(utf_java_lang_VirtualMachineError)) ||
125 !link_class(class_java_lang_VirtualMachineError))
129 /* java/lang/Exception */
131 if (!(class_java_lang_Exception =
132 load_class_bootstrap(utf_java_lang_Exception)) ||
133 !link_class(class_java_lang_Exception))
136 /* java/lang/ClassCastException */
138 if (!(class_java_lang_ClassCastException =
139 load_class_bootstrap(utf_java_lang_ClassCastException)) ||
140 !link_class(class_java_lang_ClassCastException))
143 /* java/lang/ClassNotFoundException */
145 if (!(class_java_lang_ClassNotFoundException =
146 load_class_bootstrap(utf_java_lang_ClassNotFoundException)) ||
147 !link_class(class_java_lang_ClassNotFoundException))
150 /* java/lang/NullPointerException */
152 if (!(class_java_lang_NullPointerException =
153 load_class_bootstrap(utf_java_lang_NullPointerException)) ||
154 !link_class(class_java_lang_NullPointerException))
158 #if defined(WITH_CLASSPATH_GNU)
159 /* java/lang/VMThrowable */
161 if (!(class_java_lang_VMThrowable =
162 load_class_bootstrap(utf_java_lang_VMThrowable)) ||
163 !link_class(class_java_lang_VMThrowable))
171 static void throw_exception_exit_intern(bool doexit)
173 java_objectheader *xptr;
177 xptr = *exceptionptr;
180 /* clear exception, because we are calling jit code again */
181 *exceptionptr = NULL;
183 c = xptr->vftbl->class;
185 pss = class_resolveclassmethod(c,
188 class_java_lang_Object,
191 /* print the stacktrace */
194 (void) vm_call_method(pss, xptr);
196 /* This normally means, we are EXTREMLY out of memory or have a */
197 /* serious problem while printStackTrace. But may be another */
198 /* exception, so print it. */
201 java_lang_Throwable *t;
203 t = (java_lang_Throwable *) *exceptionptr;
205 fprintf(stderr, "Exception while printStackTrace(): ");
206 utf_fprint_printable_ascii_classname(stderr, t->header.vftbl->class->name);
208 if (t->detailMessage) {
211 buf = javastring_tochar((java_objectheader *) t->detailMessage);
212 fprintf(stderr, ": %s", buf);
213 MFREE(buf, char, strlen(buf));
216 fprintf(stderr, "\n");
220 utf_fprint_printable_ascii_classname(stderr, c->name);
221 fprintf(stderr, ": printStackTrace()V not found!\n");
234 void throw_exception(void)
236 throw_exception_exit_intern(false);
240 void throw_exception_exit(void)
242 throw_exception_exit_intern(true);
246 void throw_main_exception(void)
248 fprintf(stderr, "Exception in thread \"main\" ");
251 throw_exception_exit_intern(false);
255 void throw_main_exception_exit(void)
257 fprintf(stderr, "Exception in thread \"main\" ");
260 throw_exception_exit_intern(true);
264 void throw_cacao_exception_exit(const char *exception, const char *message, ...)
271 len = strlen(exception);
272 tmp = MNEW(char, len + 1);
273 strncpy(tmp, exception, len);
276 /* convert to classname */
278 for (i = len - 1; i >= 0; i--)
279 if (tmp[i] == '/') tmp[i] = '.';
281 fprintf(stderr, "Exception in thread \"main\" %s", tmp);
283 MFREE(tmp, char, len);
285 if (strlen(message) > 0) {
286 fprintf(stderr, ": ");
288 va_start(ap, message);
289 vfprintf(stderr, message, ap);
293 fprintf(stderr, "\n");
302 /* exceptions_new_class ********************************************************
304 Creates an exception object from the given class and initalizes it.
307 class....class pointer
309 *******************************************************************************/
311 static java_objectheader *exceptions_new_class(classinfo *c)
313 java_objectheader *o;
315 o = native_new_and_init(c);
318 return *exceptionptr;
324 /* exceptions_new_utf **********************************************************
326 Creates an exception object with the given name and initalizes it.
329 classname....class name in UTF-8
331 *******************************************************************************/
333 static java_objectheader *exceptions_new_utf(utf *classname)
336 java_objectheader *o;
338 c = load_class_bootstrap(classname);
341 return *exceptionptr;
343 o = exceptions_new_class(c);
349 /* exceptions_throw_class ******************************************************
351 Creates an exception object from the given class, initalizes and
355 class....class pointer
357 *******************************************************************************/
359 static void exceptions_throw_class(classinfo *c)
361 java_objectheader *o;
363 o = exceptions_new_class(c);
372 /* exceptions_throw_utf ********************************************************
374 Creates an exception object with the given name, initalizes and
378 classname....class name in UTF-8
380 *******************************************************************************/
382 static void exceptions_throw_utf(utf *classname)
386 c = load_class_bootstrap(classname);
391 exceptions_throw_class(c);
395 /* exceptions_throw_utf_throwable **********************************************
397 Creates an exception object with the given name and initalizes it
398 with the given java/lang/Throwable exception.
401 classname....class name in UTF-8
402 cause........the given Throwable
404 *******************************************************************************/
406 static void exceptions_throw_utf_throwable(utf *classname,
407 java_objectheader *cause)
409 java_objectheader *o;
412 c = load_class_bootstrap(classname);
417 o = native_new_and_init_throwable(c, cause);
426 /* exceptions_new_utf_javastring ***********************************************
428 Creates an exception object with the given name and initalizes it
429 with the given java/lang/String message.
432 classname....class name in UTF-8
433 message......the message as a java.lang.String
436 an exception pointer (in any case -- either it is the newly created
437 exception, or an exception thrown while trying to create it).
439 *******************************************************************************/
441 static java_objectheader *exceptions_new_utf_javastring(utf *classname,
442 java_objectheader *message)
444 java_objectheader *o;
447 c = load_class_bootstrap(classname);
450 return *exceptionptr;
452 o = native_new_and_init_string(c, message);
455 return *exceptionptr;
461 /* exceptions_new_class_utf ****************************************************
463 Creates an exception object of the given class and initalizes it.
466 c..........class pointer
467 message....the message as UTF-8 string
469 *******************************************************************************/
471 static java_objectheader *exceptions_new_class_utf(classinfo *c, utf *message)
473 java_objectheader *o;
474 java_objectheader *s;
476 s = javastring_new(message);
479 return *exceptionptr;
481 o = native_new_and_init_string(c, s);
484 return *exceptionptr;
490 /* exceptions_new_utf_utf ******************************************************
492 Creates an exception object with the given name and initalizes it
493 with the given utf message.
496 classname....class name in UTF-8
497 message......the message as an utf *
500 an exception pointer (in any case -- either it is the newly created
501 exception, or an exception thrown while trying to create it).
503 *******************************************************************************/
505 static java_objectheader *exceptions_new_utf_utf(utf *classname, utf *message)
508 java_objectheader *o;
510 c = load_class_bootstrap(classname);
513 return *exceptionptr;
515 o = exceptions_new_class_utf(c, message);
521 /* new_exception_message *******************************************************
523 Creates an exception object with the given name and initalizes it
524 with the given char message.
527 classname....class name in UTF-8
528 message......message in UTF-8
531 an exception pointer (in any case -- either it is the newly created
532 exception, or an exception thrown while trying to create it).
534 *******************************************************************************/
536 static java_objectheader *new_exception_message(const char *classname,
539 java_objectheader *o;
540 java_objectheader *s;
542 s = javastring_new_from_utf_string(message);
545 return *exceptionptr;
547 o = exceptions_new_utf_javastring(classname, s);
553 /* exceptions_throw_class_utf **************************************************
555 Creates an exception object of the given class, initalizes and
556 throws it with the given utf message.
559 c..........class pointer
560 message....the message as an UTF-8
562 *******************************************************************************/
564 static void exceptions_throw_class_utf(classinfo *c, utf *message)
566 *exceptionptr = exceptions_new_class_utf(c, message);
570 /* exceptions_throw_utf_utf ****************************************************
572 Creates an exception object with the given name, initalizes and
573 throws it with the given utf message.
576 classname....class name in UTF-8
577 message......the message as an utf *
579 *******************************************************************************/
581 static void exceptions_throw_utf_utf(utf *classname, utf *message)
583 *exceptionptr = exceptions_new_utf_utf(classname, message);
587 /* new_exception_int ***********************************************************
589 Creates an exception object with the given name and initalizes it
590 with the given int value.
593 classname....class name in UTF-8
594 i............the integer
597 an exception pointer (in any case -- either it is the newly created
598 exception, or an exception thrown while trying to create it).
600 *******************************************************************************/
602 java_objectheader *new_exception_int(const char *classname, s4 i)
604 java_objectheader *o;
607 if (!(c = load_class_bootstrap(utf_new_char(classname))))
608 return *exceptionptr;
610 o = native_new_and_init_int(c, i);
613 return *exceptionptr;
619 /* exceptions_new_abstractmethoderror ****************************************
621 Generates a java.lang.AbstractMethodError for the VM.
623 *******************************************************************************/
625 java_objectheader *exceptions_new_abstractmethoderror(void)
627 java_objectheader *o;
629 o = exceptions_new_utf(utf_java_lang_AbstractMethodError);
635 /* exceptions_asm_new_abstractmethoderror **************************************
637 Generates a java.lang.AbstractMethodError for
638 asm_abstractmethoderror.
640 *******************************************************************************/
642 java_objectheader *exceptions_asm_new_abstractmethoderror(u1 *sp, u1 *ra)
645 java_objectheader *e;
647 /* create the stackframeinfo (XPC is equal to RA) */
649 stacktrace_create_extern_stackframeinfo(&sfi, NULL, sp, ra, ra);
651 /* create the exception */
653 #if defined(ENABLE_JAVASE)
654 e = exceptions_new_abstractmethoderror();
656 /* in the meantime we do this */
658 e = exceptions_new_virtualmachineerror();
661 /* remove the stackframeinfo */
663 stacktrace_remove_stackframeinfo(&sfi);
669 /* exceptions_new_arraystoreexception ******************************************
671 Generates a java.lang.ArrayStoreException for the VM.
673 *******************************************************************************/
675 java_objectheader *exceptions_new_arraystoreexception(void)
677 java_objectheader *o;
679 o = exceptions_new_utf(utf_java_lang_ArrayStoreException);
685 /* exceptions_throw_abstractmethoderror ****************************************
687 Generates and throws a java.lang.AbstractMethodError for the VM.
689 *******************************************************************************/
691 void exceptions_throw_abstractmethoderror(void)
693 exceptions_throw_utf(utf_java_lang_AbstractMethodError);
697 /* exceptions_throw_classcircularityerror **************************************
699 Generates and throws a java.lang.ClassCircularityError for the
703 c............the class in which the error was found
705 *******************************************************************************/
707 void exceptions_throw_classcircularityerror(classinfo *c)
709 java_objectheader *o;
713 /* calculate message length */
715 msglen = utf_bytes(c->name) + strlen("0");
717 /* allocate a buffer */
719 msg = MNEW(char, msglen);
721 /* print message into allocated buffer */
723 utf_copy_classname(msg, c->name);
725 o = new_exception_message(utf_java_lang_ClassCircularityError, msg);
727 MFREE(msg, char, msglen);
736 /* exceptions_throw_classformaterror *******************************************
738 Generates and throws a java.lang.ClassFormatError for the VM.
741 c............the class in which the error was found
742 message......UTF-8 format string
744 *******************************************************************************/
746 void exceptions_throw_classformaterror(classinfo *c, const char *message, ...)
748 java_objectheader *o;
753 /* calculate message length */
758 msglen += utf_bytes(c->name) + strlen(" (");
760 va_start(ap, message);
761 msglen += get_variable_message_length(message, ap);
765 msglen += strlen(")");
767 msglen += strlen("0");
769 /* allocate a buffer */
771 msg = MNEW(char, msglen);
773 /* print message into allocated buffer */
776 utf_copy_classname(msg, c->name);
780 va_start(ap, message);
781 vsprintf(msg + strlen(msg), message, ap);
787 o = new_exception_message(utf_java_lang_ClassFormatError, msg);
789 MFREE(msg, char, msglen);
795 /* exceptions_throw_classnotfoundexception *************************************
797 Generates and throws a java.lang.ClassNotFoundException for the
801 name.........name of the class not found as a utf *
803 *******************************************************************************/
805 void exceptions_throw_classnotfoundexception(utf *name)
807 /* we use class here, as this one is rather frequent */
809 exceptions_throw_class_utf(class_java_lang_ClassNotFoundException, name);
813 /* exceptions_throw_noclassdeffounderror ***************************************
815 Generates and throws a java.lang.NoClassDefFoundError.
818 name.........name of the class not found as a utf *
820 *******************************************************************************/
822 void exceptions_throw_noclassdeffounderror(utf *name)
824 exceptions_throw_class_utf(class_java_lang_NoClassDefFoundError, name);
828 /* classnotfoundexception_to_noclassdeffounderror ******************************
830 Check the *exceptionptr for a ClassNotFoundException. If it is one,
831 convert it to a NoClassDefFoundError.
833 *******************************************************************************/
835 void classnotfoundexception_to_noclassdeffounderror(void)
837 java_objectheader *xptr;
838 java_objectheader *cause;
839 java_lang_Throwable *t;
844 cause = *exceptionptr;
846 /* convert ClassNotFoundException's to NoClassDefFoundError's */
848 if (builtin_instanceof(cause, class_java_lang_ClassNotFoundException)) {
849 /* clear exception, because we are calling jit code again */
851 *exceptionptr = NULL;
853 /* create new error */
855 t = (java_lang_Throwable *) cause;
856 s = t->detailMessage;
858 xptr = exceptions_new_utf_javastring(utf_java_lang_NoClassDefFoundError, s);
860 /* we had an exception while creating the error */
865 /* set new exception */
867 *exceptionptr = xptr;
872 /* exceptions_throw_exceptionininitializererror ********************************
874 Generates and throws a java.lang.ExceptionInInitializerError for
878 cause......cause exception object
880 *******************************************************************************/
882 void exceptions_throw_exceptionininitializererror(java_objectheader *cause)
884 exceptions_throw_utf_throwable(utf_java_lang_ExceptionInInitializerError,
889 /* exceptions_throw_incompatibleclasschangeerror *******************************
891 Generates and throws a java.lang.IncompatibleClassChangeError for
895 message......UTF-8 message format string
897 *******************************************************************************/
899 void exceptions_throw_incompatibleclasschangeerror(classinfo *c, const char *message)
901 java_objectheader *o;
905 /* calculate exception message length */
907 msglen = utf_bytes(c->name) + strlen(message) + strlen("0");
909 /* allocate memory */
911 msg = MNEW(char, msglen);
913 utf_copy_classname(msg, c->name);
914 strcat(msg, message);
916 o = native_new_and_init_string(utf_java_lang_IncompatibleClassChangeError,
917 javastring_new_from_utf_string(msg));
921 MFREE(msg, char, msglen);
930 /* exceptions_throw_instantiationerror *****************************************
932 Generates and throws a java.lang.InstantiationError for the VM.
934 *******************************************************************************/
936 void exceptions_throw_instantiationerror(classinfo *c)
938 exceptions_throw_utf_utf(utf_java_lang_InstantiationError, c->name);
942 /* exceptions_throw_internalerror **********************************************
944 Generates and throws a java.lang.InternalError for the VM.
947 message......UTF-8 message format string
949 *******************************************************************************/
951 void exceptions_throw_internalerror(const char *message, ...)
953 java_objectheader *o;
958 /* calculate exception message length */
960 va_start(ap, message);
961 msglen = get_variable_message_length(message, ap);
964 /* allocate memory */
966 msg = MNEW(char, msglen);
968 /* generate message */
970 va_start(ap, message);
971 vsprintf(msg, message, ap);
974 /* create exception object */
976 o = new_exception_message(utf_java_lang_InternalError, msg);
980 MFREE(msg, char, msglen);
989 /* exceptions_throw_linkageerror ***********************************************
991 Generates and throws java.lang.LinkageError with an error message.
994 message......UTF-8 message
995 c............class related to the error. If this is != NULL
996 the name of c is appended to the error message.
998 *******************************************************************************/
1000 void exceptions_throw_linkageerror(const char *message, classinfo *c)
1002 java_objectheader *o;
1006 /* calculate exception message length */
1008 msglen = strlen(message) + 1;
1011 msglen += utf_bytes(c->name);
1013 /* allocate memory */
1015 msg = MNEW(char, msglen);
1017 /* generate message */
1019 strcpy(msg,message);
1022 utf_cat_classname(msg, c->name);
1024 o = native_new_and_init_string(class_java_lang_LinkageError,
1025 javastring_new_from_utf_string(msg));
1029 MFREE(msg, char, msglen);
1038 /* exceptions_throw_nosuchfielderror *******************************************
1040 Generates and throws a java.lang.NoSuchFieldError with an error
1044 c............class in which the field was not found
1045 name.........name of the field
1047 *******************************************************************************/
1049 void exceptions_throw_nosuchfielderror(classinfo *c, utf *name)
1055 /* calculate exception message length */
1057 msglen = utf_bytes(c->name) + strlen(".") + utf_bytes(name) + strlen("0");
1059 /* allocate memory */
1061 msg = MNEW(char, msglen);
1063 /* generate message */
1065 utf_copy_classname(msg, c->name);
1069 u = utf_new_char(msg);
1073 MFREE(msg, char, msglen);
1075 exceptions_throw_utf_utf(utf_java_lang_NoSuchFieldError, u);
1079 /* exceptions_throw_nosuchmethoderror ******************************************
1081 Generates and throws a java.lang.NoSuchMethodError with an error
1085 c............class in which the method was not found
1086 name.........name of the method
1087 desc.........descriptor of the method
1089 *******************************************************************************/
1091 void exceptions_throw_nosuchmethoderror(classinfo *c, utf *name, utf *desc)
1097 /* calculate exception message length */
1099 msglen = utf_bytes(c->name) + strlen(".") + utf_bytes(name) +
1100 utf_bytes(desc) + strlen("0");
1102 /* allocate memory */
1104 msg = MNEW(char, msglen);
1106 /* generate message */
1108 utf_copy_classname(msg, c->name);
1113 u = utf_new_char(msg);
1117 MFREE(msg, char, msglen);
1119 exceptions_throw_utf_utf(utf_java_lang_NoSuchMethodError, u);
1123 /* exceptions_throw_outofmemoryerror *******************************************
1125 Generates and throws an java.lang.OutOfMemoryError for the VM.
1127 *******************************************************************************/
1129 void exceptions_throw_outofmemoryerror(void)
1131 exceptions_throw_class(class_java_lang_OutOfMemoryError);
1135 /* exceptions_throw_unsatisfiedlinkerror ***************************************
1137 Generates and throws a java.lang.UnsatisfiedLinkError for the
1141 name......UTF-8 name string
1143 *******************************************************************************/
1145 void exceptions_throw_unsatisfiedlinkerror(utf *name)
1147 exceptions_throw_utf_utf(utf_java_lang_UnsatisfiedLinkError, name);
1151 /* exceptions_throw_unsupportedclassversionerror *******************************
1153 Generates and throws a java.lang.UnsupportedClassVersionError for
1157 c............class in which the method was not found
1158 message......UTF-8 format string
1160 *******************************************************************************/
1162 void exceptions_throw_unsupportedclassversionerror(classinfo *c, u4 ma, u4 mi)
1164 java_objectheader *o;
1168 /* calculate exception message length */
1171 utf_bytes(c->name) +
1172 strlen(" (Unsupported major.minor version 00.0)") +
1175 /* allocate memory */
1177 msg = MNEW(char, msglen);
1179 /* generate message */
1181 utf_copy_classname(msg, c->name);
1182 sprintf(msg + strlen(msg), " (Unsupported major.minor version %d.%d)",
1185 /* create exception object */
1187 o = new_exception_message(utf_java_lang_UnsupportedClassVersionError, msg);
1191 MFREE(msg, char, msglen);
1200 /* exceptions_throw_verifyerror ************************************************
1202 Generates and throws a java.lang.VerifyError for the JIT compiler.
1205 m............method in which the error was found
1206 message......UTF-8 format string
1208 *******************************************************************************/
1210 void exceptions_throw_verifyerror(methodinfo *m, const char *message, ...)
1212 java_objectheader *o;
1217 /* calculate exception message length */
1223 strlen("(class: ") + utf_bytes(m->class->name) +
1224 strlen(", method: ") + utf_bytes(m->name) +
1225 strlen(" signature: ") + utf_bytes(m->descriptor) +
1226 strlen(") ") + strlen("0");
1228 va_start(ap, message);
1229 msglen += get_variable_message_length(message, ap);
1232 /* allocate memory */
1234 msg = MNEW(char, msglen);
1236 /* generate message */
1239 strcpy(msg, "(class: ");
1240 utf_cat_classname(msg, m->class->name);
1241 strcat(msg, ", method: ");
1242 utf_cat(msg, m->name);
1243 strcat(msg, " signature: ");
1244 utf_cat(msg, m->descriptor);
1248 va_start(ap, message);
1249 vsprintf(msg + strlen(msg), message, ap);
1252 /* create exception object */
1254 o = new_exception_message(utf_java_lang_VerifyError, msg);
1258 MFREE(msg, char, msglen);
1264 /* exceptions_throw_verifyerror_for_stack **************************************
1266 throws a java.lang.VerifyError for an invalid stack slot type
1269 m............method in which the error was found
1270 type.........the expected type
1273 an exception pointer (in any case -- either it is the newly created
1274 exception, or an exception thrown while trying to create it).
1276 *******************************************************************************/
1278 void exceptions_throw_verifyerror_for_stack(methodinfo *m,int type)
1280 java_objectheader *o;
1285 /* calculate exception message length */
1290 msglen = strlen("(class: ") + utf_bytes(m->class->name) +
1291 strlen(", method: ") + utf_bytes(m->name) +
1292 strlen(" signature: ") + utf_bytes(m->descriptor) +
1293 strlen(") Expecting to find longest-------typename on stack")
1296 /* allocate memory */
1298 msg = MNEW(char, msglen);
1300 /* generate message */
1303 strcpy(msg, "(class: ");
1304 utf_cat_classname(msg, m->class->name);
1305 strcat(msg, ", method: ");
1306 utf_cat(msg, m->name);
1307 strcat(msg, " signature: ");
1308 utf_cat(msg, m->descriptor);
1315 strcat(msg,"Expecting to find ");
1317 case TYPE_INT: typename = "integer"; break;
1318 case TYPE_LNG: typename = "long"; break;
1319 case TYPE_FLT: typename = "float"; break;
1320 case TYPE_DBL: typename = "double"; break;
1321 case TYPE_ADR: typename = "object/array"; break;
1322 case TYPE_RET: typename = "returnAddress"; break;
1323 default: typename = "<INVALID>"; assert(0); break;
1325 strcat(msg, typename);
1326 strcat(msg, " on stack");
1328 /* create exception object */
1330 o = new_exception_message(utf_java_lang_VerifyError, msg);
1334 MFREE(msg, char, msglen);
1340 /* exceptions_throw_virtualmachineerror ****************************************
1342 Generates and throws a java.lang.VirtualMachineError for the VM.
1344 *******************************************************************************/
1346 void exceptions_throw_virtualmachineerror(void)
1348 exceptions_throw_class(class_java_lang_VirtualMachineError);
1352 /* exceptions_new_arithmeticexception ******************************************
1354 Generates a java.lang.ArithmeticException for the JIT compiler.
1356 *******************************************************************************/
1358 java_objectheader *exceptions_new_arithmeticexception(void)
1360 java_objectheader *o;
1362 o = new_exception_message(utf_java_lang_ArithmeticException, "/ by zero");
1365 return *exceptionptr;
1371 /* exceptions_new_arrayindexoutofboundsexception *******************************
1373 Generates a java.lang.ArrayIndexOutOfBoundsException for the VM
1376 *******************************************************************************/
1378 java_objectheader *exceptions_new_arrayindexoutofboundsexception(s4 index)
1380 java_objectheader *o;
1382 java_objectheader *s;
1384 /* convert the index into a String, like Sun does */
1386 m = class_resolveclassmethod(class_java_lang_String,
1387 utf_new_char("valueOf"),
1388 utf_new_char("(I)Ljava/lang/String;"),
1389 class_java_lang_Object,
1393 return *exceptionptr;
1395 s = vm_call_method(m, NULL, index);
1398 return *exceptionptr;
1400 o = exceptions_new_utf_javastring(utf_java_lang_ArrayIndexOutOfBoundsException,
1404 return *exceptionptr;
1410 /* exceptions_throw_arrayindexoutofboundsexception *****************************
1412 Generates and throws a java.lang.ArrayIndexOutOfBoundsException for
1415 *******************************************************************************/
1417 void exceptions_throw_arrayindexoutofboundsexception(void)
1419 exceptions_throw_utf(utf_java_lang_ArrayIndexOutOfBoundsException);
1423 /* exceptions_throw_arraystoreexception ****************************************
1425 Generates and throws a java.lang.ArrayStoreException for the VM.
1427 *******************************************************************************/
1429 void exceptions_throw_arraystoreexception(void)
1431 exceptions_throw_utf(utf_java_lang_ArrayStoreException);
1432 /* e = native_new_and_init(class_java_lang_ArrayStoreException); */
1436 /* exceptions_new_classcastexception *******************************************
1438 Generates a java.lang.ClassCastException for the JIT compiler.
1440 *******************************************************************************/
1442 java_objectheader *exceptions_new_classcastexception(java_objectheader *o)
1444 java_objectheader *e;
1446 java_lang_String *s;
1448 classname = o->vftbl->class->name;
1450 s = javastring_new(classname);
1452 e = native_new_and_init_string(class_java_lang_ClassCastException, s);
1455 return *exceptionptr;
1461 /* exceptions_throw_clonenotsupportedexception *********************************
1463 Generates and throws a java.lang.CloneNotSupportedException for the
1466 *******************************************************************************/
1468 void exceptions_throw_clonenotsupportedexception(void)
1470 exceptions_throw_utf(utf_java_lang_CloneNotSupportedException);
1474 /* exceptions_throw_illegalaccessexception *************************************
1476 Generates and throws a java.lang.IllegalAccessException for the VM.
1478 *******************************************************************************/
1480 void exceptions_throw_illegalaccessexception(classinfo *c)
1482 /* XXX handle argument */
1484 exceptions_throw_utf(utf_java_lang_IllegalAccessException);
1488 /* exceptions_throw_illegalargumentexception ***********************************
1490 Generates and throws a java.lang.IllegalArgumentException for the
1493 *******************************************************************************/
1495 void exceptions_throw_illegalargumentexception(void)
1497 exceptions_throw_utf(utf_java_lang_IllegalArgumentException);
1501 /* exceptions_throw_illegalmonitorstateexception *******************************
1503 Generates and throws a java.lang.IllegalMonitorStateException for
1506 *******************************************************************************/
1508 void exceptions_throw_illegalmonitorstateexception(void)
1510 exceptions_throw_utf(utf_java_lang_IllegalMonitorStateException);
1514 /* exceptions_throw_instantiationexception *************************************
1516 Generates and throws a java.lang.InstantiationException for the VM.
1518 *******************************************************************************/
1520 void exceptions_throw_instantiationexception(classinfo *c)
1522 exceptions_throw_utf_utf(utf_java_lang_InstantiationException, c->name);
1526 /* exceptions_throw_interruptedexception ***************************************
1528 Generates and throws a java.lang.InterruptedException for the VM.
1530 *******************************************************************************/
1532 void exceptions_throw_interruptedexception(void)
1534 exceptions_throw_utf(utf_java_lang_InterruptedException);
1538 /* exceptions_throw_invocationtargetexception **********************************
1540 Generates and throws a java.lang.InvocationTargetException for the
1544 cause......cause exception object
1546 *******************************************************************************/
1548 void exceptions_throw_invocationtargetexception(java_objectheader *cause)
1550 exceptions_throw_utf_throwable(utf_java_lang_InvocationTargetException,
1555 /* exceptions_throw_negativearraysizeexception *********************************
1557 Generates and throws a java.lang.NegativeArraySizeException for the
1560 *******************************************************************************/
1562 void exceptions_throw_negativearraysizeexception(void)
1564 exceptions_throw_utf(utf_java_lang_NegativeArraySizeException);
1568 /* exceptions_new_nullpointerexception *****************************************
1570 Generates a java.lang.NullPointerException for the VM system.
1572 *******************************************************************************/
1574 java_objectheader *exceptions_new_nullpointerexception(void)
1576 java_objectheader *o;
1578 o = exceptions_new_class(class_java_lang_NullPointerException);
1584 /* exceptions_throw_nullpointerexception ***************************************
1586 Generates a java.lang.NullPointerException for the VM system and
1587 throw it in the VM system.
1589 *******************************************************************************/
1591 void exceptions_throw_nullpointerexception(void)
1593 exceptions_throw_class(class_java_lang_NullPointerException);
1597 /* exceptions_throw_stringindexoutofboundsexception ****************************
1599 Generates and throws a java.lang.StringIndexOutOfBoundsException
1602 *******************************************************************************/
1604 void exceptions_throw_stringindexoutofboundsexception(void)
1606 exceptions_throw_utf(utf_java_lang_StringIndexOutOfBoundsException);
1610 /* exceptions_get_exception ****************************************************
1612 Returns the current exception pointer of the current thread.
1614 *******************************************************************************/
1616 java_objectheader *exceptions_get_exception(void)
1618 /* return the exception */
1620 return *exceptionptr;
1624 /* exceptions_set_exception ****************************************************
1626 Sets the exception pointer of the current thread.
1628 *******************************************************************************/
1630 void exceptions_set_exception(java_objectheader *o)
1632 /* set the exception */
1638 /* exceptions_clear_exception **************************************************
1640 Clears the current exception pointer of the current thread.
1642 *******************************************************************************/
1644 void exceptions_clear_exception(void)
1646 /* and clear the exception */
1648 *exceptionptr = NULL;
1652 /* exceptions_get_and_clear_exception ******************************************
1654 Gets the exception pointer of the current thread and clears it.
1655 This function may return NULL.
1657 *******************************************************************************/
1659 java_objectheader *exceptions_get_and_clear_exception(void)
1661 java_objectheader **p;
1662 java_objectheader *e;
1664 /* get the pointer of the exception pointer */
1668 /* get the exception */
1672 /* and clear the exception */
1676 /* return the exception */
1682 /* exceptions_handle_exception *************************************************
1684 Try to find an exception handler for the given exception and return it.
1685 If no handler is found, exit the monitor of the method (if any)
1689 xptr.........the exception object
1690 xpc..........PC of where the exception was thrown
1691 pv...........Procedure Value of the current method
1692 sp...........current stack pointer
1695 the address of the first matching exception handler, or
1696 NULL if no handler was found
1698 *******************************************************************************/
1700 #if defined(ENABLE_JIT)
1701 u1 *exceptions_handle_exception(java_objectheader *xptr, u1 *xpc, u1 *pv, u1 *sp)
1706 dseg_exception_entry *ex;
1707 s4 exceptiontablelength;
1709 classref_or_classinfo cr;
1711 #if defined(ENABLE_THREADS)
1712 java_objectheader *o;
1715 /* get info from the method header */
1717 code = *((codeinfo **) (pv + CodeinfoPointer));
1718 issync = *((s4 *) (pv + IsSync));
1719 ex = (dseg_exception_entry *) (pv + ExTableStart);
1720 exceptiontablelength = *((s4 *) (pv + ExTableSize));
1722 /* Get the methodinfo pointer from the codeinfo pointer. For
1723 asm_vm_call_method the codeinfo pointer is NULL. */
1725 m = (code == NULL) ? NULL : code->m;
1727 #if !defined(NDEBUG)
1728 /* print exception trace */
1730 if (opt_verbose || opt_verbosecall || opt_verboseexception)
1731 builtin_trace_exception(xptr, m, xpc, 1);
1734 for (i = 0; i < exceptiontablelength; i++) {
1735 /* ATTENTION: keep this here, as we need to decrement the
1736 pointer before the loop executes! */
1740 /* If the start and end PC is NULL, this means we have the
1741 special case of asm_vm_call_method. So, just return the
1742 proper exception handler. */
1744 if ((ex->startpc == NULL) && (ex->endpc == NULL))
1745 return (u1 *) (ptrint) &asm_vm_call_method_exception_handler;
1747 /* is the xpc is the current catch range */
1749 if ((ex->startpc <= xpc) && (xpc < ex->endpc)) {
1752 /* NULL catches everything */
1754 if (cr.any == NULL) {
1755 #if !defined(NDEBUG)
1756 /* Print stacktrace of exception when caught. */
1758 if (opt_verboseexception) {
1759 exceptions_print_exception(xptr);
1760 stacktrace_print_trace(xptr);
1764 return ex->handlerpc;
1767 /* resolve or load/link the exception class */
1769 if (IS_CLASSREF(cr)) {
1770 /* The exception class reference is unresolved. */
1771 /* We have to do _eager_ resolving here. While the class of */
1772 /* the exception object is guaranteed to be loaded, it may */
1773 /* well have been loaded by a different loader than the */
1774 /* defining loader of m's class, which is the one we must */
1775 /* use to resolve the catch class. Thus lazy resolving */
1776 /* might fail, even if the result of the resolution would */
1777 /* be an already loaded class. */
1779 c = resolve_classref_eager(cr.ref);
1782 /* Exception resolving the exception class, argh! */
1786 /* Ok, we resolved it. Enter it in the table, so we don't */
1787 /* have to do this again. */
1788 /* XXX this write should be atomic. Is it? */
1790 ex->catchtype.cls = c;
1794 /* XXX I don't think this case can ever happen. -Edwin */
1795 if (!(c->state & CLASS_LOADED))
1796 /* use the methods' classloader */
1797 if (!load_class_from_classloader(c->name,
1798 m->class->classloader))
1801 /* XXX I think, if it is not linked, we can be sure that */
1802 /* the exception object is no (indirect) instance of it, no? */
1804 if (!(c->state & CLASS_LINKED))
1809 /* is the thrown exception an instance of the catch class? */
1811 if (builtin_instanceof(xptr, c)) {
1812 #if !defined(NDEBUG)
1813 /* Print stacktrace of exception when caught. */
1815 if (opt_verboseexception) {
1816 exceptions_print_exception(xptr);
1817 stacktrace_print_trace(xptr);
1821 return ex->handlerpc;
1826 #if defined(ENABLE_THREADS)
1827 /* is this method synchronized? */
1830 /* get synchronization object */
1832 # if defined(__MIPS__) && (SIZEOF_VOID_P == 4)
1833 /* XXX change this if we ever want to use 4-byte stackslots */
1834 o = *((java_objectheader **) (sp + issync - 8));
1836 o = *((java_objectheader **) (sp + issync - SIZEOF_VOID_P));
1841 lock_monitor_exit(o);
1845 /* none of the exceptions catch this one */
1849 #endif /* defined(ENABLE_JIT) */
1852 /* exceptions_print_exception **************************************************
1854 Prints an exception, the detail message and the cause, if
1855 available, with CACAO internal functions to stdout.
1857 *******************************************************************************/
1859 void exceptions_print_exception(java_objectheader *xptr)
1861 java_lang_Throwable *t;
1862 #if defined(ENABLE_JAVASE)
1863 java_lang_Throwable *cause;
1867 t = (java_lang_Throwable *) xptr;
1874 #if defined(ENABLE_JAVASE)
1878 /* print the root exception */
1880 utf_display_printable_ascii_classname(t->header.vftbl->class->name);
1882 if (t->detailMessage != NULL) {
1883 u = javastring_toutf(t->detailMessage, false);
1886 utf_display_printable_ascii(u);
1891 #if defined(ENABLE_JAVASE)
1892 /* print the cause if available */
1894 if ((cause != NULL) && (cause != t)) {
1895 printf("Caused by: ");
1896 utf_display_printable_ascii_classname(cause->header.vftbl->class->name);
1898 if (cause->detailMessage) {
1899 u = javastring_toutf(cause->detailMessage, false);
1902 utf_display_printable_ascii(u);
1911 /* exceptions_print_current_exception ******************************************
1913 Prints the current pending exception, the detail message and the
1914 cause, if available, with CACAO internal functions to stdout.
1916 *******************************************************************************/
1918 void exceptions_print_current_exception(void)
1920 java_objectheader *xptr;
1922 xptr = *exceptionptr;
1924 exceptions_print_exception(xptr);
1929 * These are local overrides for various environment variables in Emacs.
1930 * Please do not remove this and leave it at the end of the file, where
1931 * Emacs will automagically detect them.
1932 * ---------------------------------------------------------------------
1935 * indent-tabs-mode: t
1939 * vim:noexpandtab:sw=4:ts=4: