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 2671 2005-06-13 14:29: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* _exceptionptr = NULL;
63 u1 _dontfillinexceptionstacktrace = false;
67 /* init_system_exceptions ******************************************************
69 Load and link exceptions used in the system.
71 *******************************************************************************/
73 bool exceptions_init(void)
75 /* java/lang/Throwable */
77 if (!(class_java_lang_Throwable =
78 load_class_bootstrap(utf_java_lang_Throwable)) ||
79 !link_class(class_java_lang_Throwable))
83 /* java/lang/VMThrowable */
85 if (!(class_java_lang_VMThrowable =
86 load_class_bootstrap(utf_java_lang_VMThrowable)) ||
87 !link_class(class_java_lang_VMThrowable))
93 if (!(class_java_lang_Error = load_class_bootstrap(utf_java_lang_Error)) ||
94 !link_class(class_java_lang_Error))
98 /* java/lang/Exception */
100 if (!(class_java_lang_Exception =
101 load_class_bootstrap(utf_java_lang_Exception)) ||
102 !link_class(class_java_lang_Exception))
106 /* java/lang/NoClassDefFoundError */
108 if (!(class_java_lang_NoClassDefFoundError =
109 load_class_bootstrap(utf_java_lang_NoClassDefFoundError)) ||
110 !link_class(class_java_lang_NoClassDefFoundError))
114 /* java/lang/OutOfMemoryError */
116 if (!(class_java_lang_OutOfMemoryError =
117 load_class_bootstrap(utf_java_lang_OutOfMemoryError)) ||
118 !link_class(class_java_lang_OutOfMemoryError))
122 /* java/lang/ClassNotFoundException */
124 if (!(class_java_lang_ClassNotFoundException =
125 load_class_bootstrap(utf_java_lang_ClassNotFoundException)) ||
126 !link_class(class_java_lang_ClassNotFoundException))
133 static void throw_exception_exit_intern(bool doexit)
135 java_objectheader *xptr;
139 xptr = *exceptionptr;
142 /* clear exception, because we are calling jit code again */
143 *exceptionptr = NULL;
145 c = xptr->vftbl->class;
147 pss = class_resolveclassmethod(c,
150 class_java_lang_Object,
153 /* print the stacktrace */
155 asm_calljavafunction(pss, xptr, NULL, NULL, NULL);
157 /* This normally means, we are EXTREMLY out of memory or have a */
158 /* serious problem while printStackTrace. But may be another */
159 /* exception, so print it. */
162 fprintf(stderr, "Exception while printStackTrace(): ");
163 utf_fprint_classname(stderr, c->name);
164 fprintf(stderr, "\n");
168 utf_fprint_classname(stderr, c->name);
169 fprintf(stderr, ": printStackTrace()V not found!\n");
182 void throw_exception(void)
184 throw_exception_exit_intern(false);
188 void throw_exception_exit(void)
190 throw_exception_exit_intern(true);
194 void throw_main_exception(void)
196 fprintf(stderr, "Exception in thread \"main\" ");
199 throw_exception_exit_intern(false);
203 void throw_main_exception_exit(void)
205 fprintf(stderr, "Exception in thread \"main\" ");
208 throw_exception_exit_intern(true);
212 void throw_cacao_exception_exit(const char *exception, const char *message, ...)
219 len = strlen(exception);
220 tmp = MNEW(char, len + 1);
221 strncpy(tmp, exception, len);
224 /* convert to classname */
226 for (i = len - 1; i >= 0; i--)
227 if (tmp[i] == '/') tmp[i] = '.';
229 fprintf(stderr, "Exception in thread \"main\" %s", tmp);
231 MFREE(tmp, char, len);
233 if (strlen(message) > 0) {
234 fprintf(stderr, ": ");
236 va_start(ap, message);
237 vfprintf(stderr, message, ap);
241 fprintf(stderr, "\n");
250 /* new_exception ***************************************************************
252 Creates an exception object with the given name and initalizes it.
254 *******************************************************************************/
256 java_objectheader *new_exception(const char *classname)
258 java_objectheader *o;
261 if (!(c = load_class_bootstrap(utf_new_char(classname))))
262 return *exceptionptr;
264 o = native_new_and_init(c);
267 return *exceptionptr;
273 /* new_exception_message *******************************************************
275 Creates an exception object with the given name and initalizes it
276 with the given char message.
278 *******************************************************************************/
280 java_objectheader *new_exception_message(const char *classname,
283 java_objectheader *o;
286 if (!(c = load_class_bootstrap(utf_new_char(classname))))
287 return *exceptionptr;
289 o = native_new_and_init_string(c, javastring_new_char(message));
292 return *exceptionptr;
298 /* new_exception_throwable *****************************************************
300 Creates an exception object with the given name and initalizes it
301 with the given java/lang/Throwable exception.
303 *******************************************************************************/
305 java_objectheader *new_exception_throwable(const char *classname,
306 java_lang_Throwable *throwable)
308 java_objectheader *o;
311 if (!(c = load_class_bootstrap(utf_new_char(classname))))
312 return *exceptionptr;
314 o = native_new_and_init_throwable(c, throwable);
317 return *exceptionptr;
323 /* new_exception_utfmessage ****************************************************
325 Creates an exception object with the given name and initalizes it
326 with the given utf message.
328 *******************************************************************************/
330 java_objectheader *new_exception_utfmessage(const char *classname, utf *message)
332 java_objectheader *o;
335 if (!(c = load_class_bootstrap(utf_new_char(classname))))
336 return *exceptionptr;
338 o = native_new_and_init_string(c, javastring_new(message));
341 return *exceptionptr;
347 /* new_exception_javastring ****************************************************
349 Creates an exception object with the given name and initalizes it
350 with the given java/lang/String message.
352 *******************************************************************************/
354 java_objectheader *new_exception_javastring(const char *classname,
355 java_lang_String *message)
357 java_objectheader *o;
360 if (!(c = load_class_bootstrap(utf_new_char(classname))))
361 return *exceptionptr;
363 o = native_new_and_init_string(c, message);
366 return *exceptionptr;
372 /* new_exception_int ***********************************************************
374 Creates an exception object with the given name and initalizes it
375 with the given int value.
377 *******************************************************************************/
379 java_objectheader *new_exception_int(const char *classname, s4 i)
381 java_objectheader *o;
384 if (!(c = load_class_bootstrap(utf_new_char(classname))))
385 return *exceptionptr;
387 o = native_new_and_init_int(c, i);
390 return *exceptionptr;
396 /* new_classformaterror ********************************************************
398 generates a java.lang.ClassFormatError for the classloader
400 *******************************************************************************/
402 java_objectheader *new_classformaterror(classinfo *c, const char *message, ...)
404 java_objectheader *o;
409 /* calculate message length */
414 msglen += utf_strlen(c->name) + strlen(" (");
416 va_start(ap, message);
417 msglen += get_variable_message_length(message, ap);
421 msglen += strlen(")");
423 msglen += strlen("0");
425 /* allocate a buffer */
427 msg = MNEW(char, msglen);
429 /* print message into allocated buffer */
432 utf_sprint_classname(msg, c->name);
436 va_start(ap, message);
437 vsprintf(msg + strlen(msg), message, ap);
443 o = new_exception_message(string_java_lang_ClassFormatError, msg);
445 MFREE(msg, char, msglen);
451 /* new_internalerror ***********************************************************
453 Generates a java.lang.InternalError for the VM.
455 *******************************************************************************/
457 java_objectheader *new_internalerror(const char *message, ...)
459 java_objectheader *o;
464 /* calculate exception message length */
466 va_start(ap, message);
467 msglen = get_variable_message_length(message, ap);
470 /* allocate memory */
472 msg = MNEW(char, msglen);
474 /* generate message */
476 va_start(ap, message);
477 vsprintf(msg, message, ap);
480 /* create exception object */
482 o = new_exception_message(string_java_lang_InternalError, msg);
486 MFREE(msg, char, msglen);
492 /* new_unsupportedclassversionerror ********************************************
494 generates a java.lang.UnsupportedClassVersionError for the classloader
496 *******************************************************************************/
498 java_objectheader *new_unsupportedclassversionerror(classinfo *c, const char *message, ...)
500 java_objectheader *o;
505 /* calculate exception message length */
507 msglen = utf_strlen(c->name) + strlen(" (") + strlen(")") + strlen("0");
509 va_start(ap, message);
510 msglen += get_variable_message_length(message, ap);
513 /* allocate memory */
515 msg = MNEW(char, msglen);
517 /* generate message */
519 utf_sprint_classname(msg, c->name);
522 va_start(ap, message);
523 vsprintf(msg + strlen(msg), message, ap);
528 /* create exception object */
530 o = new_exception_message(string_java_lang_UnsupportedClassVersionError,
535 MFREE(msg, char, msglen);
541 /* new_verifyerror *************************************************************
543 generates a java.lang.VerifyError for the jit compiler
545 *******************************************************************************/
547 java_objectheader *new_verifyerror(methodinfo *m, const char *message, ...)
549 java_objectheader *o;
554 useinlining = false; /* at least until sure inlining works with exceptions*/
556 /* calculate exception message length */
558 msglen = strlen("(class: ") + utf_strlen(m->class->name) +
559 strlen(", method: ") + utf_strlen(m->name) +
560 strlen(" signature: ") + utf_strlen(m->descriptor) +
561 strlen(") ") + strlen("0");
563 va_start(ap, message);
564 msglen += get_variable_message_length(message, ap);
567 /* allocate memory */
569 msg = MNEW(char, msglen);
571 /* generate message */
573 strcpy(msg, "(class: ");
574 utf_strcat(msg, m->class->name);
575 strcat(msg, ", method: ");
576 utf_strcat(msg, m->name);
577 strcat(msg, " signature: ");
578 utf_strcat(msg, m->descriptor);
581 va_start(ap, message);
582 vsprintf(msg + strlen(msg), message, ap);
585 /* create exception object */
587 o = new_exception_message(string_java_lang_VerifyError, msg);
591 MFREE(msg, char, msglen);
597 /* new_arithmeticexception *****************************************************
599 Generates a java.lang.ArithmeticException for the jit compiler.
601 *******************************************************************************/
603 java_objectheader *new_arithmeticexception(void)
605 java_objectheader *e;
607 e = new_exception_message(string_java_lang_ArithmeticException,
608 string_java_lang_ArithmeticException_message);
611 return *exceptionptr;
617 /* new_arrayindexoutofboundsexception ******************************************
619 Generates a java.lang.ArrayIndexOutOfBoundsException for the JIT
622 *******************************************************************************/
624 java_objectheader *new_arrayindexoutofboundsexception(s4 index)
626 java_objectheader *e;
630 /* convert the index into a String, like Sun does */
632 m = class_resolveclassmethod(class_java_lang_String,
633 utf_new_char("valueOf"),
634 utf_new_char("(I)Ljava/lang/String;"),
635 class_java_lang_Object,
639 return *exceptionptr;
641 s = (java_lang_String *) asm_calljavafunction(m,
642 (void *) (ptrint) index,
648 return *exceptionptr;
650 e = new_exception_javastring(string_java_lang_ArrayIndexOutOfBoundsException,
654 return *exceptionptr;
660 /* new_arraystoreexception *****************************************************
662 generates a java.lang.ArrayStoreException for the jit compiler
664 *******************************************************************************/
666 java_objectheader *new_arraystoreexception(void)
668 java_objectheader *e;
670 e = new_exception(string_java_lang_ArrayStoreException);
673 return *exceptionptr;
679 /* new_classcastexception ******************************************************
681 generates a java.lang.ClassCastException for the jit compiler
683 *******************************************************************************/
685 java_objectheader *new_classcastexception(void)
687 java_objectheader *e;
689 e = new_exception(string_java_lang_ClassCastException);
692 return *exceptionptr;
698 /* new_negativearraysizeexception **********************************************
700 generates a java.lang.NegativeArraySizeException for the jit compiler
702 *******************************************************************************/
704 java_objectheader *new_negativearraysizeexception(void)
706 java_objectheader *e;
708 e = new_exception(string_java_lang_NegativeArraySizeException);
711 return *exceptionptr;
717 /* new_nullpointerexception ****************************************************
719 generates a java.lang.NullPointerException for the jit compiler
721 *******************************************************************************/
723 java_objectheader *new_nullpointerexception(void)
725 java_objectheader *e;
727 e = new_exception(string_java_lang_NullPointerException);
730 return *exceptionptr;
737 * These are local overrides for various environment variables in Emacs.
738 * Please do not remove this and leave it at the end of the file, where
739 * Emacs will automagically detect them.
740 * ---------------------------------------------------------------------
743 * indent-tabs-mode: t