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 3466 2005-10-20 10:42:12Z 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/OutOfMemoryError */
105 if (!(class_java_lang_OutOfMemoryError =
106 load_class_bootstrap(utf_java_lang_OutOfMemoryError)) ||
107 !link_class(class_java_lang_OutOfMemoryError))
111 /* java/lang/Exception */
113 if (!(class_java_lang_Exception =
114 load_class_bootstrap(utf_java_lang_Exception)) ||
115 !link_class(class_java_lang_Exception))
118 /* java/lang/ClassNotFoundException */
120 if (!(class_java_lang_ClassNotFoundException =
121 load_class_bootstrap(utf_java_lang_ClassNotFoundException)) ||
122 !link_class(class_java_lang_ClassNotFoundException))
125 /* java/lang/IllegalArgumentException */
127 if (!(class_java_lang_IllegalArgumentException =
128 load_class_bootstrap(utf_java_lang_IllegalArgumentException)) ||
129 !link_class(class_java_lang_IllegalArgumentException))
137 static void throw_exception_exit_intern(bool doexit)
139 java_objectheader *xptr;
143 xptr = *exceptionptr;
146 /* clear exception, because we are calling jit code again */
147 *exceptionptr = NULL;
149 c = xptr->vftbl->class;
151 pss = class_resolveclassmethod(c,
154 class_java_lang_Object,
157 /* print the stacktrace */
159 asm_calljavafunction(pss, xptr, NULL, NULL, NULL);
161 /* This normally means, we are EXTREMLY out of memory or have a */
162 /* serious problem while printStackTrace. But may be another */
163 /* exception, so print it. */
166 java_lang_Throwable *t;
168 t = (java_lang_Throwable *) *exceptionptr;
170 fprintf(stderr, "Exception while printStackTrace(): ");
171 utf_fprint_classname(stderr, t->header.vftbl->class->name);
173 if (t->detailMessage) {
176 buf = javastring_tochar((java_objectheader *) t->detailMessage);
177 fprintf(stderr, ": %s", buf);
178 MFREE(buf, char, strlen(buf));
181 fprintf(stderr, "\n");
185 utf_fprint_classname(stderr, c->name);
186 fprintf(stderr, ": printStackTrace()V not found!\n");
199 void throw_exception(void)
201 throw_exception_exit_intern(false);
205 void throw_exception_exit(void)
207 throw_exception_exit_intern(true);
211 void throw_main_exception(void)
213 fprintf(stderr, "Exception in thread \"main\" ");
216 throw_exception_exit_intern(false);
220 void throw_main_exception_exit(void)
222 fprintf(stderr, "Exception in thread \"main\" ");
225 throw_exception_exit_intern(true);
229 void throw_cacao_exception_exit(const char *exception, const char *message, ...)
236 len = strlen(exception);
237 tmp = MNEW(char, len + 1);
238 strncpy(tmp, exception, len);
241 /* convert to classname */
243 for (i = len - 1; i >= 0; i--)
244 if (tmp[i] == '/') tmp[i] = '.';
246 fprintf(stderr, "Exception in thread \"main\" %s", tmp);
248 MFREE(tmp, char, len);
250 if (strlen(message) > 0) {
251 fprintf(stderr, ": ");
253 va_start(ap, message);
254 vfprintf(stderr, message, ap);
258 fprintf(stderr, "\n");
267 /* new_exception ***************************************************************
269 Creates an exception object with the given name and initalizes it.
271 *******************************************************************************/
273 java_objectheader *new_exception(const char *classname)
275 java_objectheader *o;
278 if (!(c = load_class_bootstrap(utf_new_char(classname))))
279 return *exceptionptr;
281 o = native_new_and_init(c);
284 return *exceptionptr;
290 /* new_exception_message *******************************************************
292 Creates an exception object with the given name and initalizes it
293 with the given char message.
295 *******************************************************************************/
297 java_objectheader *new_exception_message(const char *classname,
300 java_objectheader *o;
303 if (!(c = load_class_bootstrap(utf_new_char(classname))))
304 return *exceptionptr;
306 o = native_new_and_init_string(c, javastring_new_char(message));
309 return *exceptionptr;
315 /* new_exception_throwable *****************************************************
317 Creates an exception object with the given name and initalizes it
318 with the given java/lang/Throwable exception.
320 *******************************************************************************/
322 java_objectheader *new_exception_throwable(const char *classname,
323 java_lang_Throwable *throwable)
325 java_objectheader *o;
328 if (!(c = load_class_bootstrap(utf_new_char(classname))))
329 return *exceptionptr;
331 o = native_new_and_init_throwable(c, throwable);
334 return *exceptionptr;
340 /* new_exception_utfmessage ****************************************************
342 Creates an exception object with the given name and initalizes it
343 with the given utf message.
345 *******************************************************************************/
347 java_objectheader *new_exception_utfmessage(const char *classname, utf *message)
349 java_objectheader *o;
352 if (!(c = load_class_bootstrap(utf_new_char(classname))))
353 return *exceptionptr;
355 o = native_new_and_init_string(c, javastring_new(message));
358 return *exceptionptr;
364 /* new_exception_javastring ****************************************************
366 Creates an exception object with the given name and initalizes it
367 with the given java/lang/String message.
369 *******************************************************************************/
371 java_objectheader *new_exception_javastring(const char *classname,
372 java_lang_String *message)
374 java_objectheader *o;
377 if (!(c = load_class_bootstrap(utf_new_char(classname))))
378 return *exceptionptr;
380 o = native_new_and_init_string(c, message);
383 return *exceptionptr;
389 /* new_exception_int ***********************************************************
391 Creates an exception object with the given name and initalizes it
392 with the given int value.
394 *******************************************************************************/
396 java_objectheader *new_exception_int(const char *classname, s4 i)
398 java_objectheader *o;
401 if (!(c = load_class_bootstrap(utf_new_char(classname))))
402 return *exceptionptr;
404 o = native_new_and_init_int(c, i);
407 return *exceptionptr;
413 /* new_classformaterror ********************************************************
415 generates a java.lang.ClassFormatError for the classloader
417 *******************************************************************************/
419 java_objectheader *new_classformaterror(classinfo *c, const char *message, ...)
421 java_objectheader *o;
426 /* calculate message length */
431 msglen += utf_strlen(c->name) + strlen(" (");
433 va_start(ap, message);
434 msglen += get_variable_message_length(message, ap);
438 msglen += strlen(")");
440 msglen += strlen("0");
442 /* allocate a buffer */
444 msg = MNEW(char, msglen);
446 /* print message into allocated buffer */
449 utf_sprint_classname(msg, c->name);
453 va_start(ap, message);
454 vsprintf(msg + strlen(msg), message, ap);
460 o = new_exception_message(string_java_lang_ClassFormatError, msg);
462 MFREE(msg, char, msglen);
468 /* new_classnotfoundexception **************************************************
470 Generates a java.lang.ClassNotFoundException for the classloader.
472 *******************************************************************************/
474 java_objectheader *new_classnotfoundexception(utf *name)
476 java_objectheader *o;
478 o = native_new_and_init_string(class_java_lang_ClassNotFoundException,
479 javastring_new(name));
482 return *exceptionptr;
488 /* new_noclassdeffounderror ****************************************************
490 Generates a java.lang.NoClassDefFoundError
492 *******************************************************************************/
494 java_objectheader *new_noclassdeffounderror(utf *name)
496 java_objectheader *o;
498 o = native_new_and_init_string(class_java_lang_NoClassDefFoundError,
499 javastring_new(name));
502 return *exceptionptr;
508 /* classnotfoundexception_to_noclassdeffounderror ******************************
510 Check the *exceptionptr for a ClassNotFoundException. If it is one,
511 convert it to a NoClassDefFoundError.
513 *******************************************************************************/
515 void classnotfoundexception_to_noclassdeffounderror(void)
517 java_objectheader *xptr;
518 java_objectheader *cause;
522 cause = *exceptionptr;
524 /* convert ClassNotFoundException's to NoClassDefFoundError's */
526 if (builtin_instanceof(cause, class_java_lang_ClassNotFoundException)) {
527 /* clear exception, because we are calling jit code again */
529 *exceptionptr = NULL;
531 /* create new error */
534 new_exception_javastring(string_java_lang_NoClassDefFoundError,
535 ((java_lang_Throwable *) cause)->detailMessage);
537 /* we had an exception while creating the error */
542 /* set new exception */
544 *exceptionptr = xptr;
549 /* new_internalerror ***********************************************************
551 Generates a java.lang.InternalError for the VM.
553 *******************************************************************************/
555 java_objectheader *new_internalerror(const char *message, ...)
557 java_objectheader *o;
562 /* calculate exception message length */
564 va_start(ap, message);
565 msglen = get_variable_message_length(message, ap);
568 /* allocate memory */
570 msg = MNEW(char, msglen);
572 /* generate message */
574 va_start(ap, message);
575 vsprintf(msg, message, ap);
578 /* create exception object */
580 o = new_exception_message(string_java_lang_InternalError, msg);
584 MFREE(msg, char, msglen);
590 /* new_unsupportedclassversionerror ********************************************
592 generates a java.lang.UnsupportedClassVersionError for the classloader
594 *******************************************************************************/
596 java_objectheader *new_unsupportedclassversionerror(classinfo *c, const char *message, ...)
598 java_objectheader *o;
603 /* calculate exception message length */
605 msglen = utf_strlen(c->name) + strlen(" (") + strlen(")") + strlen("0");
607 va_start(ap, message);
608 msglen += get_variable_message_length(message, ap);
611 /* allocate memory */
613 msg = MNEW(char, msglen);
615 /* generate message */
617 utf_sprint_classname(msg, c->name);
620 va_start(ap, message);
621 vsprintf(msg + strlen(msg), message, ap);
626 /* create exception object */
628 o = new_exception_message(string_java_lang_UnsupportedClassVersionError,
633 MFREE(msg, char, msglen);
639 /* new_verifyerror *************************************************************
641 generates a java.lang.VerifyError for the jit compiler
643 *******************************************************************************/
645 java_objectheader *new_verifyerror(methodinfo *m, const char *message, ...)
647 java_objectheader *o;
652 useinlining = false; /* at least until sure inlining works with exceptions*/
654 /* calculate exception message length */
656 msglen = strlen("(class: ") + utf_strlen(m->class->name) +
657 strlen(", method: ") + utf_strlen(m->name) +
658 strlen(" signature: ") + utf_strlen(m->descriptor) +
659 strlen(") ") + strlen("0");
661 va_start(ap, message);
662 msglen += get_variable_message_length(message, ap);
665 /* allocate memory */
667 msg = MNEW(char, msglen);
669 /* generate message */
671 strcpy(msg, "(class: ");
672 utf_strcat(msg, m->class->name);
673 strcat(msg, ", method: ");
674 utf_strcat(msg, m->name);
675 strcat(msg, " signature: ");
676 utf_strcat(msg, m->descriptor);
679 va_start(ap, message);
680 vsprintf(msg + strlen(msg), message, ap);
683 /* create exception object */
685 o = new_exception_message(string_java_lang_VerifyError, msg);
689 MFREE(msg, char, msglen);
695 /* new_arithmeticexception *****************************************************
697 Generates a java.lang.ArithmeticException for the jit compiler.
699 *******************************************************************************/
701 java_objectheader *new_arithmeticexception(void)
703 java_objectheader *e;
705 e = new_exception_message(string_java_lang_ArithmeticException,
706 string_java_lang_ArithmeticException_message);
709 return *exceptionptr;
715 /* new_arrayindexoutofboundsexception ******************************************
717 Generates a java.lang.ArrayIndexOutOfBoundsException for the JIT
720 *******************************************************************************/
722 java_objectheader *new_arrayindexoutofboundsexception(s4 index)
724 java_objectheader *e;
728 /* convert the index into a String, like Sun does */
730 m = class_resolveclassmethod(class_java_lang_String,
731 utf_new_char("valueOf"),
732 utf_new_char("(I)Ljava/lang/String;"),
733 class_java_lang_Object,
737 return *exceptionptr;
739 s = (java_lang_String *) asm_calljavafunction(m,
740 (void *) (ptrint) index,
746 return *exceptionptr;
748 e = new_exception_javastring(string_java_lang_ArrayIndexOutOfBoundsException,
752 return *exceptionptr;
758 /* new_arraystoreexception *****************************************************
760 generates a java.lang.ArrayStoreException for the jit compiler
762 *******************************************************************************/
764 java_objectheader *new_arraystoreexception(void)
766 java_objectheader *e;
768 e = new_exception(string_java_lang_ArrayStoreException);
771 return *exceptionptr;
777 /* new_classcastexception ******************************************************
779 generates a java.lang.ClassCastException for the jit compiler
781 *******************************************************************************/
783 java_objectheader *new_classcastexception(void)
785 java_objectheader *e;
787 e = new_exception(string_java_lang_ClassCastException);
790 return *exceptionptr;
796 /* new_illegalargumentexception ************************************************
798 Generates a java.lang.IllegalArgumentException for the VM system.
800 *******************************************************************************/
802 java_objectheader *new_illegalargumentexception(void)
804 java_objectheader *e;
806 if (!(e = native_new_and_init(class_java_lang_IllegalArgumentException)))
807 return *exceptionptr;
813 /* new_negativearraysizeexception **********************************************
815 generates a java.lang.NegativeArraySizeException for the jit compiler
817 *******************************************************************************/
819 java_objectheader *new_negativearraysizeexception(void)
821 java_objectheader *e;
823 e = new_exception(string_java_lang_NegativeArraySizeException);
826 return *exceptionptr;
832 /* new_nullpointerexception ****************************************************
834 generates a java.lang.NullPointerException for the jit compiler
836 *******************************************************************************/
838 java_objectheader *new_nullpointerexception(void)
840 java_objectheader *e;
842 e = new_exception(string_java_lang_NullPointerException);
845 return *exceptionptr;
852 * These are local overrides for various environment variables in Emacs.
853 * Please do not remove this and leave it at the end of the file, where
854 * Emacs will automagically detect them.
855 * ---------------------------------------------------------------------
858 * indent-tabs-mode: t