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 3653 2005-11-11 11:16:42Z twisti $
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/NoSuchMethodError */
105 if (!(class_java_lang_NoSuchMethodError =
106 load_class_bootstrap(utf_java_lang_NoSuchMethodError)) ||
107 !link_class(class_java_lang_NoSuchMethodError))
110 /* java/lang/OutOfMemoryError */
112 if (!(class_java_lang_OutOfMemoryError =
113 load_class_bootstrap(utf_java_lang_OutOfMemoryError)) ||
114 !link_class(class_java_lang_OutOfMemoryError))
118 /* java/lang/Exception */
120 if (!(class_java_lang_Exception =
121 load_class_bootstrap(utf_java_lang_Exception)) ||
122 !link_class(class_java_lang_Exception))
125 /* java/lang/ClassNotFoundException */
127 if (!(class_java_lang_ClassNotFoundException =
128 load_class_bootstrap(utf_java_lang_ClassNotFoundException)) ||
129 !link_class(class_java_lang_ClassNotFoundException))
132 /* java/lang/IllegalArgumentException */
134 if (!(class_java_lang_IllegalArgumentException =
135 load_class_bootstrap(utf_java_lang_IllegalArgumentException)) ||
136 !link_class(class_java_lang_IllegalArgumentException))
139 /* java/lang/IllegalMonitorStateException */
141 if (!(class_java_lang_IllegalMonitorStateException =
142 load_class_bootstrap(utf_java_lang_IllegalMonitorStateException)) ||
143 !link_class(class_java_lang_IllegalMonitorStateException))
146 /* java/lang/NullPointerException */
148 if (!(class_java_lang_NullPointerException =
149 load_class_bootstrap(utf_java_lang_NullPointerException)) ||
150 !link_class(class_java_lang_NullPointerException))
158 static void throw_exception_exit_intern(bool doexit)
160 java_objectheader *xptr;
164 xptr = *exceptionptr;
167 /* clear exception, because we are calling jit code again */
168 *exceptionptr = NULL;
170 c = xptr->vftbl->class;
172 pss = class_resolveclassmethod(c,
175 class_java_lang_Object,
178 /* print the stacktrace */
180 asm_calljavafunction(pss, xptr, NULL, NULL, NULL);
182 /* This normally means, we are EXTREMLY out of memory or have a */
183 /* serious problem while printStackTrace. But may be another */
184 /* exception, so print it. */
187 java_lang_Throwable *t;
189 t = (java_lang_Throwable *) *exceptionptr;
191 fprintf(stderr, "Exception while printStackTrace(): ");
192 utf_fprint_classname(stderr, t->header.vftbl->class->name);
194 if (t->detailMessage) {
197 buf = javastring_tochar((java_objectheader *) t->detailMessage);
198 fprintf(stderr, ": %s", buf);
199 MFREE(buf, char, strlen(buf));
202 fprintf(stderr, "\n");
206 utf_fprint_classname(stderr, c->name);
207 fprintf(stderr, ": printStackTrace()V not found!\n");
220 void throw_exception(void)
222 throw_exception_exit_intern(false);
226 void throw_exception_exit(void)
228 throw_exception_exit_intern(true);
232 void throw_main_exception(void)
234 fprintf(stderr, "Exception in thread \"main\" ");
237 throw_exception_exit_intern(false);
241 void throw_main_exception_exit(void)
243 fprintf(stderr, "Exception in thread \"main\" ");
246 throw_exception_exit_intern(true);
250 void throw_cacao_exception_exit(const char *exception, const char *message, ...)
257 len = strlen(exception);
258 tmp = MNEW(char, len + 1);
259 strncpy(tmp, exception, len);
262 /* convert to classname */
264 for (i = len - 1; i >= 0; i--)
265 if (tmp[i] == '/') tmp[i] = '.';
267 fprintf(stderr, "Exception in thread \"main\" %s", tmp);
269 MFREE(tmp, char, len);
271 if (strlen(message) > 0) {
272 fprintf(stderr, ": ");
274 va_start(ap, message);
275 vfprintf(stderr, message, ap);
279 fprintf(stderr, "\n");
288 /* exceptions_throw_outofmemory_exit *******************************************
290 Just print an: java.lang.InternalError: Out of memory
292 *******************************************************************************/
294 void exceptions_throw_outofmemory_exit(void)
296 throw_cacao_exception_exit(string_java_lang_InternalError,
301 /* new_exception ***************************************************************
303 Creates an exception object with the given name and initalizes it.
305 *******************************************************************************/
307 java_objectheader *new_exception(const char *classname)
309 java_objectheader *o;
312 if (!(c = load_class_bootstrap(utf_new_char(classname))))
313 return *exceptionptr;
315 o = native_new_and_init(c);
318 return *exceptionptr;
324 /* new_exception_message *******************************************************
326 Creates an exception object with the given name and initalizes it
327 with the given char message.
329 *******************************************************************************/
331 java_objectheader *new_exception_message(const char *classname,
334 java_objectheader *o;
337 if (!(c = load_class_bootstrap(utf_new_char(classname))))
338 return *exceptionptr;
340 o = native_new_and_init_string(c, javastring_new_char(message));
343 return *exceptionptr;
349 /* new_exception_throwable *****************************************************
351 Creates an exception object with the given name and initalizes it
352 with the given java/lang/Throwable exception.
354 *******************************************************************************/
356 java_objectheader *new_exception_throwable(const char *classname,
357 java_lang_Throwable *throwable)
359 java_objectheader *o;
362 if (!(c = load_class_bootstrap(utf_new_char(classname))))
363 return *exceptionptr;
365 o = native_new_and_init_throwable(c, throwable);
368 return *exceptionptr;
374 /* new_exception_utfmessage ****************************************************
376 Creates an exception object with the given name and initalizes it
377 with the given utf message.
379 *******************************************************************************/
381 java_objectheader *new_exception_utfmessage(const char *classname, utf *message)
383 java_objectheader *o;
386 if (!(c = load_class_bootstrap(utf_new_char(classname))))
387 return *exceptionptr;
389 o = native_new_and_init_string(c, javastring_new(message));
392 return *exceptionptr;
398 /* new_exception_javastring ****************************************************
400 Creates an exception object with the given name and initalizes it
401 with the given java/lang/String message.
403 *******************************************************************************/
405 java_objectheader *new_exception_javastring(const char *classname,
406 java_lang_String *message)
408 java_objectheader *o;
411 if (!(c = load_class_bootstrap(utf_new_char(classname))))
412 return *exceptionptr;
414 o = native_new_and_init_string(c, message);
417 return *exceptionptr;
423 /* new_exception_int ***********************************************************
425 Creates an exception object with the given name and initalizes it
426 with the given int value.
428 *******************************************************************************/
430 java_objectheader *new_exception_int(const char *classname, s4 i)
432 java_objectheader *o;
435 if (!(c = load_class_bootstrap(utf_new_char(classname))))
436 return *exceptionptr;
438 o = native_new_and_init_int(c, i);
441 return *exceptionptr;
447 /* new_classformaterror ********************************************************
449 generates a java.lang.ClassFormatError for the classloader
451 *******************************************************************************/
453 java_objectheader *new_classformaterror(classinfo *c, const char *message, ...)
455 java_objectheader *o;
460 /* calculate message length */
465 msglen += utf_strlen(c->name) + strlen(" (");
467 va_start(ap, message);
468 msglen += get_variable_message_length(message, ap);
472 msglen += strlen(")");
474 msglen += strlen("0");
476 /* allocate a buffer */
478 msg = MNEW(char, msglen);
480 /* print message into allocated buffer */
483 utf_sprint_classname(msg, c->name);
487 va_start(ap, message);
488 vsprintf(msg + strlen(msg), message, ap);
494 o = new_exception_message(string_java_lang_ClassFormatError, msg);
496 MFREE(msg, char, msglen);
502 /* new_classnotfoundexception **************************************************
504 Generates a java.lang.ClassNotFoundException for the classloader.
506 *******************************************************************************/
508 java_objectheader *new_classnotfoundexception(utf *name)
510 java_objectheader *o;
512 o = native_new_and_init_string(class_java_lang_ClassNotFoundException,
513 javastring_new(name));
516 return *exceptionptr;
522 /* new_noclassdeffounderror ****************************************************
524 Generates a java.lang.NoClassDefFoundError
526 *******************************************************************************/
528 java_objectheader *new_noclassdeffounderror(utf *name)
530 java_objectheader *o;
532 o = native_new_and_init_string(class_java_lang_NoClassDefFoundError,
533 javastring_new(name));
536 return *exceptionptr;
542 /* classnotfoundexception_to_noclassdeffounderror ******************************
544 Check the *exceptionptr for a ClassNotFoundException. If it is one,
545 convert it to a NoClassDefFoundError.
547 *******************************************************************************/
549 void classnotfoundexception_to_noclassdeffounderror(void)
551 java_objectheader *xptr;
552 java_objectheader *cause;
556 cause = *exceptionptr;
558 /* convert ClassNotFoundException's to NoClassDefFoundError's */
560 if (builtin_instanceof(cause, class_java_lang_ClassNotFoundException)) {
561 /* clear exception, because we are calling jit code again */
563 *exceptionptr = NULL;
565 /* create new error */
568 new_exception_javastring(string_java_lang_NoClassDefFoundError,
569 ((java_lang_Throwable *) cause)->detailMessage);
571 /* we had an exception while creating the error */
576 /* set new exception */
578 *exceptionptr = xptr;
583 /* new_internalerror ***********************************************************
585 Generates a java.lang.InternalError for the VM.
587 *******************************************************************************/
589 java_objectheader *new_internalerror(const char *message, ...)
591 java_objectheader *o;
596 /* calculate exception message length */
598 va_start(ap, message);
599 msglen = get_variable_message_length(message, ap);
602 /* allocate memory */
604 msg = MNEW(char, msglen);
606 /* generate message */
608 va_start(ap, message);
609 vsprintf(msg, message, ap);
612 /* create exception object */
614 o = new_exception_message(string_java_lang_InternalError, msg);
618 MFREE(msg, char, msglen);
624 /* exceptions_new_nosuchmethoderror ********************************************
626 Generates a java.lang.NoSuchMethodError with an error message.
628 *******************************************************************************/
630 java_objectheader *exceptions_new_nosuchmethoderror(classinfo *c,
631 utf *name, utf *desc)
633 java_objectheader *o;
637 /* calculate exception message length */
639 msglen = utf_strlen(c->name) + strlen(".") + utf_strlen(name) +
640 utf_strlen(desc) + strlen("0");
642 /* allocate memory */
644 msg = MNEW(char, msglen);
646 /* generate message */
648 utf_sprint(msg, c->name);
650 utf_strcat(msg, name);
651 utf_strcat(msg, desc);
653 o = native_new_and_init_string(class_java_lang_NoSuchMethodError,
654 javastring_new_char(msg));
658 MFREE(msg, char, msglen);
664 /* new_unsupportedclassversionerror ********************************************
666 generates a java.lang.UnsupportedClassVersionError for the classloader
668 *******************************************************************************/
670 java_objectheader *new_unsupportedclassversionerror(classinfo *c, const char *message, ...)
672 java_objectheader *o;
677 /* calculate exception message length */
679 msglen = utf_strlen(c->name) + strlen(" (") + strlen(")") + strlen("0");
681 va_start(ap, message);
682 msglen += get_variable_message_length(message, ap);
685 /* allocate memory */
687 msg = MNEW(char, msglen);
689 /* generate message */
691 utf_sprint_classname(msg, c->name);
694 va_start(ap, message);
695 vsprintf(msg + strlen(msg), message, ap);
700 /* create exception object */
702 o = new_exception_message(string_java_lang_UnsupportedClassVersionError,
707 MFREE(msg, char, msglen);
713 /* new_verifyerror *************************************************************
715 generates a java.lang.VerifyError for the jit compiler
717 *******************************************************************************/
719 java_objectheader *new_verifyerror(methodinfo *m, const char *message, ...)
721 java_objectheader *o;
726 useinlining = false; /* at least until sure inlining works with exceptions*/
728 /* calculate exception message length */
733 msglen = strlen("(class: ") + utf_strlen(m->class->name) +
734 strlen(", method: ") + utf_strlen(m->name) +
735 strlen(" signature: ") + utf_strlen(m->descriptor) +
736 strlen(") ") + strlen("0");
738 va_start(ap, message);
739 msglen += get_variable_message_length(message, ap);
742 /* allocate memory */
744 msg = MNEW(char, msglen);
746 /* generate message */
749 strcpy(msg, "(class: ");
750 utf_strcat(msg, m->class->name);
751 strcat(msg, ", method: ");
752 utf_strcat(msg, m->name);
753 strcat(msg, " signature: ");
754 utf_strcat(msg, m->descriptor);
758 va_start(ap, message);
759 vsprintf(msg + strlen(msg), message, ap);
762 /* create exception object */
764 o = new_exception_message(string_java_lang_VerifyError, msg);
768 MFREE(msg, char, msglen);
774 /* new_arithmeticexception *****************************************************
776 Generates a java.lang.ArithmeticException for the jit compiler.
778 *******************************************************************************/
780 java_objectheader *new_arithmeticexception(void)
782 java_objectheader *e;
784 e = new_exception_message(string_java_lang_ArithmeticException,
785 string_java_lang_ArithmeticException_message);
788 return *exceptionptr;
794 /* new_arrayindexoutofboundsexception ******************************************
796 Generates a java.lang.ArrayIndexOutOfBoundsException for the JIT
799 *******************************************************************************/
801 java_objectheader *new_arrayindexoutofboundsexception(s4 index)
803 java_objectheader *e;
807 /* convert the index into a String, like Sun does */
809 m = class_resolveclassmethod(class_java_lang_String,
810 utf_new_char("valueOf"),
811 utf_new_char("(I)Ljava/lang/String;"),
812 class_java_lang_Object,
816 return *exceptionptr;
818 s = (java_lang_String *) asm_calljavafunction(m,
819 (void *) (ptrint) index,
825 return *exceptionptr;
827 e = new_exception_javastring(string_java_lang_ArrayIndexOutOfBoundsException,
831 return *exceptionptr;
837 /* new_arraystoreexception *****************************************************
839 generates a java.lang.ArrayStoreException for the jit compiler
841 *******************************************************************************/
843 java_objectheader *new_arraystoreexception(void)
845 java_objectheader *e;
847 e = new_exception(string_java_lang_ArrayStoreException);
848 /* e = native_new_and_init(class_java_lang_ArrayStoreException); */
851 return *exceptionptr;
857 /* new_classcastexception ******************************************************
859 generates a java.lang.ClassCastException for the jit compiler
861 *******************************************************************************/
863 java_objectheader *new_classcastexception(void)
865 java_objectheader *e;
867 e = new_exception(string_java_lang_ClassCastException);
870 return *exceptionptr;
876 /* new_illegalargumentexception ************************************************
878 Generates a java.lang.IllegalArgumentException for the VM system.
880 *******************************************************************************/
882 java_objectheader *new_illegalargumentexception(void)
884 java_objectheader *e;
886 if (!(e = native_new_and_init(class_java_lang_IllegalArgumentException)))
887 return *exceptionptr;
893 /* new_illegalmonitorstateexception ********************************************
895 Generates a java.lang.IllegalMonitorStateException for the VM
898 *******************************************************************************/
900 java_objectheader *new_illegalmonitorstateexception(void)
902 java_objectheader *e;
904 if (!(e = native_new_and_init(class_java_lang_IllegalMonitorStateException)))
905 return *exceptionptr;
911 /* new_negativearraysizeexception **********************************************
913 generates a java.lang.NegativeArraySizeException for the jit compiler
915 *******************************************************************************/
917 java_objectheader *new_negativearraysizeexception(void)
919 java_objectheader *e;
921 e = new_exception(string_java_lang_NegativeArraySizeException);
924 return *exceptionptr;
930 /* new_nullpointerexception ****************************************************
932 generates a java.lang.NullPointerException for the jit compiler
934 *******************************************************************************/
936 java_objectheader *new_nullpointerexception(void)
938 java_objectheader *e;
940 e = native_new_and_init(class_java_lang_NullPointerException);
943 return *exceptionptr;
949 /* exceptions_print_exception **************************************************
951 Prints an exception, the detail message and the cause, if
952 available, with CACAO internal functions to stdout.
954 *******************************************************************************/
956 void exceptions_print_exception(java_objectheader *xptr)
958 java_lang_Throwable *t;
959 java_lang_Throwable *cause;
962 t = (java_lang_Throwable *) xptr;
965 /* print the root exception */
967 utf_display_classname(t->header.vftbl->class->name);
969 if (t->detailMessage) {
970 u = javastring_toutf(t->detailMessage, false);
978 /* print the cause if available */
980 if (cause && (cause != t)) {
981 printf("Caused by: ");
982 utf_display_classname(cause->header.vftbl->class->name);
984 if (cause->detailMessage) {
985 u = javastring_toutf(cause->detailMessage, false);
997 * These are local overrides for various environment variables in Emacs.
998 * Please do not remove this and leave it at the end of the file, where
999 * Emacs will automagically detect them.
1000 * ---------------------------------------------------------------------
1003 * indent-tabs-mode: t