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
31 $Id: exceptions.c 3264 2005-09-21 20:18:24Z 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))
97 /* java/lang/Exception */
99 if (!(class_java_lang_Exception =
100 load_class_bootstrap(utf_java_lang_Exception)) ||
101 !link_class(class_java_lang_Exception))
105 /* java/lang/NoClassDefFoundError */
107 if (!(class_java_lang_NoClassDefFoundError =
108 load_class_bootstrap(utf_java_lang_NoClassDefFoundError)) ||
109 !link_class(class_java_lang_NoClassDefFoundError))
113 /* java/lang/OutOfMemoryError */
115 if (!(class_java_lang_OutOfMemoryError =
116 load_class_bootstrap(utf_java_lang_OutOfMemoryError)) ||
117 !link_class(class_java_lang_OutOfMemoryError))
121 /* java/lang/ClassNotFoundException */
123 if (!(class_java_lang_ClassNotFoundException =
124 load_class_bootstrap(utf_java_lang_ClassNotFoundException)) ||
125 !link_class(class_java_lang_ClassNotFoundException))
132 static void throw_exception_exit_intern(bool doexit)
134 java_objectheader *xptr;
138 xptr = *exceptionptr;
141 /* clear exception, because we are calling jit code again */
142 *exceptionptr = NULL;
144 c = xptr->vftbl->class;
146 pss = class_resolveclassmethod(c,
149 class_java_lang_Object,
152 /* print the stacktrace */
154 asm_calljavafunction(pss, xptr, NULL, NULL, NULL);
156 /* This normally means, we are EXTREMLY out of memory or have a */
157 /* serious problem while printStackTrace. But may be another */
158 /* exception, so print it. */
161 java_lang_Throwable *t;
163 t = (java_lang_Throwable *) *exceptionptr;
165 fprintf(stderr, "Exception while printStackTrace(): ");
166 utf_fprint_classname(stderr, t->header.vftbl->class->name);
168 if (t->detailMessage) {
171 buf = javastring_tochar((java_objectheader *) t->detailMessage);
172 fprintf(stderr, ": %s", buf);
173 MFREE(buf, char, strlen(buf));
176 fprintf(stderr, "\n");
180 utf_fprint_classname(stderr, c->name);
181 fprintf(stderr, ": printStackTrace()V not found!\n");
194 void throw_exception(void)
196 throw_exception_exit_intern(false);
200 void throw_exception_exit(void)
202 throw_exception_exit_intern(true);
206 void throw_main_exception(void)
208 fprintf(stderr, "Exception in thread \"main\" ");
211 throw_exception_exit_intern(false);
215 void throw_main_exception_exit(void)
217 fprintf(stderr, "Exception in thread \"main\" ");
220 throw_exception_exit_intern(true);
224 void throw_cacao_exception_exit(const char *exception, const char *message, ...)
231 len = strlen(exception);
232 tmp = MNEW(char, len + 1);
233 strncpy(tmp, exception, len);
236 /* convert to classname */
238 for (i = len - 1; i >= 0; i--)
239 if (tmp[i] == '/') tmp[i] = '.';
241 fprintf(stderr, "Exception in thread \"main\" %s", tmp);
243 MFREE(tmp, char, len);
245 if (strlen(message) > 0) {
246 fprintf(stderr, ": ");
248 va_start(ap, message);
249 vfprintf(stderr, message, ap);
253 fprintf(stderr, "\n");
262 /* new_exception ***************************************************************
264 Creates an exception object with the given name and initalizes it.
266 *******************************************************************************/
268 java_objectheader *new_exception(const char *classname)
270 java_objectheader *o;
273 if (!(c = load_class_bootstrap(utf_new_char(classname))))
274 return *exceptionptr;
276 o = native_new_and_init(c);
279 return *exceptionptr;
285 /* new_exception_message *******************************************************
287 Creates an exception object with the given name and initalizes it
288 with the given char message.
290 *******************************************************************************/
292 java_objectheader *new_exception_message(const char *classname,
295 java_objectheader *o;
298 if (!(c = load_class_bootstrap(utf_new_char(classname))))
299 return *exceptionptr;
301 o = native_new_and_init_string(c, javastring_new_char(message));
304 return *exceptionptr;
310 /* new_exception_throwable *****************************************************
312 Creates an exception object with the given name and initalizes it
313 with the given java/lang/Throwable exception.
315 *******************************************************************************/
317 java_objectheader *new_exception_throwable(const char *classname,
318 java_lang_Throwable *throwable)
320 java_objectheader *o;
323 if (!(c = load_class_bootstrap(utf_new_char(classname))))
324 return *exceptionptr;
326 o = native_new_and_init_throwable(c, throwable);
329 return *exceptionptr;
335 /* new_exception_utfmessage ****************************************************
337 Creates an exception object with the given name and initalizes it
338 with the given utf message.
340 *******************************************************************************/
342 java_objectheader *new_exception_utfmessage(const char *classname, utf *message)
344 java_objectheader *o;
347 if (!(c = load_class_bootstrap(utf_new_char(classname))))
348 return *exceptionptr;
350 o = native_new_and_init_string(c, javastring_new(message));
353 return *exceptionptr;
359 /* new_exception_javastring ****************************************************
361 Creates an exception object with the given name and initalizes it
362 with the given java/lang/String message.
364 *******************************************************************************/
366 java_objectheader *new_exception_javastring(const char *classname,
367 java_lang_String *message)
369 java_objectheader *o;
372 if (!(c = load_class_bootstrap(utf_new_char(classname))))
373 return *exceptionptr;
375 o = native_new_and_init_string(c, message);
378 return *exceptionptr;
384 /* new_exception_int ***********************************************************
386 Creates an exception object with the given name and initalizes it
387 with the given int value.
389 *******************************************************************************/
391 java_objectheader *new_exception_int(const char *classname, s4 i)
393 java_objectheader *o;
396 if (!(c = load_class_bootstrap(utf_new_char(classname))))
397 return *exceptionptr;
399 o = native_new_and_init_int(c, i);
402 return *exceptionptr;
408 /* new_classformaterror ********************************************************
410 generates a java.lang.ClassFormatError for the classloader
412 *******************************************************************************/
414 java_objectheader *new_classformaterror(classinfo *c, const char *message, ...)
416 java_objectheader *o;
421 /* calculate message length */
426 msglen += utf_strlen(c->name) + strlen(" (");
428 va_start(ap, message);
429 msglen += get_variable_message_length(message, ap);
433 msglen += strlen(")");
435 msglen += strlen("0");
437 /* allocate a buffer */
439 msg = MNEW(char, msglen);
441 /* print message into allocated buffer */
444 utf_sprint_classname(msg, c->name);
448 va_start(ap, message);
449 vsprintf(msg + strlen(msg), message, ap);
455 o = new_exception_message(string_java_lang_ClassFormatError, msg);
457 MFREE(msg, char, msglen);
463 /* new_classnotfoundexception **************************************************
465 Generates a java.lang.ClassNotFoundException for the classloader.
467 *******************************************************************************/
469 java_objectheader *new_classnotfoundexception(utf *name)
471 java_objectheader *o;
473 o = native_new_and_init_string(class_java_lang_ClassNotFoundException,
474 javastring_new(name));
477 return *exceptionptr;
483 /* new_internalerror ***********************************************************
485 Generates a java.lang.InternalError for the VM.
487 *******************************************************************************/
489 java_objectheader *new_internalerror(const char *message, ...)
491 java_objectheader *o;
496 /* calculate exception message length */
498 va_start(ap, message);
499 msglen = get_variable_message_length(message, ap);
502 /* allocate memory */
504 msg = MNEW(char, msglen);
506 /* generate message */
508 va_start(ap, message);
509 vsprintf(msg, message, ap);
512 /* create exception object */
514 o = new_exception_message(string_java_lang_InternalError, msg);
518 MFREE(msg, char, msglen);
524 /* new_unsupportedclassversionerror ********************************************
526 generates a java.lang.UnsupportedClassVersionError for the classloader
528 *******************************************************************************/
530 java_objectheader *new_unsupportedclassversionerror(classinfo *c, const char *message, ...)
532 java_objectheader *o;
537 /* calculate exception message length */
539 msglen = utf_strlen(c->name) + strlen(" (") + strlen(")") + strlen("0");
541 va_start(ap, message);
542 msglen += get_variable_message_length(message, ap);
545 /* allocate memory */
547 msg = MNEW(char, msglen);
549 /* generate message */
551 utf_sprint_classname(msg, c->name);
554 va_start(ap, message);
555 vsprintf(msg + strlen(msg), message, ap);
560 /* create exception object */
562 o = new_exception_message(string_java_lang_UnsupportedClassVersionError,
567 MFREE(msg, char, msglen);
573 /* new_verifyerror *************************************************************
575 generates a java.lang.VerifyError for the jit compiler
577 *******************************************************************************/
579 java_objectheader *new_verifyerror(methodinfo *m, const char *message, ...)
581 java_objectheader *o;
586 useinlining = false; /* at least until sure inlining works with exceptions*/
588 /* calculate exception message length */
590 msglen = strlen("(class: ") + utf_strlen(m->class->name) +
591 strlen(", method: ") + utf_strlen(m->name) +
592 strlen(" signature: ") + utf_strlen(m->descriptor) +
593 strlen(") ") + strlen("0");
595 va_start(ap, message);
596 msglen += get_variable_message_length(message, ap);
599 /* allocate memory */
601 msg = MNEW(char, msglen);
603 /* generate message */
605 strcpy(msg, "(class: ");
606 utf_strcat(msg, m->class->name);
607 strcat(msg, ", method: ");
608 utf_strcat(msg, m->name);
609 strcat(msg, " signature: ");
610 utf_strcat(msg, m->descriptor);
613 va_start(ap, message);
614 vsprintf(msg + strlen(msg), message, ap);
617 /* create exception object */
619 o = new_exception_message(string_java_lang_VerifyError, msg);
623 MFREE(msg, char, msglen);
629 /* new_arithmeticexception *****************************************************
631 Generates a java.lang.ArithmeticException for the jit compiler.
633 *******************************************************************************/
635 java_objectheader *new_arithmeticexception(void)
637 java_objectheader *e;
639 e = new_exception_message(string_java_lang_ArithmeticException,
640 string_java_lang_ArithmeticException_message);
643 return *exceptionptr;
649 /* new_arrayindexoutofboundsexception ******************************************
651 Generates a java.lang.ArrayIndexOutOfBoundsException for the JIT
654 *******************************************************************************/
656 java_objectheader *new_arrayindexoutofboundsexception(s4 index)
658 java_objectheader *e;
662 /* convert the index into a String, like Sun does */
664 m = class_resolveclassmethod(class_java_lang_String,
665 utf_new_char("valueOf"),
666 utf_new_char("(I)Ljava/lang/String;"),
667 class_java_lang_Object,
671 return *exceptionptr;
673 s = (java_lang_String *) asm_calljavafunction(m,
674 (void *) (ptrint) index,
680 return *exceptionptr;
682 e = new_exception_javastring(string_java_lang_ArrayIndexOutOfBoundsException,
686 return *exceptionptr;
692 /* new_arraystoreexception *****************************************************
694 generates a java.lang.ArrayStoreException for the jit compiler
696 *******************************************************************************/
698 java_objectheader *new_arraystoreexception(void)
700 java_objectheader *e;
702 e = new_exception(string_java_lang_ArrayStoreException);
705 return *exceptionptr;
711 /* new_classcastexception ******************************************************
713 generates a java.lang.ClassCastException for the jit compiler
715 *******************************************************************************/
717 java_objectheader *new_classcastexception(void)
719 java_objectheader *e;
721 e = new_exception(string_java_lang_ClassCastException);
724 return *exceptionptr;
730 /* new_negativearraysizeexception **********************************************
732 generates a java.lang.NegativeArraySizeException for the jit compiler
734 *******************************************************************************/
736 java_objectheader *new_negativearraysizeexception(void)
738 java_objectheader *e;
740 e = new_exception(string_java_lang_NegativeArraySizeException);
743 return *exceptionptr;
749 /* new_nullpointerexception ****************************************************
751 generates a java.lang.NullPointerException for the jit compiler
753 *******************************************************************************/
755 java_objectheader *new_nullpointerexception(void)
757 java_objectheader *e;
759 e = new_exception(string_java_lang_NullPointerException);
762 return *exceptionptr;
769 * These are local overrides for various environment variables in Emacs.
770 * Please do not remove this and leave it at the end of the file, where
771 * Emacs will automagically detect them.
772 * ---------------------------------------------------------------------
775 * indent-tabs-mode: t