1 /* src/vm/exceptions.c - exception related functions
3 Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
4 R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
5 C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
6 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., 59 Temple Place - Suite 330, Boston, MA
25 Contact: cacao@complang.tuwien.ac.at
27 Authors: Christian Thalinger
29 Changes: Edwin Steiner
31 $Id: exceptions.c 3807 2005-11-26 21:51:11Z edwin $
42 #include "mm/memory.h"
43 #include "native/native.h"
44 #include "native/include/java_lang_String.h"
45 #include "native/include/java_lang_Throwable.h"
46 #include "toolbox/logging.h"
47 #include "toolbox/util.h"
49 #include "vm/exceptions.h"
50 #include "vm/global.h"
51 #include "vm/loader.h"
52 #include "vm/options.h"
53 #include "vm/stringlocal.h"
54 #include "vm/tables.h"
55 #include "vm/jit/asmpart.h"
56 #include "vm/jit/jit.h"
59 /* for raising exceptions from native methods *********************************/
61 #if !defined(USE_THREADS) || !defined(NATIVE_THREADS)
62 java_objectheader *_no_threads_exceptionptr = NULL;
66 /* init_system_exceptions ******************************************************
68 Load and link exceptions used in the system.
70 *******************************************************************************/
72 bool exceptions_init(void)
74 /* java/lang/Throwable */
76 if (!(class_java_lang_Throwable =
77 load_class_bootstrap(utf_java_lang_Throwable)) ||
78 !link_class(class_java_lang_Throwable))
82 /* java/lang/VMThrowable */
84 if (!(class_java_lang_VMThrowable =
85 load_class_bootstrap(utf_java_lang_VMThrowable)) ||
86 !link_class(class_java_lang_VMThrowable))
92 if (!(class_java_lang_Error = load_class_bootstrap(utf_java_lang_Error)) ||
93 !link_class(class_java_lang_Error))
96 /* java/lang/NoClassDefFoundError */
98 if (!(class_java_lang_NoClassDefFoundError =
99 load_class_bootstrap(utf_java_lang_NoClassDefFoundError)) ||
100 !link_class(class_java_lang_NoClassDefFoundError))
103 /* java/lang/LinkageError */
105 if (!(class_java_lang_LinkageError =
106 load_class_bootstrap(utf_java_lang_LinkageError)) ||
107 !link_class(class_java_lang_LinkageError))
110 /* java/lang/NoSuchMethodError */
112 if (!(class_java_lang_NoSuchMethodError =
113 load_class_bootstrap(utf_java_lang_NoSuchMethodError)) ||
114 !link_class(class_java_lang_NoSuchMethodError))
117 /* java/lang/OutOfMemoryError */
119 if (!(class_java_lang_OutOfMemoryError =
120 load_class_bootstrap(utf_java_lang_OutOfMemoryError)) ||
121 !link_class(class_java_lang_OutOfMemoryError))
125 /* java/lang/Exception */
127 if (!(class_java_lang_Exception =
128 load_class_bootstrap(utf_java_lang_Exception)) ||
129 !link_class(class_java_lang_Exception))
132 /* java/lang/ClassNotFoundException */
134 if (!(class_java_lang_ClassNotFoundException =
135 load_class_bootstrap(utf_java_lang_ClassNotFoundException)) ||
136 !link_class(class_java_lang_ClassNotFoundException))
139 /* java/lang/IllegalArgumentException */
141 if (!(class_java_lang_IllegalArgumentException =
142 load_class_bootstrap(utf_java_lang_IllegalArgumentException)) ||
143 !link_class(class_java_lang_IllegalArgumentException))
146 /* java/lang/IllegalMonitorStateException */
148 if (!(class_java_lang_IllegalMonitorStateException =
149 load_class_bootstrap(utf_java_lang_IllegalMonitorStateException)) ||
150 !link_class(class_java_lang_IllegalMonitorStateException))
153 /* java/lang/NullPointerException */
155 if (!(class_java_lang_NullPointerException =
156 load_class_bootstrap(utf_java_lang_NullPointerException)) ||
157 !link_class(class_java_lang_NullPointerException))
165 static void throw_exception_exit_intern(bool doexit)
167 java_objectheader *xptr;
171 xptr = *exceptionptr;
174 /* clear exception, because we are calling jit code again */
175 *exceptionptr = NULL;
177 c = xptr->vftbl->class;
179 pss = class_resolveclassmethod(c,
182 class_java_lang_Object,
185 /* print the stacktrace */
187 asm_calljavafunction(pss, xptr, NULL, NULL, NULL);
189 /* This normally means, we are EXTREMLY out of memory or have a */
190 /* serious problem while printStackTrace. But may be another */
191 /* exception, so print it. */
194 java_lang_Throwable *t;
196 t = (java_lang_Throwable *) *exceptionptr;
198 fprintf(stderr, "Exception while printStackTrace(): ");
199 utf_fprint_classname(stderr, t->header.vftbl->class->name);
201 if (t->detailMessage) {
204 buf = javastring_tochar((java_objectheader *) t->detailMessage);
205 fprintf(stderr, ": %s", buf);
206 MFREE(buf, char, strlen(buf));
209 fprintf(stderr, "\n");
213 utf_fprint_classname(stderr, c->name);
214 fprintf(stderr, ": printStackTrace()V not found!\n");
227 void throw_exception(void)
229 throw_exception_exit_intern(false);
233 void throw_exception_exit(void)
235 throw_exception_exit_intern(true);
239 void throw_main_exception(void)
241 fprintf(stderr, "Exception in thread \"main\" ");
244 throw_exception_exit_intern(false);
248 void throw_main_exception_exit(void)
250 fprintf(stderr, "Exception in thread \"main\" ");
253 throw_exception_exit_intern(true);
257 void throw_cacao_exception_exit(const char *exception, const char *message, ...)
264 len = strlen(exception);
265 tmp = MNEW(char, len + 1);
266 strncpy(tmp, exception, len);
269 /* convert to classname */
271 for (i = len - 1; i >= 0; i--)
272 if (tmp[i] == '/') tmp[i] = '.';
274 fprintf(stderr, "Exception in thread \"main\" %s", tmp);
276 MFREE(tmp, char, len);
278 if (strlen(message) > 0) {
279 fprintf(stderr, ": ");
281 va_start(ap, message);
282 vfprintf(stderr, message, ap);
286 fprintf(stderr, "\n");
295 /* exceptions_throw_outofmemory_exit *******************************************
297 Just print an: java.lang.InternalError: Out of memory
299 *******************************************************************************/
301 void exceptions_throw_outofmemory_exit(void)
303 throw_cacao_exception_exit(string_java_lang_InternalError,
308 /* new_exception ***************************************************************
310 Creates an exception object with the given name and initalizes it.
312 *******************************************************************************/
314 java_objectheader *new_exception(const char *classname)
316 java_objectheader *o;
319 if (!(c = load_class_bootstrap(utf_new_char(classname))))
320 return *exceptionptr;
322 o = native_new_and_init(c);
325 return *exceptionptr;
331 /* new_exception_message *******************************************************
333 Creates an exception object with the given name and initalizes it
334 with the given char message.
336 *******************************************************************************/
338 java_objectheader *new_exception_message(const char *classname,
341 java_objectheader *o;
344 if (!(c = load_class_bootstrap(utf_new_char(classname))))
345 return *exceptionptr;
347 o = native_new_and_init_string(c, javastring_new_char(message));
350 return *exceptionptr;
356 /* new_exception_throwable *****************************************************
358 Creates an exception object with the given name and initalizes it
359 with the given java/lang/Throwable exception.
361 *******************************************************************************/
363 java_objectheader *new_exception_throwable(const char *classname,
364 java_lang_Throwable *throwable)
366 java_objectheader *o;
369 if (!(c = load_class_bootstrap(utf_new_char(classname))))
370 return *exceptionptr;
372 o = native_new_and_init_throwable(c, throwable);
375 return *exceptionptr;
381 /* new_exception_utfmessage ****************************************************
383 Creates an exception object with the given name and initalizes it
384 with the given utf message.
386 *******************************************************************************/
388 java_objectheader *new_exception_utfmessage(const char *classname, utf *message)
390 java_objectheader *o;
393 if (!(c = load_class_bootstrap(utf_new_char(classname))))
394 return *exceptionptr;
396 o = native_new_and_init_string(c, javastring_new(message));
399 return *exceptionptr;
405 /* new_exception_javastring ****************************************************
407 Creates an exception object with the given name and initalizes it
408 with the given java/lang/String message.
410 *******************************************************************************/
412 java_objectheader *new_exception_javastring(const char *classname,
413 java_lang_String *message)
415 java_objectheader *o;
418 if (!(c = load_class_bootstrap(utf_new_char(classname))))
419 return *exceptionptr;
421 o = native_new_and_init_string(c, message);
424 return *exceptionptr;
430 /* new_exception_int ***********************************************************
432 Creates an exception object with the given name and initalizes it
433 with the given int value.
435 *******************************************************************************/
437 java_objectheader *new_exception_int(const char *classname, s4 i)
439 java_objectheader *o;
442 if (!(c = load_class_bootstrap(utf_new_char(classname))))
443 return *exceptionptr;
445 o = native_new_and_init_int(c, i);
448 return *exceptionptr;
454 /* new_classformaterror ********************************************************
456 generates a java.lang.ClassFormatError for the classloader
458 *******************************************************************************/
460 java_objectheader *new_classformaterror(classinfo *c, const char *message, ...)
462 java_objectheader *o;
467 /* calculate message length */
472 msglen += utf_strlen(c->name) + strlen(" (");
474 va_start(ap, message);
475 msglen += get_variable_message_length(message, ap);
479 msglen += strlen(")");
481 msglen += strlen("0");
483 /* allocate a buffer */
485 msg = MNEW(char, msglen);
487 /* print message into allocated buffer */
490 utf_sprint_classname(msg, c->name);
494 va_start(ap, message);
495 vsprintf(msg + strlen(msg), message, ap);
501 o = new_exception_message(string_java_lang_ClassFormatError, msg);
503 MFREE(msg, char, msglen);
509 /* new_classnotfoundexception **************************************************
511 Generates a java.lang.ClassNotFoundException for the classloader.
513 *******************************************************************************/
515 java_objectheader *new_classnotfoundexception(utf *name)
517 java_objectheader *o;
519 o = native_new_and_init_string(class_java_lang_ClassNotFoundException,
520 javastring_new(name));
523 return *exceptionptr;
529 /* new_noclassdeffounderror ****************************************************
531 Generates a java.lang.NoClassDefFoundError
533 *******************************************************************************/
535 java_objectheader *new_noclassdeffounderror(utf *name)
537 java_objectheader *o;
539 o = native_new_and_init_string(class_java_lang_NoClassDefFoundError,
540 javastring_new(name));
543 return *exceptionptr;
549 /* classnotfoundexception_to_noclassdeffounderror ******************************
551 Check the *exceptionptr for a ClassNotFoundException. If it is one,
552 convert it to a NoClassDefFoundError.
554 *******************************************************************************/
556 void classnotfoundexception_to_noclassdeffounderror(void)
558 java_objectheader *xptr;
559 java_objectheader *cause;
563 cause = *exceptionptr;
565 /* convert ClassNotFoundException's to NoClassDefFoundError's */
567 if (builtin_instanceof(cause, class_java_lang_ClassNotFoundException)) {
568 /* clear exception, because we are calling jit code again */
570 *exceptionptr = NULL;
572 /* create new error */
575 new_exception_javastring(string_java_lang_NoClassDefFoundError,
576 ((java_lang_Throwable *) cause)->detailMessage);
578 /* we had an exception while creating the error */
583 /* set new exception */
585 *exceptionptr = xptr;
590 /* new_internalerror ***********************************************************
592 Generates a java.lang.InternalError for the VM.
594 *******************************************************************************/
596 java_objectheader *new_internalerror(const char *message, ...)
598 java_objectheader *o;
603 /* calculate exception message length */
605 va_start(ap, message);
606 msglen = get_variable_message_length(message, ap);
609 /* allocate memory */
611 msg = MNEW(char, msglen);
613 /* generate message */
615 va_start(ap, message);
616 vsprintf(msg, message, ap);
619 /* create exception object */
621 o = new_exception_message(string_java_lang_InternalError, msg);
625 MFREE(msg, char, msglen);
631 /* exceptions_new_linkageerror *************************************************
633 Generates a java.lang.LinkageError with an error message.
634 If c != NULL, the name of c is appended to the error message.
636 *******************************************************************************/
638 java_objectheader *exceptions_new_linkageerror(const char *message,
641 java_objectheader *o;
645 /* calculate exception message length */
647 msglen = strlen(message) + 1;
649 msglen += utf_strlen(c->name);
652 /* allocate memory */
654 msg = MNEW(char, msglen);
656 /* generate message */
660 utf_strcat(msg, c->name);
663 o = native_new_and_init_string(class_java_lang_LinkageError,
664 javastring_new_char(msg));
668 MFREE(msg, char, msglen);
674 /* exceptions_new_nosuchmethoderror ********************************************
676 Generates a java.lang.NoSuchMethodError with an error message.
678 *******************************************************************************/
680 java_objectheader *exceptions_new_nosuchmethoderror(classinfo *c,
681 utf *name, utf *desc)
683 java_objectheader *o;
687 /* calculate exception message length */
689 msglen = utf_strlen(c->name) + strlen(".") + utf_strlen(name) +
690 utf_strlen(desc) + strlen("0");
692 /* allocate memory */
694 msg = MNEW(char, msglen);
696 /* generate message */
698 utf_sprint(msg, c->name);
700 utf_strcat(msg, name);
701 utf_strcat(msg, desc);
703 o = native_new_and_init_string(class_java_lang_NoSuchMethodError,
704 javastring_new_char(msg));
708 MFREE(msg, char, msglen);
714 /* new_unsupportedclassversionerror ********************************************
716 generates a java.lang.UnsupportedClassVersionError for the classloader
718 *******************************************************************************/
720 java_objectheader *new_unsupportedclassversionerror(classinfo *c, const char *message, ...)
722 java_objectheader *o;
727 /* calculate exception message length */
729 msglen = utf_strlen(c->name) + strlen(" (") + strlen(")") + strlen("0");
731 va_start(ap, message);
732 msglen += get_variable_message_length(message, ap);
735 /* allocate memory */
737 msg = MNEW(char, msglen);
739 /* generate message */
741 utf_sprint_classname(msg, c->name);
744 va_start(ap, message);
745 vsprintf(msg + strlen(msg), message, ap);
750 /* create exception object */
752 o = new_exception_message(string_java_lang_UnsupportedClassVersionError,
757 MFREE(msg, char, msglen);
763 /* new_verifyerror *************************************************************
765 generates a java.lang.VerifyError for the jit compiler
767 *******************************************************************************/
769 java_objectheader *new_verifyerror(methodinfo *m, const char *message, ...)
771 java_objectheader *o;
776 useinlining = false; /* at least until sure inlining works with exceptions*/
778 /* calculate exception message length */
783 msglen = strlen("(class: ") + utf_strlen(m->class->name) +
784 strlen(", method: ") + utf_strlen(m->name) +
785 strlen(" signature: ") + utf_strlen(m->descriptor) +
786 strlen(") ") + strlen("0");
788 va_start(ap, message);
789 msglen += get_variable_message_length(message, ap);
792 /* allocate memory */
794 msg = MNEW(char, msglen);
796 /* generate message */
799 strcpy(msg, "(class: ");
800 utf_strcat(msg, m->class->name);
801 strcat(msg, ", method: ");
802 utf_strcat(msg, m->name);
803 strcat(msg, " signature: ");
804 utf_strcat(msg, m->descriptor);
808 va_start(ap, message);
809 vsprintf(msg + strlen(msg), message, ap);
812 /* create exception object */
814 o = new_exception_message(string_java_lang_VerifyError, msg);
818 MFREE(msg, char, msglen);
824 /* new_arithmeticexception *****************************************************
826 Generates a java.lang.ArithmeticException for the jit compiler.
828 *******************************************************************************/
830 java_objectheader *new_arithmeticexception(void)
832 java_objectheader *e;
834 e = new_exception_message(string_java_lang_ArithmeticException,
835 string_java_lang_ArithmeticException_message);
838 return *exceptionptr;
844 /* new_arrayindexoutofboundsexception ******************************************
846 Generates a java.lang.ArrayIndexOutOfBoundsException for the JIT
849 *******************************************************************************/
851 java_objectheader *new_arrayindexoutofboundsexception(s4 index)
853 java_objectheader *e;
857 /* convert the index into a String, like Sun does */
859 m = class_resolveclassmethod(class_java_lang_String,
860 utf_new_char("valueOf"),
861 utf_new_char("(I)Ljava/lang/String;"),
862 class_java_lang_Object,
866 return *exceptionptr;
868 s = (java_lang_String *) asm_calljavafunction(m,
869 (void *) (ptrint) index,
875 return *exceptionptr;
877 e = new_exception_javastring(string_java_lang_ArrayIndexOutOfBoundsException,
881 return *exceptionptr;
887 /* new_arraystoreexception *****************************************************
889 generates a java.lang.ArrayStoreException for the jit compiler
891 *******************************************************************************/
893 java_objectheader *new_arraystoreexception(void)
895 java_objectheader *e;
897 e = new_exception(string_java_lang_ArrayStoreException);
898 /* e = native_new_and_init(class_java_lang_ArrayStoreException); */
901 return *exceptionptr;
907 /* new_classcastexception ******************************************************
909 generates a java.lang.ClassCastException for the jit compiler
911 *******************************************************************************/
913 java_objectheader *new_classcastexception(void)
915 java_objectheader *e;
917 e = new_exception(string_java_lang_ClassCastException);
920 return *exceptionptr;
926 /* new_illegalargumentexception ************************************************
928 Generates a java.lang.IllegalArgumentException for the VM system.
930 *******************************************************************************/
932 java_objectheader *new_illegalargumentexception(void)
934 java_objectheader *e;
936 if (!(e = native_new_and_init(class_java_lang_IllegalArgumentException)))
937 return *exceptionptr;
943 /* new_illegalmonitorstateexception ********************************************
945 Generates a java.lang.IllegalMonitorStateException for the VM
948 *******************************************************************************/
950 java_objectheader *new_illegalmonitorstateexception(void)
952 java_objectheader *e;
954 if (!(e = native_new_and_init(class_java_lang_IllegalMonitorStateException)))
955 return *exceptionptr;
961 /* new_negativearraysizeexception **********************************************
963 generates a java.lang.NegativeArraySizeException for the jit compiler
965 *******************************************************************************/
967 java_objectheader *new_negativearraysizeexception(void)
969 java_objectheader *e;
971 e = new_exception(string_java_lang_NegativeArraySizeException);
974 return *exceptionptr;
980 /* new_nullpointerexception ****************************************************
982 generates a java.lang.NullPointerException for the jit compiler
984 *******************************************************************************/
986 java_objectheader *new_nullpointerexception(void)
988 java_objectheader *e;
990 e = native_new_and_init(class_java_lang_NullPointerException);
993 return *exceptionptr;
999 /* exceptions_print_exception **************************************************
1001 Prints an exception, the detail message and the cause, if
1002 available, with CACAO internal functions to stdout.
1004 *******************************************************************************/
1006 void exceptions_print_exception(java_objectheader *xptr)
1008 java_lang_Throwable *t;
1009 java_lang_Throwable *cause;
1012 t = (java_lang_Throwable *) xptr;
1015 /* print the root exception */
1017 utf_display_classname(t->header.vftbl->class->name);
1019 if (t->detailMessage) {
1020 u = javastring_toutf(t->detailMessage, false);
1028 /* print the cause if available */
1030 if (cause && (cause != t)) {
1031 printf("Caused by: ");
1032 utf_display_classname(cause->header.vftbl->class->name);
1034 if (cause->detailMessage) {
1035 u = javastring_toutf(cause->detailMessage, false);
1047 * These are local overrides for various environment variables in Emacs.
1048 * Please do not remove this and leave it at the end of the file, where
1049 * Emacs will automagically detect them.
1050 * ---------------------------------------------------------------------
1053 * indent-tabs-mode: t