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 3612 2005-11-07 17:47:49Z 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/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))
132 /* java/lang/IllegalMonitorStateException */
134 if (!(class_java_lang_IllegalMonitorStateException =
135 load_class_bootstrap(utf_java_lang_IllegalMonitorStateException)) ||
136 !link_class(class_java_lang_IllegalMonitorStateException))
139 /* java/lang/NullPointerException */
141 if (!(class_java_lang_NullPointerException =
142 load_class_bootstrap(utf_java_lang_NullPointerException)) ||
143 !link_class(class_java_lang_NullPointerException))
151 static void throw_exception_exit_intern(bool doexit)
153 java_objectheader *xptr;
157 xptr = *exceptionptr;
160 /* clear exception, because we are calling jit code again */
161 *exceptionptr = NULL;
163 c = xptr->vftbl->class;
165 pss = class_resolveclassmethod(c,
168 class_java_lang_Object,
171 /* print the stacktrace */
173 asm_calljavafunction(pss, xptr, NULL, NULL, NULL);
175 /* This normally means, we are EXTREMLY out of memory or have a */
176 /* serious problem while printStackTrace. But may be another */
177 /* exception, so print it. */
180 java_lang_Throwable *t;
182 t = (java_lang_Throwable *) *exceptionptr;
184 fprintf(stderr, "Exception while printStackTrace(): ");
185 utf_fprint_classname(stderr, t->header.vftbl->class->name);
187 if (t->detailMessage) {
190 buf = javastring_tochar((java_objectheader *) t->detailMessage);
191 fprintf(stderr, ": %s", buf);
192 MFREE(buf, char, strlen(buf));
195 fprintf(stderr, "\n");
199 utf_fprint_classname(stderr, c->name);
200 fprintf(stderr, ": printStackTrace()V not found!\n");
213 void throw_exception(void)
215 throw_exception_exit_intern(false);
219 void throw_exception_exit(void)
221 throw_exception_exit_intern(true);
225 void throw_main_exception(void)
227 fprintf(stderr, "Exception in thread \"main\" ");
230 throw_exception_exit_intern(false);
234 void throw_main_exception_exit(void)
236 fprintf(stderr, "Exception in thread \"main\" ");
239 throw_exception_exit_intern(true);
243 void throw_cacao_exception_exit(const char *exception, const char *message, ...)
250 len = strlen(exception);
251 tmp = MNEW(char, len + 1);
252 strncpy(tmp, exception, len);
255 /* convert to classname */
257 for (i = len - 1; i >= 0; i--)
258 if (tmp[i] == '/') tmp[i] = '.';
260 fprintf(stderr, "Exception in thread \"main\" %s", tmp);
262 MFREE(tmp, char, len);
264 if (strlen(message) > 0) {
265 fprintf(stderr, ": ");
267 va_start(ap, message);
268 vfprintf(stderr, message, ap);
272 fprintf(stderr, "\n");
281 /* exceptions_throw_outofmemory_exit *******************************************
283 Just print an: java.lang.InternalError: Out of memory
285 *******************************************************************************/
287 void exceptions_throw_outofmemory_exit(void)
289 throw_cacao_exception_exit(string_java_lang_InternalError,
294 /* new_exception ***************************************************************
296 Creates an exception object with the given name and initalizes it.
298 *******************************************************************************/
300 java_objectheader *new_exception(const char *classname)
302 java_objectheader *o;
305 if (!(c = load_class_bootstrap(utf_new_char(classname))))
306 return *exceptionptr;
308 o = native_new_and_init(c);
311 return *exceptionptr;
317 /* new_exception_message *******************************************************
319 Creates an exception object with the given name and initalizes it
320 with the given char message.
322 *******************************************************************************/
324 java_objectheader *new_exception_message(const char *classname,
327 java_objectheader *o;
330 if (!(c = load_class_bootstrap(utf_new_char(classname))))
331 return *exceptionptr;
333 o = native_new_and_init_string(c, javastring_new_char(message));
336 return *exceptionptr;
342 /* new_exception_throwable *****************************************************
344 Creates an exception object with the given name and initalizes it
345 with the given java/lang/Throwable exception.
347 *******************************************************************************/
349 java_objectheader *new_exception_throwable(const char *classname,
350 java_lang_Throwable *throwable)
352 java_objectheader *o;
355 if (!(c = load_class_bootstrap(utf_new_char(classname))))
356 return *exceptionptr;
358 o = native_new_and_init_throwable(c, throwable);
361 return *exceptionptr;
367 /* new_exception_utfmessage ****************************************************
369 Creates an exception object with the given name and initalizes it
370 with the given utf message.
372 *******************************************************************************/
374 java_objectheader *new_exception_utfmessage(const char *classname, utf *message)
376 java_objectheader *o;
379 if (!(c = load_class_bootstrap(utf_new_char(classname))))
380 return *exceptionptr;
382 o = native_new_and_init_string(c, javastring_new(message));
385 return *exceptionptr;
391 /* new_exception_javastring ****************************************************
393 Creates an exception object with the given name and initalizes it
394 with the given java/lang/String message.
396 *******************************************************************************/
398 java_objectheader *new_exception_javastring(const char *classname,
399 java_lang_String *message)
401 java_objectheader *o;
404 if (!(c = load_class_bootstrap(utf_new_char(classname))))
405 return *exceptionptr;
407 o = native_new_and_init_string(c, message);
410 return *exceptionptr;
416 /* new_exception_int ***********************************************************
418 Creates an exception object with the given name and initalizes it
419 with the given int value.
421 *******************************************************************************/
423 java_objectheader *new_exception_int(const char *classname, s4 i)
425 java_objectheader *o;
428 if (!(c = load_class_bootstrap(utf_new_char(classname))))
429 return *exceptionptr;
431 o = native_new_and_init_int(c, i);
434 return *exceptionptr;
440 /* new_classformaterror ********************************************************
442 generates a java.lang.ClassFormatError for the classloader
444 *******************************************************************************/
446 java_objectheader *new_classformaterror(classinfo *c, const char *message, ...)
448 java_objectheader *o;
453 /* calculate message length */
458 msglen += utf_strlen(c->name) + strlen(" (");
460 va_start(ap, message);
461 msglen += get_variable_message_length(message, ap);
465 msglen += strlen(")");
467 msglen += strlen("0");
469 /* allocate a buffer */
471 msg = MNEW(char, msglen);
473 /* print message into allocated buffer */
476 utf_sprint_classname(msg, c->name);
480 va_start(ap, message);
481 vsprintf(msg + strlen(msg), message, ap);
487 o = new_exception_message(string_java_lang_ClassFormatError, msg);
489 MFREE(msg, char, msglen);
495 /* new_classnotfoundexception **************************************************
497 Generates a java.lang.ClassNotFoundException for the classloader.
499 *******************************************************************************/
501 java_objectheader *new_classnotfoundexception(utf *name)
503 java_objectheader *o;
505 o = native_new_and_init_string(class_java_lang_ClassNotFoundException,
506 javastring_new(name));
509 return *exceptionptr;
515 /* new_noclassdeffounderror ****************************************************
517 Generates a java.lang.NoClassDefFoundError
519 *******************************************************************************/
521 java_objectheader *new_noclassdeffounderror(utf *name)
523 java_objectheader *o;
525 o = native_new_and_init_string(class_java_lang_NoClassDefFoundError,
526 javastring_new(name));
529 return *exceptionptr;
535 /* classnotfoundexception_to_noclassdeffounderror ******************************
537 Check the *exceptionptr for a ClassNotFoundException. If it is one,
538 convert it to a NoClassDefFoundError.
540 *******************************************************************************/
542 void classnotfoundexception_to_noclassdeffounderror(void)
544 java_objectheader *xptr;
545 java_objectheader *cause;
549 cause = *exceptionptr;
551 /* convert ClassNotFoundException's to NoClassDefFoundError's */
553 if (builtin_instanceof(cause, class_java_lang_ClassNotFoundException)) {
554 /* clear exception, because we are calling jit code again */
556 *exceptionptr = NULL;
558 /* create new error */
561 new_exception_javastring(string_java_lang_NoClassDefFoundError,
562 ((java_lang_Throwable *) cause)->detailMessage);
564 /* we had an exception while creating the error */
569 /* set new exception */
571 *exceptionptr = xptr;
576 /* new_internalerror ***********************************************************
578 Generates a java.lang.InternalError for the VM.
580 *******************************************************************************/
582 java_objectheader *new_internalerror(const char *message, ...)
584 java_objectheader *o;
589 /* calculate exception message length */
591 va_start(ap, message);
592 msglen = get_variable_message_length(message, ap);
595 /* allocate memory */
597 msg = MNEW(char, msglen);
599 /* generate message */
601 va_start(ap, message);
602 vsprintf(msg, message, ap);
605 /* create exception object */
607 o = new_exception_message(string_java_lang_InternalError, msg);
611 MFREE(msg, char, msglen);
617 /* new_unsupportedclassversionerror ********************************************
619 generates a java.lang.UnsupportedClassVersionError for the classloader
621 *******************************************************************************/
623 java_objectheader *new_unsupportedclassversionerror(classinfo *c, const char *message, ...)
625 java_objectheader *o;
630 /* calculate exception message length */
632 msglen = utf_strlen(c->name) + strlen(" (") + strlen(")") + strlen("0");
634 va_start(ap, message);
635 msglen += get_variable_message_length(message, ap);
638 /* allocate memory */
640 msg = MNEW(char, msglen);
642 /* generate message */
644 utf_sprint_classname(msg, c->name);
647 va_start(ap, message);
648 vsprintf(msg + strlen(msg), message, ap);
653 /* create exception object */
655 o = new_exception_message(string_java_lang_UnsupportedClassVersionError,
660 MFREE(msg, char, msglen);
666 /* new_verifyerror *************************************************************
668 generates a java.lang.VerifyError for the jit compiler
670 *******************************************************************************/
672 java_objectheader *new_verifyerror(methodinfo *m, const char *message, ...)
674 java_objectheader *o;
679 useinlining = false; /* at least until sure inlining works with exceptions*/
681 /* calculate exception message length */
686 msglen = strlen("(class: ") + utf_strlen(m->class->name) +
687 strlen(", method: ") + utf_strlen(m->name) +
688 strlen(" signature: ") + utf_strlen(m->descriptor) +
689 strlen(") ") + strlen("0");
691 va_start(ap, message);
692 msglen += get_variable_message_length(message, ap);
695 /* allocate memory */
697 msg = MNEW(char, msglen);
699 /* generate message */
702 strcpy(msg, "(class: ");
703 utf_strcat(msg, m->class->name);
704 strcat(msg, ", method: ");
705 utf_strcat(msg, m->name);
706 strcat(msg, " signature: ");
707 utf_strcat(msg, m->descriptor);
711 va_start(ap, message);
712 vsprintf(msg + strlen(msg), message, ap);
715 /* create exception object */
717 o = new_exception_message(string_java_lang_VerifyError, msg);
721 MFREE(msg, char, msglen);
727 /* new_arithmeticexception *****************************************************
729 Generates a java.lang.ArithmeticException for the jit compiler.
731 *******************************************************************************/
733 java_objectheader *new_arithmeticexception(void)
735 java_objectheader *e;
737 e = new_exception_message(string_java_lang_ArithmeticException,
738 string_java_lang_ArithmeticException_message);
741 return *exceptionptr;
747 /* new_arrayindexoutofboundsexception ******************************************
749 Generates a java.lang.ArrayIndexOutOfBoundsException for the JIT
752 *******************************************************************************/
754 java_objectheader *new_arrayindexoutofboundsexception(s4 index)
756 java_objectheader *e;
760 /* convert the index into a String, like Sun does */
762 m = class_resolveclassmethod(class_java_lang_String,
763 utf_new_char("valueOf"),
764 utf_new_char("(I)Ljava/lang/String;"),
765 class_java_lang_Object,
769 return *exceptionptr;
771 s = (java_lang_String *) asm_calljavafunction(m,
772 (void *) (ptrint) index,
778 return *exceptionptr;
780 e = new_exception_javastring(string_java_lang_ArrayIndexOutOfBoundsException,
784 return *exceptionptr;
790 /* new_arraystoreexception *****************************************************
792 generates a java.lang.ArrayStoreException for the jit compiler
794 *******************************************************************************/
796 java_objectheader *new_arraystoreexception(void)
798 java_objectheader *e;
800 e = new_exception(string_java_lang_ArrayStoreException);
801 /* e = native_new_and_init(class_java_lang_ArrayStoreException); */
804 return *exceptionptr;
810 /* new_classcastexception ******************************************************
812 generates a java.lang.ClassCastException for the jit compiler
814 *******************************************************************************/
816 java_objectheader *new_classcastexception(void)
818 java_objectheader *e;
820 e = new_exception(string_java_lang_ClassCastException);
823 return *exceptionptr;
829 /* new_illegalargumentexception ************************************************
831 Generates a java.lang.IllegalArgumentException for the VM system.
833 *******************************************************************************/
835 java_objectheader *new_illegalargumentexception(void)
837 java_objectheader *e;
839 if (!(e = native_new_and_init(class_java_lang_IllegalArgumentException)))
840 return *exceptionptr;
846 /* new_illegalmonitorstateexception ********************************************
848 Generates a java.lang.IllegalMonitorStateException for the VM
851 *******************************************************************************/
853 java_objectheader *new_illegalmonitorstateexception(void)
855 java_objectheader *e;
857 if (!(e = native_new_and_init(class_java_lang_IllegalMonitorStateException)))
858 return *exceptionptr;
864 /* new_negativearraysizeexception **********************************************
866 generates a java.lang.NegativeArraySizeException for the jit compiler
868 *******************************************************************************/
870 java_objectheader *new_negativearraysizeexception(void)
872 java_objectheader *e;
874 e = new_exception(string_java_lang_NegativeArraySizeException);
877 return *exceptionptr;
883 /* new_nullpointerexception ****************************************************
885 generates a java.lang.NullPointerException for the jit compiler
887 *******************************************************************************/
889 java_objectheader *new_nullpointerexception(void)
891 java_objectheader *e;
893 e = native_new_and_init(class_java_lang_NullPointerException);
896 return *exceptionptr;
903 * These are local overrides for various environment variables in Emacs.
904 * Please do not remove this and leave it at the end of the file, where
905 * Emacs will automagically detect them.
906 * ---------------------------------------------------------------------
909 * indent-tabs-mode: t