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 7343 2007-02-13 02:36:29Z ajordan $
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 static void throw_exception_exit_intern(bool doexit)
174 java_objectheader *xptr;
178 xptr = *exceptionptr;
181 /* clear exception, because we are calling jit code again */
182 *exceptionptr = NULL;
184 c = xptr->vftbl->class;
186 pss = class_resolveclassmethod(c,
189 class_java_lang_Object,
192 /* print the stacktrace */
195 (void) vm_call_method(pss, xptr);
197 /* This normally means, we are EXTREMLY out of memory or have a */
198 /* serious problem while printStackTrace. But may be another */
199 /* exception, so print it. */
202 java_lang_Throwable *t;
204 t = (java_lang_Throwable *) *exceptionptr;
206 fprintf(stderr, "Exception while printStackTrace(): ");
207 utf_fprint_printable_ascii_classname(stderr, t->header.vftbl->class->name);
209 if (t->detailMessage) {
212 buf = javastring_tochar((java_objectheader *) t->detailMessage);
213 fprintf(stderr, ": %s", buf);
214 MFREE(buf, char, strlen(buf));
217 fprintf(stderr, "\n");
221 utf_fprint_printable_ascii_classname(stderr, c->name);
222 fprintf(stderr, ": printStackTrace()V not found!\n");
235 void throw_exception(void)
237 throw_exception_exit_intern(false);
241 void throw_exception_exit(void)
243 throw_exception_exit_intern(true);
247 void throw_main_exception(void)
249 fprintf(stderr, "Exception in thread \"main\" ");
252 throw_exception_exit_intern(false);
256 void throw_main_exception_exit(void)
258 fprintf(stderr, "Exception in thread \"main\" ");
261 throw_exception_exit_intern(true);
265 void throw_cacao_exception_exit(const char *exception, const char *message, ...)
272 len = strlen(exception);
273 tmp = MNEW(char, len + 1);
274 strncpy(tmp, exception, len);
277 /* convert to classname */
279 for (i = len - 1; i >= 0; i--)
280 if (tmp[i] == '/') tmp[i] = '.';
282 fprintf(stderr, "Exception in thread \"main\" %s", tmp);
284 MFREE(tmp, char, len);
286 if (strlen(message) > 0) {
287 fprintf(stderr, ": ");
289 va_start(ap, message);
290 vfprintf(stderr, message, ap);
294 fprintf(stderr, "\n");
303 /* exceptions_new_class ********************************************************
305 Creates an exception object from the given class and initalizes it.
308 class....class pointer
310 *******************************************************************************/
312 static java_objectheader *exceptions_new_class(classinfo *c)
314 java_objectheader *o;
316 o = native_new_and_init(c);
319 return *exceptionptr;
325 /* exceptions_new_utf **********************************************************
327 Creates an exception object with the given name and initalizes it.
330 classname....class name in UTF-8
332 *******************************************************************************/
334 static java_objectheader *exceptions_new_utf(utf *classname)
337 java_objectheader *o;
339 c = load_class_bootstrap(classname);
342 return *exceptionptr;
344 o = exceptions_new_class(c);
350 /* exceptions_throw_class ******************************************************
352 Creates an exception object from the given class, initalizes and
356 class....class pointer
358 *******************************************************************************/
360 static void exceptions_throw_class(classinfo *c)
362 java_objectheader *o;
364 o = exceptions_new_class(c);
373 /* exceptions_throw_utf ********************************************************
375 Creates an exception object with the given name, initalizes and
379 classname....class name in UTF-8
381 *******************************************************************************/
383 static void exceptions_throw_utf(utf *classname)
387 c = load_class_bootstrap(classname);
392 exceptions_throw_class(c);
396 /* exceptions_throw_utf_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 cause........the given Throwable
405 *******************************************************************************/
407 static void exceptions_throw_utf_throwable(utf *classname,
408 java_objectheader *cause)
410 java_objectheader *o;
413 c = load_class_bootstrap(classname);
418 o = native_new_and_init_throwable(c, cause);
427 /* exceptions_new_utf_javastring ***********************************************
429 Creates an exception object with the given name and initalizes it
430 with the given java/lang/String message.
433 classname....class name in UTF-8
434 message......the message as a java.lang.String
437 an exception pointer (in any case -- either it is the newly created
438 exception, or an exception thrown while trying to create it).
440 *******************************************************************************/
442 static java_objectheader *exceptions_new_utf_javastring(utf *classname,
443 java_objectheader *message)
445 java_objectheader *o;
448 c = load_class_bootstrap(classname);
451 return *exceptionptr;
453 o = native_new_and_init_string(c, message);
456 return *exceptionptr;
462 /* exceptions_new_class_utf ****************************************************
464 Creates an exception object of the given class and initalizes it.
467 c..........class pointer
468 message....the message as UTF-8 string
470 *******************************************************************************/
472 static java_objectheader *exceptions_new_class_utf(classinfo *c, utf *message)
474 java_objectheader *o;
475 java_objectheader *s;
477 s = javastring_new(message);
480 return *exceptionptr;
482 o = native_new_and_init_string(c, s);
485 return *exceptionptr;
491 /* exceptions_new_utf_utf ******************************************************
493 Creates an exception object with the given name and initalizes it
494 with the given utf message.
497 classname....class name in UTF-8
498 message......the message as an utf *
501 an exception pointer (in any case -- either it is the newly created
502 exception, or an exception thrown while trying to create it).
504 *******************************************************************************/
506 static java_objectheader *exceptions_new_utf_utf(utf *classname, utf *message)
509 java_objectheader *o;
511 c = load_class_bootstrap(classname);
514 return *exceptionptr;
516 o = exceptions_new_class_utf(c, message);
522 /* new_exception_message *******************************************************
524 Creates an exception object with the given name and initalizes it
525 with the given char message.
528 classname....class name in UTF-8
529 message......message in UTF-8
532 an exception pointer (in any case -- either it is the newly created
533 exception, or an exception thrown while trying to create it).
535 *******************************************************************************/
537 static java_objectheader *new_exception_message(const char *classname,
540 java_objectheader *o;
541 java_objectheader *s;
543 s = javastring_new_from_utf_string(message);
546 return *exceptionptr;
548 o = exceptions_new_utf_javastring(classname, s);
554 /* exceptions_throw_class_utf **************************************************
556 Creates an exception object of the given class, initalizes and
557 throws it with the given utf message.
560 c..........class pointer
561 message....the message as an UTF-8
563 *******************************************************************************/
565 static void exceptions_throw_class_utf(classinfo *c, utf *message)
567 *exceptionptr = exceptions_new_class_utf(c, message);
571 /* exceptions_throw_utf_utf ****************************************************
573 Creates an exception object with the given name, initalizes and
574 throws it with the given utf message.
577 classname....class name in UTF-8
578 message......the message as an utf *
580 *******************************************************************************/
582 static void exceptions_throw_utf_utf(utf *classname, utf *message)
584 *exceptionptr = exceptions_new_utf_utf(classname, message);
588 /* new_exception_int ***********************************************************
590 Creates an exception object with the given name and initalizes it
591 with the given int value.
594 classname....class name in UTF-8
595 i............the integer
598 an exception pointer (in any case -- either it is the newly created
599 exception, or an exception thrown while trying to create it).
601 *******************************************************************************/
603 java_objectheader *new_exception_int(const char *classname, s4 i)
605 java_objectheader *o;
608 if (!(c = load_class_bootstrap(utf_new_char(classname))))
609 return *exceptionptr;
611 o = native_new_and_init_int(c, i);
614 return *exceptionptr;
620 /* exceptions_new_abstractmethoderror ****************************************
622 Generates a java.lang.AbstractMethodError for the VM.
624 *******************************************************************************/
626 java_objectheader *exceptions_new_abstractmethoderror(void)
628 java_objectheader *o;
630 o = exceptions_new_utf(utf_java_lang_AbstractMethodError);
636 /* exceptions_new_error ********************************************************
638 Generates a java.lang.Error for the VM.
640 *******************************************************************************/
642 #if defined(ENABLE_JAVAME_CLDC1_1)
643 static java_objectheader *exceptions_new_error(utf *message)
645 java_objectheader *o;
647 o = exceptions_new_class_utf(class_java_lang_Error, message);
654 /* exceptions_asm_new_abstractmethoderror **************************************
656 Generates a java.lang.AbstractMethodError for
657 asm_abstractmethoderror.
659 *******************************************************************************/
661 java_objectheader *exceptions_asm_new_abstractmethoderror(u1 *sp, u1 *ra)
664 java_objectheader *e;
666 /* create the stackframeinfo (XPC is equal to RA) */
668 stacktrace_create_extern_stackframeinfo(&sfi, NULL, sp, ra, ra);
670 /* create the exception */
672 #if defined(ENABLE_JAVASE)
673 e = exceptions_new_abstractmethoderror();
675 e = exceptions_new_error(utf_java_lang_AbstractMethodError);
678 /* remove the stackframeinfo */
680 stacktrace_remove_stackframeinfo(&sfi);
686 /* exceptions_new_arraystoreexception ******************************************
688 Generates a java.lang.ArrayStoreException for the VM.
690 *******************************************************************************/
692 java_objectheader *exceptions_new_arraystoreexception(void)
694 java_objectheader *o;
696 o = exceptions_new_utf(utf_java_lang_ArrayStoreException);
702 /* exceptions_throw_abstractmethoderror ****************************************
704 Generates and throws a java.lang.AbstractMethodError for the VM.
706 *******************************************************************************/
708 void exceptions_throw_abstractmethoderror(void)
710 exceptions_throw_utf(utf_java_lang_AbstractMethodError);
714 /* exceptions_throw_classcircularityerror **************************************
716 Generates and throws a java.lang.ClassCircularityError for the
720 c............the class in which the error was found
722 *******************************************************************************/
724 void exceptions_throw_classcircularityerror(classinfo *c)
726 java_objectheader *o;
730 /* calculate message length */
732 msglen = utf_bytes(c->name) + strlen("0");
734 /* allocate a buffer */
736 msg = MNEW(char, msglen);
738 /* print message into allocated buffer */
740 utf_copy_classname(msg, c->name);
742 o = new_exception_message(utf_java_lang_ClassCircularityError, msg);
744 MFREE(msg, char, msglen);
753 /* exceptions_throw_classformaterror *******************************************
755 Generates and throws a java.lang.ClassFormatError for the VM.
758 c............the class in which the error was found
759 message......UTF-8 format string
761 *******************************************************************************/
763 void exceptions_throw_classformaterror(classinfo *c, const char *message, ...)
765 java_objectheader *o;
770 /* calculate message length */
775 msglen += utf_bytes(c->name) + strlen(" (");
777 va_start(ap, message);
778 msglen += get_variable_message_length(message, ap);
782 msglen += strlen(")");
784 msglen += strlen("0");
786 /* allocate a buffer */
788 msg = MNEW(char, msglen);
790 /* print message into allocated buffer */
793 utf_copy_classname(msg, c->name);
797 va_start(ap, message);
798 vsprintf(msg + strlen(msg), message, ap);
804 o = new_exception_message(utf_java_lang_ClassFormatError, msg);
806 MFREE(msg, char, msglen);
812 /* exceptions_throw_classnotfoundexception *************************************
814 Generates and throws a java.lang.ClassNotFoundException for the
818 name.........name of the class not found as a utf *
820 *******************************************************************************/
822 void exceptions_throw_classnotfoundexception(utf *name)
824 /* we use class here, as this one is rather frequent */
826 exceptions_throw_class_utf(class_java_lang_ClassNotFoundException, name);
830 /* exceptions_throw_noclassdeffounderror ***************************************
832 Generates and throws a java.lang.NoClassDefFoundError.
835 name.........name of the class not found as a utf *
837 *******************************************************************************/
839 void exceptions_throw_noclassdeffounderror(utf *name)
841 exceptions_throw_class_utf(class_java_lang_NoClassDefFoundError, name);
845 /* classnotfoundexception_to_noclassdeffounderror ******************************
847 Check the *exceptionptr for a ClassNotFoundException. If it is one,
848 convert it to a NoClassDefFoundError.
850 *******************************************************************************/
852 void classnotfoundexception_to_noclassdeffounderror(void)
854 java_objectheader *xptr;
855 java_objectheader *cause;
856 java_lang_Throwable *t;
861 cause = *exceptionptr;
863 /* convert ClassNotFoundException's to NoClassDefFoundError's */
865 if (builtin_instanceof(cause, class_java_lang_ClassNotFoundException)) {
866 /* clear exception, because we are calling jit code again */
868 *exceptionptr = NULL;
870 /* create new error */
872 t = (java_lang_Throwable *) cause;
873 s = t->detailMessage;
875 xptr = exceptions_new_utf_javastring(utf_java_lang_NoClassDefFoundError, s);
877 /* we had an exception while creating the error */
882 /* set new exception */
884 *exceptionptr = xptr;
889 /* exceptions_throw_exceptionininitializererror ********************************
891 Generates and throws a java.lang.ExceptionInInitializerError for
895 cause......cause exception object
897 *******************************************************************************/
899 void exceptions_throw_exceptionininitializererror(java_objectheader *cause)
901 exceptions_throw_utf_throwable(utf_java_lang_ExceptionInInitializerError,
906 /* exceptions_throw_incompatibleclasschangeerror *******************************
908 Generates and throws a java.lang.IncompatibleClassChangeError for
912 message......UTF-8 message format string
914 *******************************************************************************/
916 void exceptions_throw_incompatibleclasschangeerror(classinfo *c, const char *message)
918 java_objectheader *o;
922 /* calculate exception message length */
924 msglen = utf_bytes(c->name) + strlen(message) + strlen("0");
926 /* allocate memory */
928 msg = MNEW(char, msglen);
930 utf_copy_classname(msg, c->name);
931 strcat(msg, message);
933 o = native_new_and_init_string(utf_java_lang_IncompatibleClassChangeError,
934 javastring_new_from_utf_string(msg));
938 MFREE(msg, char, msglen);
947 /* exceptions_throw_instantiationerror *****************************************
949 Generates and throws a java.lang.InstantiationError for the VM.
951 *******************************************************************************/
953 void exceptions_throw_instantiationerror(classinfo *c)
955 exceptions_throw_utf_utf(utf_java_lang_InstantiationError, c->name);
959 /* exceptions_throw_internalerror **********************************************
961 Generates and throws a java.lang.InternalError for the VM.
964 message......UTF-8 message format string
966 *******************************************************************************/
968 void exceptions_throw_internalerror(const char *message, ...)
970 java_objectheader *o;
975 /* calculate exception message length */
977 va_start(ap, message);
978 msglen = get_variable_message_length(message, ap);
981 /* allocate memory */
983 msg = MNEW(char, msglen);
985 /* generate message */
987 va_start(ap, message);
988 vsprintf(msg, message, ap);
991 /* create exception object */
993 o = new_exception_message(utf_java_lang_InternalError, msg);
997 MFREE(msg, char, msglen);
1006 /* exceptions_throw_linkageerror ***********************************************
1008 Generates and throws java.lang.LinkageError with an error message.
1011 message......UTF-8 message
1012 c............class related to the error. If this is != NULL
1013 the name of c is appended to the error message.
1015 *******************************************************************************/
1017 void exceptions_throw_linkageerror(const char *message, classinfo *c)
1019 java_objectheader *o;
1023 /* calculate exception message length */
1025 msglen = strlen(message) + 1;
1028 msglen += utf_bytes(c->name);
1030 /* allocate memory */
1032 msg = MNEW(char, msglen);
1034 /* generate message */
1036 strcpy(msg,message);
1039 utf_cat_classname(msg, c->name);
1041 o = native_new_and_init_string(class_java_lang_LinkageError,
1042 javastring_new_from_utf_string(msg));
1046 MFREE(msg, char, msglen);
1055 /* exceptions_throw_nosuchfielderror *******************************************
1057 Generates and throws a java.lang.NoSuchFieldError with an error
1061 c............class in which the field was not found
1062 name.........name of the field
1064 *******************************************************************************/
1066 void exceptions_throw_nosuchfielderror(classinfo *c, utf *name)
1072 /* calculate exception message length */
1074 msglen = utf_bytes(c->name) + strlen(".") + utf_bytes(name) + strlen("0");
1076 /* allocate memory */
1078 msg = MNEW(char, msglen);
1080 /* generate message */
1082 utf_copy_classname(msg, c->name);
1086 u = utf_new_char(msg);
1090 MFREE(msg, char, msglen);
1092 exceptions_throw_utf_utf(utf_java_lang_NoSuchFieldError, u);
1096 /* exceptions_throw_nosuchmethoderror ******************************************
1098 Generates and throws a java.lang.NoSuchMethodError with an error
1102 c............class in which the method was not found
1103 name.........name of the method
1104 desc.........descriptor of the method
1106 *******************************************************************************/
1108 void exceptions_throw_nosuchmethoderror(classinfo *c, utf *name, utf *desc)
1114 /* calculate exception message length */
1116 msglen = utf_bytes(c->name) + strlen(".") + utf_bytes(name) +
1117 utf_bytes(desc) + strlen("0");
1119 /* allocate memory */
1121 msg = MNEW(char, msglen);
1123 /* generate message */
1125 utf_copy_classname(msg, c->name);
1130 u = utf_new_char(msg);
1134 MFREE(msg, char, msglen);
1136 exceptions_throw_utf_utf(utf_java_lang_NoSuchMethodError, u);
1140 /* exceptions_throw_outofmemoryerror *******************************************
1142 Generates and throws an java.lang.OutOfMemoryError for the VM.
1144 *******************************************************************************/
1146 void exceptions_throw_outofmemoryerror(void)
1148 exceptions_throw_class(class_java_lang_OutOfMemoryError);
1152 /* exceptions_throw_unsatisfiedlinkerror ***************************************
1154 Generates and throws a java.lang.UnsatisfiedLinkError for the
1158 name......UTF-8 name string
1160 *******************************************************************************/
1162 void exceptions_throw_unsatisfiedlinkerror(utf *name)
1164 #if defined(ENABLE_JAVASE)
1165 exceptions_throw_utf_utf(utf_java_lang_UnsatisfiedLinkError, name);
1167 exceptions_throw_class_utf(class_java_lang_Error, name);
1172 /* exceptions_throw_unsupportedclassversionerror *******************************
1174 Generates and throws a java.lang.UnsupportedClassVersionError for
1178 c............class in which the method was not found
1179 message......UTF-8 format string
1181 *******************************************************************************/
1183 void exceptions_throw_unsupportedclassversionerror(classinfo *c, u4 ma, u4 mi)
1185 java_objectheader *o;
1189 /* calculate exception message length */
1192 utf_bytes(c->name) +
1193 strlen(" (Unsupported major.minor version 00.0)") +
1196 /* allocate memory */
1198 msg = MNEW(char, msglen);
1200 /* generate message */
1202 utf_copy_classname(msg, c->name);
1203 sprintf(msg + strlen(msg), " (Unsupported major.minor version %d.%d)",
1206 /* create exception object */
1208 o = new_exception_message(utf_java_lang_UnsupportedClassVersionError, msg);
1212 MFREE(msg, char, msglen);
1221 /* exceptions_throw_verifyerror ************************************************
1223 Generates and throws a java.lang.VerifyError for the JIT compiler.
1226 m............method in which the error was found
1227 message......UTF-8 format string
1229 *******************************************************************************/
1231 void exceptions_throw_verifyerror(methodinfo *m, const char *message, ...)
1233 java_objectheader *o;
1238 /* calculate exception message length */
1244 strlen("(class: ") + utf_bytes(m->class->name) +
1245 strlen(", method: ") + utf_bytes(m->name) +
1246 strlen(" signature: ") + utf_bytes(m->descriptor) +
1247 strlen(") ") + strlen("0");
1249 va_start(ap, message);
1250 msglen += get_variable_message_length(message, ap);
1253 /* allocate memory */
1255 msg = MNEW(char, msglen);
1257 /* generate message */
1260 strcpy(msg, "(class: ");
1261 utf_cat_classname(msg, m->class->name);
1262 strcat(msg, ", method: ");
1263 utf_cat(msg, m->name);
1264 strcat(msg, " signature: ");
1265 utf_cat(msg, m->descriptor);
1269 va_start(ap, message);
1270 vsprintf(msg + strlen(msg), message, ap);
1273 /* create exception object */
1275 o = new_exception_message(utf_java_lang_VerifyError, msg);
1279 MFREE(msg, char, msglen);
1285 /* exceptions_throw_verifyerror_for_stack **************************************
1287 throws a java.lang.VerifyError for an invalid stack slot type
1290 m............method in which the error was found
1291 type.........the expected type
1294 an exception pointer (in any case -- either it is the newly created
1295 exception, or an exception thrown while trying to create it).
1297 *******************************************************************************/
1299 void exceptions_throw_verifyerror_for_stack(methodinfo *m,int type)
1301 java_objectheader *o;
1306 /* calculate exception message length */
1311 msglen = strlen("(class: ") + utf_bytes(m->class->name) +
1312 strlen(", method: ") + utf_bytes(m->name) +
1313 strlen(" signature: ") + utf_bytes(m->descriptor) +
1314 strlen(") Expecting to find longest-------typename on stack")
1317 /* allocate memory */
1319 msg = MNEW(char, msglen);
1321 /* generate message */
1324 strcpy(msg, "(class: ");
1325 utf_cat_classname(msg, m->class->name);
1326 strcat(msg, ", method: ");
1327 utf_cat(msg, m->name);
1328 strcat(msg, " signature: ");
1329 utf_cat(msg, m->descriptor);
1336 strcat(msg,"Expecting to find ");
1338 case TYPE_INT: typename = "integer"; break;
1339 case TYPE_LNG: typename = "long"; break;
1340 case TYPE_FLT: typename = "float"; break;
1341 case TYPE_DBL: typename = "double"; break;
1342 case TYPE_ADR: typename = "object/array"; break;
1343 case TYPE_RET: typename = "returnAddress"; break;
1344 default: typename = "<INVALID>"; assert(0); break;
1346 strcat(msg, typename);
1347 strcat(msg, " on stack");
1349 /* create exception object */
1351 o = new_exception_message(utf_java_lang_VerifyError, msg);
1355 MFREE(msg, char, msglen);
1361 /* exceptions_new_arithmeticexception ******************************************
1363 Generates a java.lang.ArithmeticException for the JIT compiler.
1365 *******************************************************************************/
1367 java_objectheader *exceptions_new_arithmeticexception(void)
1369 java_objectheader *o;
1371 o = new_exception_message(utf_java_lang_ArithmeticException, "/ by zero");
1374 return *exceptionptr;
1380 /* exceptions_new_arrayindexoutofboundsexception *******************************
1382 Generates a java.lang.ArrayIndexOutOfBoundsException for the VM
1385 *******************************************************************************/
1387 java_objectheader *exceptions_new_arrayindexoutofboundsexception(s4 index)
1389 java_objectheader *o;
1391 java_objectheader *s;
1393 /* convert the index into a String, like Sun does */
1395 m = class_resolveclassmethod(class_java_lang_String,
1396 utf_new_char("valueOf"),
1397 utf_new_char("(I)Ljava/lang/String;"),
1398 class_java_lang_Object,
1402 return *exceptionptr;
1404 s = vm_call_method(m, NULL, index);
1407 return *exceptionptr;
1409 o = exceptions_new_utf_javastring(utf_java_lang_ArrayIndexOutOfBoundsException,
1413 return *exceptionptr;
1419 /* exceptions_throw_arrayindexoutofboundsexception *****************************
1421 Generates and throws a java.lang.ArrayIndexOutOfBoundsException for
1424 *******************************************************************************/
1426 void exceptions_throw_arrayindexoutofboundsexception(void)
1428 exceptions_throw_utf(utf_java_lang_ArrayIndexOutOfBoundsException);
1432 /* exceptions_throw_arraystoreexception ****************************************
1434 Generates and throws a java.lang.ArrayStoreException for the VM.
1436 *******************************************************************************/
1438 void exceptions_throw_arraystoreexception(void)
1440 exceptions_throw_utf(utf_java_lang_ArrayStoreException);
1441 /* e = native_new_and_init(class_java_lang_ArrayStoreException); */
1445 /* exceptions_new_classcastexception *******************************************
1447 Generates a java.lang.ClassCastException for the JIT compiler.
1449 *******************************************************************************/
1451 java_objectheader *exceptions_new_classcastexception(java_objectheader *o)
1453 java_objectheader *e;
1455 java_lang_String *s;
1457 classname = o->vftbl->class->name;
1459 s = javastring_new(classname);
1461 e = native_new_and_init_string(class_java_lang_ClassCastException, s);
1464 return *exceptionptr;
1470 /* exceptions_throw_clonenotsupportedexception *********************************
1472 Generates and throws a java.lang.CloneNotSupportedException for the
1475 *******************************************************************************/
1477 void exceptions_throw_clonenotsupportedexception(void)
1479 exceptions_throw_utf(utf_java_lang_CloneNotSupportedException);
1483 /* exceptions_throw_illegalaccessexception *************************************
1485 Generates and throws a java.lang.IllegalAccessException for the VM.
1487 *******************************************************************************/
1489 void exceptions_throw_illegalaccessexception(classinfo *c)
1491 /* XXX handle argument */
1493 exceptions_throw_utf(utf_java_lang_IllegalAccessException);
1497 /* exceptions_throw_illegalargumentexception ***********************************
1499 Generates and throws a java.lang.IllegalArgumentException for the
1502 *******************************************************************************/
1504 void exceptions_throw_illegalargumentexception(void)
1506 exceptions_throw_utf(utf_java_lang_IllegalArgumentException);
1510 /* exceptions_throw_illegalmonitorstateexception *******************************
1512 Generates and throws a java.lang.IllegalMonitorStateException for
1515 *******************************************************************************/
1517 void exceptions_throw_illegalmonitorstateexception(void)
1519 exceptions_throw_utf(utf_java_lang_IllegalMonitorStateException);
1523 /* exceptions_throw_instantiationexception *************************************
1525 Generates and throws a java.lang.InstantiationException for the VM.
1527 *******************************************************************************/
1529 void exceptions_throw_instantiationexception(classinfo *c)
1531 exceptions_throw_utf_utf(utf_java_lang_InstantiationException, c->name);
1535 /* exceptions_throw_interruptedexception ***************************************
1537 Generates and throws a java.lang.InterruptedException for the VM.
1539 *******************************************************************************/
1541 void exceptions_throw_interruptedexception(void)
1543 exceptions_throw_utf(utf_java_lang_InterruptedException);
1547 /* exceptions_throw_invocationtargetexception **********************************
1549 Generates and throws a java.lang.reflect.InvocationTargetException
1553 cause......cause exception object
1555 *******************************************************************************/
1557 void exceptions_throw_invocationtargetexception(java_objectheader *cause)
1559 exceptions_throw_utf_throwable(utf_java_lang_reflect_InvocationTargetException,
1564 /* exceptions_throw_negativearraysizeexception *********************************
1566 Generates and throws a java.lang.NegativeArraySizeException for the
1569 *******************************************************************************/
1571 void exceptions_throw_negativearraysizeexception(void)
1573 exceptions_throw_utf(utf_java_lang_NegativeArraySizeException);
1577 /* exceptions_new_nullpointerexception *****************************************
1579 Generates a java.lang.NullPointerException for the VM system.
1581 *******************************************************************************/
1583 java_objectheader *exceptions_new_nullpointerexception(void)
1585 java_objectheader *o;
1587 o = exceptions_new_class(class_java_lang_NullPointerException);
1593 /* exceptions_throw_nullpointerexception ***************************************
1595 Generates a java.lang.NullPointerException for the VM system and
1596 throw it in the VM system.
1598 *******************************************************************************/
1600 void exceptions_throw_nullpointerexception(void)
1602 exceptions_throw_class(class_java_lang_NullPointerException);
1606 /* exceptions_throw_stringindexoutofboundsexception ****************************
1608 Generates and throws a java.lang.StringIndexOutOfBoundsException
1611 *******************************************************************************/
1613 void exceptions_throw_stringindexoutofboundsexception(void)
1615 exceptions_throw_utf(utf_java_lang_StringIndexOutOfBoundsException);
1619 /* exceptions_get_exception ****************************************************
1621 Returns the current exception pointer of the current thread.
1623 *******************************************************************************/
1625 java_objectheader *exceptions_get_exception(void)
1627 /* return the exception */
1629 return *exceptionptr;
1633 /* exceptions_set_exception ****************************************************
1635 Sets the exception pointer of the current thread.
1637 *******************************************************************************/
1639 void exceptions_set_exception(java_objectheader *o)
1641 /* set the exception */
1647 /* exceptions_clear_exception **************************************************
1649 Clears the current exception pointer of the current thread.
1651 *******************************************************************************/
1653 void exceptions_clear_exception(void)
1655 /* and clear the exception */
1657 *exceptionptr = NULL;
1661 /* exceptions_get_and_clear_exception ******************************************
1663 Gets the exception pointer of the current thread and clears it.
1664 This function may return NULL.
1666 *******************************************************************************/
1668 java_objectheader *exceptions_get_and_clear_exception(void)
1670 java_objectheader **p;
1671 java_objectheader *e;
1673 /* get the pointer of the exception pointer */
1677 /* get the exception */
1681 /* and clear the exception */
1685 /* return the exception */
1691 /* exceptions_handle_exception *************************************************
1693 Try to find an exception handler for the given exception and return it.
1694 If no handler is found, exit the monitor of the method (if any)
1698 xptr.........the exception object
1699 xpc..........PC of where the exception was thrown
1700 pv...........Procedure Value of the current method
1701 sp...........current stack pointer
1704 the address of the first matching exception handler, or
1705 NULL if no handler was found
1707 *******************************************************************************/
1709 #if defined(ENABLE_JIT)
1710 u1 *exceptions_handle_exception(java_objectheader *xptr, u1 *xpc, u1 *pv, u1 *sp)
1715 dseg_exception_entry *ex;
1716 s4 exceptiontablelength;
1718 classref_or_classinfo cr;
1720 #if defined(ENABLE_THREADS)
1721 java_objectheader *o;
1724 /* get info from the method header */
1726 code = *((codeinfo **) (pv + CodeinfoPointer));
1727 issync = *((s4 *) (pv + IsSync));
1728 ex = (dseg_exception_entry *) (pv + ExTableStart);
1729 exceptiontablelength = *((s4 *) (pv + ExTableSize));
1731 /* Get the methodinfo pointer from the codeinfo pointer. For
1732 asm_vm_call_method the codeinfo pointer is NULL. */
1734 m = (code == NULL) ? NULL : code->m;
1736 #if !defined(NDEBUG)
1737 /* print exception trace */
1739 if (opt_verbose || opt_verbosecall || opt_verboseexception)
1740 builtin_trace_exception(xptr, m, xpc, 1);
1743 for (i = 0; i < exceptiontablelength; i++) {
1744 /* ATTENTION: keep this here, as we need to decrement the
1745 pointer before the loop executes! */
1749 /* If the start and end PC is NULL, this means we have the
1750 special case of asm_vm_call_method. So, just return the
1751 proper exception handler. */
1753 if ((ex->startpc == NULL) && (ex->endpc == NULL))
1754 return (u1 *) (ptrint) &asm_vm_call_method_exception_handler;
1756 /* is the xpc is the current catch range */
1758 if ((ex->startpc <= xpc) && (xpc < ex->endpc)) {
1761 /* NULL catches everything */
1763 if (cr.any == NULL) {
1764 #if !defined(NDEBUG)
1765 /* Print stacktrace of exception when caught. */
1767 if (opt_verboseexception) {
1768 exceptions_print_exception(xptr);
1769 stacktrace_print_trace(xptr);
1773 return ex->handlerpc;
1776 /* resolve or load/link the exception class */
1778 if (IS_CLASSREF(cr)) {
1779 /* The exception class reference is unresolved. */
1780 /* We have to do _eager_ resolving here. While the class of */
1781 /* the exception object is guaranteed to be loaded, it may */
1782 /* well have been loaded by a different loader than the */
1783 /* defining loader of m's class, which is the one we must */
1784 /* use to resolve the catch class. Thus lazy resolving */
1785 /* might fail, even if the result of the resolution would */
1786 /* be an already loaded class. */
1788 c = resolve_classref_eager(cr.ref);
1791 /* Exception resolving the exception class, argh! */
1795 /* Ok, we resolved it. Enter it in the table, so we don't */
1796 /* have to do this again. */
1797 /* XXX this write should be atomic. Is it? */
1799 ex->catchtype.cls = c;
1803 /* XXX I don't think this case can ever happen. -Edwin */
1804 if (!(c->state & CLASS_LOADED))
1805 /* use the methods' classloader */
1806 if (!load_class_from_classloader(c->name,
1807 m->class->classloader))
1810 /* XXX I think, if it is not linked, we can be sure that */
1811 /* the exception object is no (indirect) instance of it, no? */
1813 if (!(c->state & CLASS_LINKED))
1818 /* is the thrown exception an instance of the catch class? */
1820 if (builtin_instanceof(xptr, c)) {
1821 #if !defined(NDEBUG)
1822 /* Print stacktrace of exception when caught. */
1824 if (opt_verboseexception) {
1825 exceptions_print_exception(xptr);
1826 stacktrace_print_trace(xptr);
1830 return ex->handlerpc;
1835 #if defined(ENABLE_THREADS)
1836 /* is this method synchronized? */
1839 /* get synchronization object */
1841 # if defined(__MIPS__) && (SIZEOF_VOID_P == 4)
1842 /* XXX change this if we ever want to use 4-byte stackslots */
1843 o = *((java_objectheader **) (sp + issync - 8));
1845 o = *((java_objectheader **) (sp + issync - SIZEOF_VOID_P));
1850 lock_monitor_exit(o);
1854 /* none of the exceptions catch this one */
1858 #endif /* defined(ENABLE_JIT) */
1861 /* exceptions_print_exception **************************************************
1863 Prints an exception, the detail message and the cause, if
1864 available, with CACAO internal functions to stdout.
1866 *******************************************************************************/
1868 void exceptions_print_exception(java_objectheader *xptr)
1870 java_lang_Throwable *t;
1871 #if defined(ENABLE_JAVASE)
1872 java_lang_Throwable *cause;
1876 t = (java_lang_Throwable *) xptr;
1883 #if defined(ENABLE_JAVASE)
1887 /* print the root exception */
1889 utf_display_printable_ascii_classname(t->header.vftbl->class->name);
1891 if (t->detailMessage != NULL) {
1892 u = javastring_toutf(t->detailMessage, false);
1895 utf_display_printable_ascii(u);
1900 #if defined(ENABLE_JAVASE)
1901 /* print the cause if available */
1903 if ((cause != NULL) && (cause != t)) {
1904 printf("Caused by: ");
1905 utf_display_printable_ascii_classname(cause->header.vftbl->class->name);
1907 if (cause->detailMessage) {
1908 u = javastring_toutf(cause->detailMessage, false);
1911 utf_display_printable_ascii(u);
1920 /* exceptions_print_current_exception ******************************************
1922 Prints the current pending exception, the detail message and the
1923 cause, if available, with CACAO internal functions to stdout.
1925 *******************************************************************************/
1927 void exceptions_print_current_exception(void)
1929 java_objectheader *xptr;
1931 xptr = *exceptionptr;
1933 exceptions_print_exception(xptr);
1938 * These are local overrides for various environment variables in Emacs.
1939 * Please do not remove this and leave it at the end of the file, where
1940 * Emacs will automagically detect them.
1941 * ---------------------------------------------------------------------
1944 * indent-tabs-mode: t
1948 * vim:noexpandtab:sw=4:ts=4: